Skip to content

Commit 606c1cf

Browse files
authored
Merge branch 'dreamstalker:master' into master
2 parents a073c45 + de3679f commit 606c1cf

18 files changed

+130
-36
lines changed

.github/workflows/build.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ jobs:
277277
github.event.action == 'published' &&
278278
startsWith(github.ref, 'refs/tags/')
279279
run: |
280-
7z a -tzip rehlds-bin-${{ env.APP_VERSION }}.zip bin/linux32/ hlsdk/
280+
7z a -tzip rehlds-bin-${{ env.APP_VERSION }}.zip bin/ hlsdk/
281281
7z a -t7z -m0=lzma2 -mx=9 -mfb=64 -aoa rehlds-dbg-${{ env.APP_VERSION }}.7z debug/
282282
283283
- name: Publish artifacts

rehlds/HLTV/Core/src/BSPModel.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ byte *BSPModel::LeafPVS(mleaf_t *leaf)
170170

171171
byte *BSPModel::DecompressVis(unsigned char *in)
172172
{
173-
static unsigned char decompressed[MODEL_MAX_PVS];
173+
static unsigned char decompressed[MAX_MAP_LEAFS / 8];
174174
if (in == nullptr) {
175175
return m_novis;
176176
}

rehlds/HLTV/Core/src/BSPModel.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
#include "l_studio.h"
3434
#include "edict.h"
35+
#include "bspfile.h"
3536

3637
// values for model_t's needload
3738
#define NL_PRESENT 0
@@ -87,9 +88,7 @@ class BSPModel: public IBSPModel {
8788

8889
protected:
8990
model_t m_model;
90-
91-
enum { MODEL_MAX_PVS = 1024 };
92-
byte m_novis[MODEL_MAX_PVS];
91+
byte m_novis[MAX_MAP_LEAFS / 8];
9392
byte *m_base;
9493

9594
int m_visframecount;

rehlds/engine/cmodel.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,17 @@
3131
unsigned char *gPAS;
3232
unsigned char *gPVS;
3333
int gPVSRowBytes;
34-
unsigned char mod_novis[MODEL_MAX_PVS];
34+
unsigned char mod_novis[MAX_MAP_LEAFS / 8];
3535

3636
void Mod_Init(void)
3737
{
3838
SW_Mod_Init();
39-
Q_memset(mod_novis, 255, MODEL_MAX_PVS);
39+
Q_memset(mod_novis, 0xFF, MAX_MAP_LEAFS / 8);
4040
}
4141

4242
unsigned char *Mod_DecompressVis(unsigned char *in, model_t *model)
4343
{
44-
static unsigned char decompressed[MODEL_MAX_PVS];
44+
static unsigned char decompressed[MAX_MAP_LEAFS / 8];
4545

4646
if (in == NULL)
4747
{

rehlds/engine/cmodel.h

-5
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,10 @@
2929
#pragma once
3030

3131
#include "maintypes.h"
32-
#include "model.h"
33-
34-
// Looks like no more than 8096 visibility leafs per world model
35-
const int MODEL_MAX_PVS = 1024;
3632

3733
extern unsigned char *gPAS;
3834
extern unsigned char *gPVS;
3935
extern int gPVSRowBytes;
40-
extern unsigned char mod_novis[MODEL_MAX_PVS];
4136

4237
void Mod_Init(void);
4338
unsigned char *Mod_DecompressVis(unsigned char *in, model_t *model);

rehlds/engine/common.cpp

+28
Original file line numberDiff line numberDiff line change
@@ -1978,6 +1978,34 @@ NOXREF int COM_ExpandFilename(char *filename)
19781978
return *filename != 0;
19791979
}
19801980

1981+
// small helper function shared by lots of modules
1982+
qboolean COM_IsAbsolutePath(const char *pStr)
1983+
{
1984+
if (strchr(pStr, ':') || pStr[0] == '/' || pStr[0] == '\\')
1985+
return FALSE;
1986+
1987+
return TRUE;
1988+
}
1989+
1990+
qboolean COM_IsValidPath(const char *pszFilename)
1991+
{
1992+
if (!pszFilename)
1993+
return FALSE;
1994+
1995+
if (Q_strlen(pszFilename) <= 0 ||
1996+
Q_strstr(pszFilename, "\\\\") || // to protect network paths
1997+
Q_strstr(pszFilename, ":") || // to protect absolute paths
1998+
Q_strstr(pszFilename, "..") || // to protect relative paths
1999+
Q_strstr(pszFilename, "~") ||
2000+
Q_strstr(pszFilename, "\n") || // CFileSystem_Stdio::FS_fopen doesn't allow this
2001+
Q_strstr(pszFilename, "\r")) // CFileSystem_Stdio::FS_fopen doesn't allow this
2002+
{
2003+
return FALSE;
2004+
}
2005+
2006+
return TRUE;
2007+
}
2008+
19812009
int EXT_FUNC COM_FileSize(const char *filename)
19822010
{
19832011
FileHandle_t fp;

rehlds/engine/common.h

+2
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ void COM_CreatePath(char *path);
187187
NOXREF void COM_CopyFile(char *netpath, char *cachepath);
188188
NOXREF int COM_ExpandFilename(char *filename);
189189
int COM_FileSize(const char *filename);
190+
qboolean COM_IsAbsolutePath(const char *pStr);
191+
qboolean COM_IsValidPath(const char *pszFilename);
190192
unsigned char *COM_LoadFile(const char *path, int usehunk, int *pLength);
191193
void COM_FreeFile(void *buffer);
192194
void COM_CopyFileChunk(FileHandle_t dst, FileHandle_t src, int nSize);

rehlds/engine/host_cmd.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,19 @@ void Host_Motd_f(void)
205205
char *next;
206206

207207
pFileList = motdfile.string;
208-
if (*pFileList == '/' || Q_strstr(pFileList, ":") || Q_strstr(pFileList, "..") || Q_strstr(pFileList, "\\"))
208+
if (!COM_IsValidPath(pFileList) || COM_IsAbsolutePath(pFileList))
209209
{
210210
Con_Printf("Unable to open %s (contains illegal characters)\n", pFileList);
211211
return;
212212
}
213+
214+
const char *pchExtension = COM_FileExtension(pFileList);
215+
if (Q_stricmp(pchExtension, "txt") != 0)
216+
{
217+
Con_Printf("Invalid motdfile name %s (wrong file extension, must be .txt)\n", pFileList);
218+
return;
219+
}
220+
213221
pFile = FS_Open(pFileList, "rb");
214222
if (!pFile)
215223
{

rehlds/engine/pr_cmds.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -1447,6 +1447,9 @@ int EXT_FUNC PF_precache_model_I_internal(const char *s)
14471447
{
14481448
for (int i = 0; i < MAX_MODELS; i++)
14491449
{
1450+
if (!g_psv.model_precache[i])
1451+
continue;
1452+
14501453
// use case-sensitive names to increase performance
14511454
#ifdef REHLDS_FIXES
14521455
if (!Q_strcmp(g_psv.model_precache[i], s))
@@ -1545,7 +1548,7 @@ int EXT_FUNC PF_precache_generic_I_internal(const char *s)
15451548
{
15461549
for (int i = 0; i < MAX_GENERIC; i++)
15471550
{
1548-
if (!Q_stricmp(g_psv.generic_precache[i], s))
1551+
if (g_psv.generic_precache[i] && !Q_stricmp(g_psv.generic_precache[i], s))
15491552
return i;
15501553
}
15511554
Host_Error("%s: '%s' Precache can only be done in spawn functions", __func__, s);

rehlds/engine/r_studio.cpp

+22-4
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,15 @@ void EXT_FUNC AnimationAutomove(const edict_t *pEdict, float flTime)
881881
void EXT_FUNC GetBonePosition(const edict_t *pEdict, int iBone, float *rgflOrigin, float *rgflAngles)
882882
{
883883
pstudiohdr = (studiohdr_t *)Mod_Extradata(g_psv.models[pEdict->v.modelindex]);
884+
885+
#ifdef REHLDS_FIXES
886+
if (!pstudiohdr)
887+
return;
888+
889+
if (iBone < 0 || iBone >= pstudiohdr->numbones)
890+
return; // invalid bone
891+
#endif
892+
884893
g_pSvBlendingAPI->SV_StudioSetupBones(
885894
g_psv.models[pEdict->v.modelindex],
886895
pEdict->v.frame,
@@ -906,14 +915,23 @@ void EXT_FUNC GetAttachment(const edict_t *pEdict, int iAttachment, float *rgflO
906915
mstudioattachment_t *pattachment;
907916
vec3_t angles;
908917

909-
angles[0] = -pEdict->v.angles[0];
910-
angles[1] = pEdict->v.angles[1];
911-
angles[2] = pEdict->v.angles[2];
912-
913918
pstudiohdr = (studiohdr_t *)Mod_Extradata(g_psv.models[pEdict->v.modelindex]);
919+
920+
#ifdef REHLDS_FIXES
921+
if (!pstudiohdr)
922+
return;
923+
924+
if (iAttachment < 0 || iAttachment >= pstudiohdr->numattachments)
925+
return; // invalid attachment
926+
#endif
927+
914928
pattachment = (mstudioattachment_t *)((char *)pstudiohdr + pstudiohdr->attachmentindex);
915929
pattachment += iAttachment;
916930

931+
angles[0] = -pEdict->v.angles[0];
932+
angles[1] = pEdict->v.angles[1];
933+
angles[2] = pEdict->v.angles[2];
934+
917935
g_pSvBlendingAPI->SV_StudioSetupBones(
918936
g_psv.models[pEdict->v.modelindex],
919937
pEdict->v.frame,

rehlds/engine/server.h

-5
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,6 @@ enum GameType_e
405405

406406
extern GameType_e g_eGameType;
407407

408-
extern int fatbytes;
409408
extern int giNextUserMsg;
410409
extern int hashstrings_collisions;
411410

@@ -418,10 +417,6 @@ extern delta_t *g_pweapondelta;
418417
extern delta_t *g_pusercmddelta;
419418
#endif
420419

421-
extern unsigned char fatpvs[1024];
422-
extern int fatpasbytes;
423-
extern unsigned char fatpas[1024];
424-
425420
extern int gPacketSuppressed;
426421

427422
extern char localinfo[MAX_LOCALINFO];

rehlds/engine/sv_main.cpp

+27-10
Original file line numberDiff line numberDiff line change
@@ -680,22 +680,22 @@ qboolean SV_BuildSoundMsg(edict_t *entity, int channel, const char *sample, int
680680

681681
if (volume < 0 || volume > 255)
682682
{
683-
Con_Printf("%s: volume = %i", __func__, volume);
683+
Con_Printf("%s: volume = %i\n", __func__, volume);
684684
volume = (volume < 0) ? 0 : 255;
685685
}
686686
if (attenuation < 0.0f || attenuation > 4.0f)
687687
{
688-
Con_Printf("%s: attenuation = %f", __func__, attenuation);
688+
Con_Printf("%s: attenuation = %f\n", __func__, attenuation);
689689
attenuation = (attenuation < 0.0f) ? 0.0f : 4.0f;
690690
}
691691
if (channel < 0 || channel > 7)
692692
{
693-
Con_Printf("%s: channel = %i", __func__, channel);
693+
Con_Printf("%s: channel = %i\n", __func__, channel);
694694
channel = (channel < 0) ? CHAN_AUTO : CHAN_NETWORKVOICE_BASE;
695695
}
696696
if (pitch < 0 || pitch > 255)
697697
{
698-
Con_Printf("%s: pitch = %i", __func__, pitch);
698+
Con_Printf("%s: pitch = %i\n", __func__, pitch);
699699
pitch = (pitch < 0) ? 0 : 255;
700700
}
701701

@@ -707,7 +707,7 @@ qboolean SV_BuildSoundMsg(edict_t *entity, int channel, const char *sample, int
707707
sound_num = Q_atoi(sample + 1);
708708
if (sound_num >= CVOXFILESENTENCEMAX)
709709
{
710-
Con_Printf("%s: invalid sentence number: %s", __func__, sample + 1);
710+
Con_Printf("%s: invalid sentence number: %s\n", __func__, sample + 1);
711711
return FALSE;
712712
}
713713
}
@@ -1112,8 +1112,18 @@ void SV_SendServerinfo_internal(sizebuf_t *msg, client_t *client)
11121112
else
11131113
MSG_WriteByte(msg, 0);
11141114

1115-
COM_FileBase(com_gamedir, message);
1116-
MSG_WriteString(msg, message);
1115+
const char *pszGameDir = message;
1116+
1117+
#ifdef REHLDS_FIXES
1118+
// Give the client a chance to connect in to the server with different game
1119+
const char *gd = Info_ValueForKey(client->userinfo, "_gd");
1120+
if (gd[0])
1121+
pszGameDir = gd;
1122+
else
1123+
#endif
1124+
COM_FileBase(com_gamedir, message);
1125+
1126+
MSG_WriteString(msg, pszGameDir);
11171127
MSG_WriteString(msg, Cvar_VariableString("hostname"));
11181128
MSG_WriteString(msg, g_psv.modelname);
11191129

@@ -4030,9 +4040,10 @@ void SV_EmitEvents_internal(client_t *cl, packet_entities_t *pack, sizebuf_t *ms
40304040
}
40314041

40324042
int fatbytes;
4033-
unsigned char fatpvs[1024];
4043+
unsigned char fatpvs[MAX_MAP_LEAFS / 8];
4044+
40344045
int fatpasbytes;
4035-
unsigned char fatpas[1024];
4046+
unsigned char fatpas[MAX_MAP_LEAFS / 8];
40364047

40374048
void SV_AddToFatPVS(vec_t *org, mnode_t *node)
40384049
{
@@ -4074,6 +4085,9 @@ unsigned char* EXT_FUNC SV_FatPVS(float *org)
40744085
#endif // REHLDS_FIXES
40754086
fatbytes = (g_psv.worldmodel->numleafs + 31) >> 3;
40764087

4088+
if (fatbytes >= (MAX_MAP_LEAFS / 8))
4089+
Sys_Error("%s: MAX_MAP_LEAFS limit exceeded\n", __func__);
4090+
40774091
Q_memset(fatpvs, 0, fatbytes);
40784092
SV_AddToFatPVS(org, g_psv.worldmodel->nodes);
40794093
return fatpvs;
@@ -4131,6 +4145,9 @@ unsigned char* EXT_FUNC SV_FatPAS(float *org)
41314145
#endif // REHLDS_FIXES
41324146
fatpasbytes = (g_psv.worldmodel->numleafs + 31) >> 3;
41334147

4148+
if (fatpasbytes >= (MAX_MAP_LEAFS / 8))
4149+
Sys_Error("%s: MAX_MAP_LEAFS limit exceeded\n", __func__);
4150+
41344151
Q_memset(fatpas, 0, fatpasbytes);
41354152
SV_AddToFatPAS(org, g_psv.worldmodel->nodes);
41364153
return fatpas;
@@ -6155,7 +6172,7 @@ int SV_SpawnServer(qboolean bIsDemo, char *server, char *startspot)
61556172
if (g_psvs.maxclients <= 1)
61566173
{
61576174
int row = (g_psv.worldmodel->numleafs + 7) / 8;
6158-
if (row < 0 || row > MODEL_MAX_PVS)
6175+
if (row < 0 || row > (MAX_MAP_LEAFS / 8))
61596176
{
61606177
Sys_Error("%s: oversized g_psv.worldmodel->numleafs: %i", __func__, g_psv.worldmodel->numleafs);
61616178
}

rehlds/engine/sv_user.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,14 @@ void SV_CopyEdictToPhysent(physent_t *pe, int e, edict_t *check)
511511
pe->vuser4[2] = check->v.vuser4[2];
512512
}
513513

514+
bool EXT_FUNC SV_AllowPhysent_mod(edict_t* check, edict_t* sv_player) {
515+
return true;
516+
}
517+
518+
bool SV_AllowPhysent(edict_t* check, edict_t* sv_player) {
519+
return g_RehldsHookchains.m_SV_AllowPhysent.callChain(SV_AllowPhysent_mod, check, sv_player);
520+
}
521+
514522
void SV_AddLinksToPM_(areanode_t *node, float *pmove_mins, float *pmove_maxs)
515523
{
516524
struct link_s *l;
@@ -547,6 +555,11 @@ void SV_AddLinksToPM_(areanode_t *node, float *pmove_mins, float *pmove_maxs)
547555
if (check->v.solid != SOLID_BSP && check->v.solid != SOLID_BBOX && check->v.solid != SOLID_SLIDEBOX && check->v.solid != SOLID_NOT)
548556
continue;
549557

558+
// Apply our own custom checks
559+
if (!SV_AllowPhysent(check, sv_player)) {
560+
continue;
561+
}
562+
550563
e = NUM_FOR_EDICT(check);
551564
ve = &pmove->visents[pmove->numvisent];
552565
pmove->numvisent = pmove->numvisent + 1;

rehlds/public/rehlds/bspfile.h

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#define HLBSP_VERSION 30 // half-life regular version
3333

3434
#define MAX_MAP_HULLS 4
35+
#define MAX_MAP_LEAFS 32767 // signed short limit
3536

3637
#define CONTENTS_ORIGIN -7 // removed at csg time
3738
#define CONTENTS_CLIP -8 // changed to contents_solid

rehlds/public/rehlds/rehlds_api.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
#include "pr_dlls.h"
3838

3939
#define REHLDS_API_VERSION_MAJOR 3
40-
#define REHLDS_API_VERSION_MINOR 12
40+
#define REHLDS_API_VERSION_MINOR 13
4141

4242
//Steam_NotifyClientConnect hook
4343
typedef IHookChain<qboolean, IGameClient*, const void*, unsigned int> IRehldsHook_Steam_NotifyClientConnect;
@@ -255,6 +255,10 @@ typedef IVoidHookChainRegistry<resourcetype_t, const char *, int, unsigned char,
255255
typedef IVoidHookChain<const char *> IRehldsHook_SV_ClientPrintf;
256256
typedef IVoidHookChainRegistry<const char *> IRehldsHookRegistry_SV_ClientPrintf;
257257

258+
//SV_AllowPhysent hook
259+
typedef IHookChain<bool, edict_t*, edict_t*> IRehldsHook_SV_AllowPhysent;
260+
typedef IHookChainRegistry<bool, edict_t*, edict_t*> IRehldsHookRegistry_SV_AllowPhysent;
261+
258262
class IRehldsHookchains {
259263
public:
260264
virtual ~IRehldsHookchains() { }
@@ -313,6 +317,7 @@ class IRehldsHookchains {
313317
virtual IRehldsHookRegistry_EV_Precache* EV_Precache() = 0;
314318
virtual IRehldsHookRegistry_SV_AddResource* SV_AddResource() = 0;
315319
virtual IRehldsHookRegistry_SV_ClientPrintf* SV_ClientPrintf() = 0;
320+
virtual IRehldsHookRegistry_SV_AllowPhysent* SV_AllowPhysent() = 0;
316321
};
317322

318323
struct RehldsFuncs_t {

rehlds/rehlds/rehlds_api_impl.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,10 @@ IRehldsHookRegistry_SV_ClientPrintf* CRehldsHookchains::SV_ClientPrintf(){
879879
return &m_SV_ClientPrintf;
880880
}
881881

882+
IRehldsHookRegistry_SV_AllowPhysent* CRehldsHookchains::SV_AllowPhysent() {
883+
return &m_SV_AllowPhysent;
884+
}
885+
882886
int EXT_FUNC CRehldsApi::GetMajorVersion()
883887
{
884888
return REHLDS_API_VERSION_MAJOR;

0 commit comments

Comments
 (0)