From 2ba27d409c364d12c01b6b72813ac4b991a6e224 Mon Sep 17 00:00:00 2001 From: s1lentq Date: Sun, 3 Sep 2023 15:08:30 +0700 Subject: [PATCH 1/6] Fixed reversing mistake, missing checking string for null --- rehlds/engine/pr_cmds.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rehlds/engine/pr_cmds.cpp b/rehlds/engine/pr_cmds.cpp index e1d956a..e83cbb4 100644 --- a/rehlds/engine/pr_cmds.cpp +++ b/rehlds/engine/pr_cmds.cpp @@ -1447,6 +1447,9 @@ int EXT_FUNC PF_precache_model_I_internal(const char *s) { for (int i = 0; i < MAX_MODELS; i++) { + if (!g_psv.model_precache[i]) + continue; + // use case-sensitive names to increase performance #ifdef REHLDS_FIXES if (!Q_strcmp(g_psv.model_precache[i], s)) @@ -1545,7 +1548,7 @@ int EXT_FUNC PF_precache_generic_I_internal(const char *s) { for (int i = 0; i < MAX_GENERIC; i++) { - if (!Q_stricmp(g_psv.generic_precache[i], s)) + if (g_psv.generic_precache[i] && !Q_stricmp(g_psv.generic_precache[i], s)) return i; } Host_Error("%s: '%s' Precache can only be done in spawn functions", __func__, s); From de3679f0391f1452532c820f07a8c4042b1c4281 Mon Sep 17 00:00:00 2001 From: s1lentq Date: Wed, 20 Sep 2023 20:20:14 +0700 Subject: [PATCH 2/6] Host_Motd_f: Fixed viewing motd when motdfile is not specified --- rehlds/engine/common.cpp | 28 ++++++++++++++++++++++++++++ rehlds/engine/common.h | 2 ++ rehlds/engine/host_cmd.cpp | 10 +++++++++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/rehlds/engine/common.cpp b/rehlds/engine/common.cpp index badf993..e70d03c 100644 --- a/rehlds/engine/common.cpp +++ b/rehlds/engine/common.cpp @@ -1978,6 +1978,34 @@ NOXREF int COM_ExpandFilename(char *filename) return *filename != 0; } +// small helper function shared by lots of modules +qboolean COM_IsAbsolutePath(const char *pStr) +{ + if (strchr(pStr, ':') || pStr[0] == '/' || pStr[0] == '\\') + return FALSE; + + return TRUE; +} + +qboolean COM_IsValidPath(const char *pszFilename) +{ + if (!pszFilename) + return FALSE; + + if (Q_strlen(pszFilename) <= 0 || + Q_strstr(pszFilename, "\\\\") || // to protect network paths + Q_strstr(pszFilename, ":") || // to protect absolute paths + Q_strstr(pszFilename, "..") || // to protect relative paths + Q_strstr(pszFilename, "~") || + Q_strstr(pszFilename, "\n") || // CFileSystem_Stdio::FS_fopen doesn't allow this + Q_strstr(pszFilename, "\r")) // CFileSystem_Stdio::FS_fopen doesn't allow this + { + return FALSE; + } + + return TRUE; +} + int EXT_FUNC COM_FileSize(const char *filename) { FileHandle_t fp; diff --git a/rehlds/engine/common.h b/rehlds/engine/common.h index 1a7fc08..94d9404 100644 --- a/rehlds/engine/common.h +++ b/rehlds/engine/common.h @@ -187,6 +187,8 @@ void COM_CreatePath(char *path); NOXREF void COM_CopyFile(char *netpath, char *cachepath); NOXREF int COM_ExpandFilename(char *filename); int COM_FileSize(const char *filename); +qboolean COM_IsAbsolutePath(const char *pStr); +qboolean COM_IsValidPath(const char *pszFilename); unsigned char *COM_LoadFile(const char *path, int usehunk, int *pLength); void COM_FreeFile(void *buffer); void COM_CopyFileChunk(FileHandle_t dst, FileHandle_t src, int nSize); diff --git a/rehlds/engine/host_cmd.cpp b/rehlds/engine/host_cmd.cpp index d76815c..3d6558c 100644 --- a/rehlds/engine/host_cmd.cpp +++ b/rehlds/engine/host_cmd.cpp @@ -205,11 +205,19 @@ void Host_Motd_f(void) char *next; pFileList = motdfile.string; - if (*pFileList == '/' || Q_strstr(pFileList, ":") || Q_strstr(pFileList, "..") || Q_strstr(pFileList, "\\")) + if (!COM_IsValidPath(pFileList) || COM_IsAbsolutePath(pFileList)) { Con_Printf("Unable to open %s (contains illegal characters)\n", pFileList); return; } + + const char *pchExtension = COM_FileExtension(pFileList); + if (Q_stricmp(pchExtension, "txt") != 0) + { + Con_Printf("Invalid motdfile name %s (wrong file extension, must be .txt)\n", pFileList); + return; + } + pFile = FS_Open(pFileList, "rb"); if (!pFile) { From 6f031901cfa85d86c6028086bc9335db1e867a03 Mon Sep 17 00:00:00 2001 From: s1lentq Date: Mon, 25 Sep 2023 02:08:04 +0700 Subject: [PATCH 3/6] Added cvarhook from latest HLDS build Making mapcyclefile/sv_cheats work in realtime Resolve #868 --- rehlds/common/cvardef.h | 12 ++++++++ rehlds/engine/cvar.cpp | 49 +++++++++++++++++++++++++++++-- rehlds/engine/host.cpp | 31 +++++++++++++++++-- rehlds/engine/net_ws.cpp | 4 +-- rehlds/engine/server.h | 1 - rehlds/engine/sv_main.cpp | 48 ++++++++++++++++++++++++++++-- rehlds/engine/zone.cpp | 2 +- rehlds/msvc/ReHLDS.vcxproj | 1 + rehlds/rehlds/rehlds_api_impl.cpp | 4 ++- 9 files changed, 140 insertions(+), 12 deletions(-) diff --git a/rehlds/common/cvardef.h b/rehlds/common/cvardef.h index aea0f9e..5d9e45e 100644 --- a/rehlds/common/cvardef.h +++ b/rehlds/common/cvardef.h @@ -47,4 +47,16 @@ struct cvar_listener_t const char *name; }; +typedef void (*pfnCvar_HookVariable_t) (cvar_t *pCvar); + +struct cvarhook_t +{ + pfnCvar_HookVariable_t hook; + + cvar_t *cvar; + cvarhook_t *next; +}; + +qboolean Cvar_HookVariable(const char *var_name, cvarhook_t *pHook); + #endif // CVARDEF_H diff --git a/rehlds/engine/cvar.cpp b/rehlds/engine/cvar.cpp index 9285fa2..7c7ce2b 100644 --- a/rehlds/engine/cvar.cpp +++ b/rehlds/engine/cvar.cpp @@ -32,7 +32,8 @@ All cvar names are case insensitive! Values not. */ -cvar_t *cvar_vars; +cvar_t *cvar_vars = NULL; +cvarhook_t *cvar_hooks = NULL; char cvar_null_string[] = ""; void Cvar_Init(void) @@ -319,8 +320,10 @@ void Cvar_DirectSet(struct cvar_s *var, const char *value) void Cvar_Set(const char *var_name, const char *value) { - cvar_t *var = Cvar_FindVar(var_name); + cvar_t *var; + cvarhook_t *pHook; + var = Cvar_FindVar(var_name); if (!var) { Con_DPrintf("%s: variable \"%s\" not found\n", __func__, var_name); @@ -328,6 +331,15 @@ void Cvar_Set(const char *var_name, const char *value) } Cvar_DirectSet(var, value); + + for (pHook = cvar_hooks; pHook; pHook = pHook->next) + { + if (pHook->cvar == var) + { + pHook->hook(var); + break; + } + } } void Cvar_SetValue(const char *var_name, float value) @@ -730,3 +742,36 @@ void Cvar_CmdInit(void) { Cmd_AddCommand("cvarlist", Cmd_CvarList_f); } + +qboolean Cvar_HookVariable(const char *var_name, cvarhook_t *pHook) +{ + cvar_t *cvar; + + if (!pHook || !pHook->hook) + return FALSE; + + if (pHook->cvar || pHook->next) + return FALSE; + + cvar = Cvar_FindVar(var_name); + if (!cvar) + return FALSE; + + cvarhook_t *pCur = cvar_hooks; + pHook->cvar = cvar; + + if (pCur) + { + while (pCur->next) + pCur = pCur->next; + + pCur->next = pHook; + } + else + { + // First in chain is null, assign pHook to it + cvar_hooks = pHook; + } + + return TRUE; +} diff --git a/rehlds/engine/host.cpp b/rehlds/engine/host.cpp index 3416efd..31560b7 100644 --- a/rehlds/engine/host.cpp +++ b/rehlds/engine/host.cpp @@ -57,7 +57,11 @@ cvar_t deathmatch = { "deathmatch", "0", FCVAR_SERVER, 0.0f, NULL }; cvar_t coop = { "coop", "0", FCVAR_SERVER, 0.0f, NULL }; cvar_t sys_ticrate = { "sys_ticrate", "100.0", 0, 0.0f, NULL }; + +void sys_timescale_hook_callback(cvar_t *cvar); +cvarhook_t sys_timescale_hook = { sys_timescale_hook_callback, NULL, NULL }; cvar_t sys_timescale = { "sys_timescale", "1.0", 0, 0.0f, NULL }; + cvar_t fps_max = { "fps_max", "100.0", FCVAR_ARCHIVE, 0.0f, NULL }; cvar_t host_killtime = { "host_killtime", "0.0", 0, 0.0f, NULL }; cvar_t sv_stats = { "sv_stats", "1", 0, 0.0f, NULL }; @@ -143,6 +147,9 @@ void Host_InitLocal(void) Host_InitCommands(); Cvar_RegisterVariable(&host_killtime); Cvar_RegisterVariable(&sys_ticrate); + Cvar_RegisterVariable(&sys_timescale); + Cvar_HookVariable(sys_timescale.name, &sys_timescale_hook); + Cvar_RegisterVariable(&fps_max); Cvar_RegisterVariable(&fps_override); Cvar_RegisterVariable(&host_name); @@ -355,7 +362,7 @@ void SV_ClientPrintf(const char *fmt, ...) { va_list va; char string[1024]; - + va_start(va, fmt); Q_vsnprintf(string, ARRAYSIZE(string) - 1, fmt, va); va_end(va); @@ -367,7 +374,7 @@ void SV_ClientPrintf(const char *fmt, ...) void EXT_FUNC SV_ClientPrintf_internal(const char *Dest) { char string[1024]; - + Q_strlcpy(string, Dest, min(strlen(Dest) + 1, sizeof(string))); MSG_WriteByte(&host_client->netchan.message, svc_print); MSG_WriteString(&host_client->netchan.message, string); @@ -1275,3 +1282,23 @@ void Host_Shutdown(void) g_psv.time = 0.0f; g_pcl.time = 0.0f; } + +void sys_timescale_hook_callback(cvar_t *cvar) +{ + int i; + client_t *client = NULL; + + if (!Host_IsServerActive()) + return; + + for (i = 0; i < g_psvs.maxclients; i++) + { + client = &g_psvs.clients[i]; + + if (!client->fakeclient && (client->active || client->spawned || client->connected)) + { + MSG_WriteByte(&client->netchan.message, svc_timescale); + MSG_WriteFloat(&client->netchan.message, max(0.1f, sys_timescale.value)); + } + } +} diff --git a/rehlds/engine/net_ws.cpp b/rehlds/engine/net_ws.cpp index 219b73a..4880da9 100644 --- a/rehlds/engine/net_ws.cpp +++ b/rehlds/engine/net_ws.cpp @@ -651,7 +651,7 @@ void NET_AdjustLag() } lasttime = realtime; - if (allow_cheats || fakelag.value == 0.0) + if (sv_cheats.value || fakelag.value == 0.0) { if (fakelag.value != gFakeLag) { @@ -689,7 +689,7 @@ qboolean NET_LagPacket(qboolean newdata, netsrc_t sock, netadr_t *from, sizebuf_ { if (fakeloss.value != 0.0) { - if (allow_cheats) + if (sv_cheats.value) { static int losscount[NS_MAX] = {}; ++losscount[sock]; diff --git a/rehlds/engine/server.h b/rehlds/engine/server.h index 4bdd7ef..eedb6f0 100644 --- a/rehlds/engine/server.h +++ b/rehlds/engine/server.h @@ -349,7 +349,6 @@ extern cvar_t sv_proxies; extern cvar_t sv_outofdatetime; extern cvar_t mapchangecfgfile; -extern qboolean allow_cheats; extern cvar_t mp_logecho; extern cvar_t mp_logfile; extern cvar_t sv_allow_download; diff --git a/rehlds/engine/sv_main.cpp b/rehlds/engine/sv_main.cpp index fa79fe9..b3779c9 100644 --- a/rehlds/engine/sv_main.cpp +++ b/rehlds/engine/sv_main.cpp @@ -100,7 +100,6 @@ redirect_t sv_redirected; netadr_t sv_redirectto; GameType_e g_eGameType = GT_Unitialized; -qboolean allow_cheats; char *gNullString = ""; int SV_UPDATE_BACKUP = SINGLEPLAYER_BACKUP; @@ -130,6 +129,12 @@ cvar_t sv_waterfriction = { "sv_waterfriction", "1", FCVAR_SERVER, 0.0f, NULL }; cvar_t sv_zmax = { "sv_zmax", "4096", FCVAR_SPONLY, 0.0f, NULL }; cvar_t sv_wateramp = { "sv_wateramp", "0", 0, 0.0f, NULL }; +void sv_cheats_hook_callback(cvar_t *cvar); +void mapcyclefile_hook_callback(cvar_t *cvar); + +cvarhook_t sv_cheats_hook = { sv_cheats_hook_callback, NULL, NULL }; +cvarhook_t mapcyclefile_hook = { mapcyclefile_hook_callback, NULL, NULL }; + cvar_t sv_skyname = { "sv_skyname", "desert", 0, 0.0f, NULL }; cvar_t mapcyclefile = { "mapcyclefile", "mapcycle.txt", 0, 0.0f, NULL }; cvar_t motdfile = { "motdfile", "motd.txt", 0, 0.0f, NULL }; @@ -1173,7 +1178,7 @@ void SV_SendServerinfo_internal(sizebuf_t *msg, client_t *client) MSG_WriteByte(msg, svc_sendextrainfo); MSG_WriteString(msg, com_clientfallback); - MSG_WriteByte(msg, allow_cheats); + MSG_WriteByte(msg, sv_cheats.value != 0); SV_WriteDeltaDescriptionsToClient(msg); SV_SetMoveVars(); @@ -6257,7 +6262,6 @@ int SV_SpawnServer(qboolean bIsDemo, char *server, char *startspot) gGlobalVariables.serverflags = g_psvs.serverflags; gGlobalVariables.mapname = (size_t)g_psv.name - (size_t)pr_strings; gGlobalVariables.startspot = (size_t)g_psv.startspot - (size_t)pr_strings; - allow_cheats = sv_cheats.value; SV_SetMoveVars(); return 1; @@ -6576,6 +6580,42 @@ void EXT_FUNC SV_SerializeSteamid(USERID_t* id, USERID_t* serialized) *serialized = *id; } +void sv_cheats_hook_callback(cvar_t *cvar) +{ + int i; + client_t *client = NULL; + + if (!Host_IsServerActive()) + return; + + for (i = 0; i < g_psvs.maxclients; i++) + { + client = &g_psvs.clients[i]; + + if (!client->fakeclient && (client->active || client->spawned || client->connected)) + { + MSG_WriteByte(&client->netchan.message, svc_sendextrainfo); + MSG_WriteString(&client->netchan.message, ""); + MSG_WriteByte(&client->netchan.message, sv_cheats.value != 0); + } + } +} + +void mapcyclefile_hook_callback(cvar_t *cvar) +{ + char buf[MAX_PATH + 4]; + + if (!Q_strcmp(COM_FileExtension(cvar->string), "txt")) + return; + + Q_snprintf(buf, sizeof(buf) - 3, "%s.txt", cvar->string); + + if (!Q_strcmp(COM_FileExtension(buf), "txt")) + Cvar_DirectSet(cvar, buf); + else + Cvar_DirectSet(cvar, "mapcycle.txt"); +} + void SV_BanId_f(void) { char szreason[256]; @@ -8014,6 +8054,7 @@ void SV_Init(void) Cvar_RegisterVariable(&sv_skyname); Cvar_RegisterVariable(&sv_maxvelocity); Cvar_RegisterVariable(&sv_cheats); + Cvar_HookVariable(sv_cheats.name, &sv_cheats_hook); if (COM_CheckParm("-dev")) Cvar_SetValue("sv_cheats", 1.0); Cvar_RegisterVariable(&sv_spectatormaxspeed); @@ -8025,6 +8066,7 @@ void SV_Init(void) Cvar_RegisterVariable(&sv_logbans); Cvar_RegisterVariable(&hpk_maxsize); Cvar_RegisterVariable(&mapcyclefile); + Cvar_HookVariable(mapcyclefile.name, &mapcyclefile_hook); Cvar_RegisterVariable(&motdfile); Cvar_RegisterVariable(&servercfgfile); Cvar_RegisterVariable(&mapchangecfgfile); diff --git a/rehlds/engine/zone.cpp b/rehlds/engine/zone.cpp index afd8469..3a1ab65 100644 --- a/rehlds/engine/zone.cpp +++ b/rehlds/engine/zone.cpp @@ -679,7 +679,7 @@ void Cache_Force_Flush() void Cache_Flush() { - if (g_pcl.maxclients <= 1 || allow_cheats) + if (g_pcl.maxclients <= 1 || sv_cheats.value) { Cache_Force_Flush(); } diff --git a/rehlds/msvc/ReHLDS.vcxproj b/rehlds/msvc/ReHLDS.vcxproj index 2078e83..dc15355 100644 --- a/rehlds/msvc/ReHLDS.vcxproj +++ b/rehlds/msvc/ReHLDS.vcxproj @@ -463,6 +463,7 @@ {6973dca5-253c-4d84-b51e-187e035eae06} + false diff --git a/rehlds/rehlds/rehlds_api_impl.cpp b/rehlds/rehlds/rehlds_api_impl.cpp index d186220..8d7f9da 100644 --- a/rehlds/rehlds/rehlds_api_impl.cpp +++ b/rehlds/rehlds/rehlds_api_impl.cpp @@ -52,7 +52,9 @@ char* EXT_FUNC GetClientFallback_api() { } int* EXT_FUNC GetAllowCheats_api() { - return &allow_cheats; + static int sv_cheats_stub = 0; + Con_Printf("WARNING! allow_cheats marked as deprecated! Use sv_cheats cvar directly!\n"); + return &sv_cheats_stub; } bool EXT_FUNC GSBSecure_api() { From 5ec8c29185a960ae31b090de735f8399a16b3042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Mu=C3=B1oz?= Date: Sun, 24 Sep 2023 17:40:50 -0300 Subject: [PATCH 4/6] Update world.cpp (#985) --- rehlds/engine/world.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/rehlds/engine/world.cpp b/rehlds/engine/world.cpp index 4cec668..2ba99d0 100644 --- a/rehlds/engine/world.cpp +++ b/rehlds/engine/world.cpp @@ -1190,13 +1190,15 @@ void SV_ClipToLinks(areanode_t *node, moveclip_t *clip) if (touch->v.solid == SOLID_TRIGGER) Sys_Error("%s: Trigger in clipping list", __func__); +#ifndef REHLDS_OPT_PEDANTIC if (gNewDLLFunctions.pfnShouldCollide && !gNewDLLFunctions.pfnShouldCollide(touch, clip->passedict)) #ifdef REHLDS_FIXES // https://github.com/dreamstalker/rehlds/issues/46 continue; #else return; -#endif +#endif // REHLDS_FIXES +#endif // REHLDS_OPT_PEDANTIC // monsterclip filter if (touch->v.solid == SOLID_BSP) @@ -1248,6 +1250,16 @@ void SV_ClipToLinks(areanode_t *node, moveclip_t *clip) continue; // don't clip against owner } +#ifdef REHLDS_OPT_PEDANTIC + if (gNewDLLFunctions.pfnShouldCollide && !gNewDLLFunctions.pfnShouldCollide(touch, clip->passedict)) +#ifdef REHLDS_FIXES + // https://github.com/dreamstalker/rehlds/issues/46 + continue; +#else + return; +#endif // REHLDS_FIXES +#endif // REHLDS_OPT_PEDANTIC + trace_t trace; if (touch->v.flags & FL_MONSTER) trace = SV_ClipMoveToEntity(touch, clip->start, clip->mins2, clip->maxs2, clip->end); From b7f6eb8023c87bc625317d608a849b3ea94f9ec6 Mon Sep 17 00:00:00 2001 From: Hamdi Date: Wed, 27 Sep 2023 18:41:37 +0100 Subject: [PATCH 5/6] Minor refactor ( add BoundsIntersect function ) (#986) --- rehlds/engine/mathlib.cpp | 9 +++++++++ rehlds/engine/mathlib_e.h | 1 + rehlds/engine/sv_user.cpp | 9 +-------- rehlds/engine/world.cpp | 28 ++++------------------------ 4 files changed, 15 insertions(+), 32 deletions(-) diff --git a/rehlds/engine/mathlib.cpp b/rehlds/engine/mathlib.cpp index 4647b97..667f510 100644 --- a/rehlds/engine/mathlib.cpp +++ b/rehlds/engine/mathlib.cpp @@ -418,3 +418,12 @@ qboolean VectorCompare(const vec_t *v1, const vec_t *v2) } #endif // #if !defined(REHLDS_SSE) + +qboolean BoundsIntersect(const vec3_t mins1, const vec3_t maxs1, const vec3_t mins2, const vec3_t maxs2) +{ + if (mins1[0] > maxs2[0] || mins1[1] > maxs2[1] || mins1[2] > maxs2[2]) + return FALSE; + if (maxs1[0] < mins2[0] || maxs1[1] < mins2[1] || maxs1[2] < mins2[2]) + return FALSE; + return TRUE; +} diff --git a/rehlds/engine/mathlib_e.h b/rehlds/engine/mathlib_e.h index 3b265a1..921c701 100644 --- a/rehlds/engine/mathlib_e.h +++ b/rehlds/engine/mathlib_e.h @@ -171,3 +171,4 @@ void R_ConcatTransforms(float in1[3][4], float in2[3][4], float out[3][4]); NOBODY void FloorDivMod(double numer, double denom, int *quotient, int *rem); NOBODY int GreatestCommonDivisor(int i1, int i2); NOBODY fixed16_t Invert24To16(fixed16_t val); +qboolean BoundsIntersect(const vec3_t mins1, const vec3_t maxs1, const vec3_t mins2, const vec3_t maxs2); diff --git a/rehlds/engine/sv_user.cpp b/rehlds/engine/sv_user.cpp index 0912cc0..f4c077d 100644 --- a/rehlds/engine/sv_user.cpp +++ b/rehlds/engine/sv_user.cpp @@ -525,7 +525,6 @@ void SV_AddLinksToPM_(areanode_t *node, float *pmove_mins, float *pmove_maxs) edict_t *check; int e; physent_t *ve; - int i; link_t *next; float *fmax; float *fmin; @@ -588,13 +587,7 @@ void SV_AddLinksToPM_(areanode_t *node, float *pmove_mins, float *pmove_maxs) if (check->v.flags & FL_CLIENT) SV_GetTrueMinMax(e - 1, &fmin, &fmax); - for (i = 0; i < 3; i++) - { - if (fmin[i] > pmove_maxs[i] || fmax[i] < pmove_mins[i]) - break; - } - - if (i != 3) + if (!BoundsIntersect(pmove_mins, pmove_maxs, fmin, fmax)) continue; if (check->v.solid || check->v.skin != -16) diff --git a/rehlds/engine/world.cpp b/rehlds/engine/world.cpp index 2ba99d0..8038ab7 100644 --- a/rehlds/engine/world.cpp +++ b/rehlds/engine/world.cpp @@ -359,12 +359,7 @@ void SV_TouchLinks(edict_t *ent, areanode_t *node) if (touch->v.solid != SOLID_TRIGGER) continue; - if (ent->v.absmin[0] > touch->v.absmax[0] - || ent->v.absmin[1] > touch->v.absmax[1] - || ent->v.absmin[2] > touch->v.absmax[2] - || ent->v.absmax[0] < touch->v.absmin[0] - || ent->v.absmax[1] < touch->v.absmin[1] - || ent->v.absmax[2] < touch->v.absmin[2]) + if (!BoundsIntersect(ent->v.absmin, ent->v.absmax, touch->v.absmin, touch->v.absmax)) continue; // check brush triggers accuracy @@ -647,12 +642,7 @@ int SV_LinkContents(areanode_t *node, const vec_t *pos) if (Mod_GetType(touch->v.modelindex) != mod_brush) continue; - if (pos[0] > touch->v.absmax[0] - || pos[1] > touch->v.absmax[1] - || pos[2] > touch->v.absmax[2] - || pos[0] < touch->v.absmin[0] - || pos[1] < touch->v.absmin[1] - || pos[2] < touch->v.absmin[2]) + if (!BoundsIntersect(pos, pos, touch->v.absmin, touch->v.absmax)) continue; int contents = touch->v.skin; @@ -1216,12 +1206,7 @@ void SV_ClipToLinks(areanode_t *node, moveclip_t *clip) if (clip->ignoretrans && touch->v.rendermode != kRenderNormal && !(touch->v.flags & FL_WORLDBRUSH)) continue; - if (clip->boxmins[0] > touch->v.absmax[0] - || clip->boxmins[1] > touch->v.absmax[1] - || clip->boxmins[2] > touch->v.absmax[2] - || clip->boxmaxs[0] < touch->v.absmin[0] - || clip->boxmaxs[1] < touch->v.absmin[1] - || clip->boxmaxs[2] < touch->v.absmin[2]) + if (!BoundsIntersect(clip->boxmins, clip->boxmaxs, touch->v.absmin, touch->v.absmax)) continue; if (touch->v.solid != SOLID_SLIDEBOX @@ -1310,12 +1295,7 @@ void SV_ClipToWorldbrush(areanode_t *node, moveclip_t *clip) if (!(touch->v.flags & FL_WORLDBRUSH)) continue; - if (clip->boxmins[0] > touch->v.absmax[0] - || clip->boxmins[1] > touch->v.absmax[1] - || clip->boxmins[2] > touch->v.absmax[2] - || clip->boxmaxs[0] < touch->v.absmin[0] - || clip->boxmaxs[1] < touch->v.absmin[1] - || clip->boxmaxs[2] < touch->v.absmin[2]) + if (!BoundsIntersect(clip->boxmins, clip->boxmaxs, touch->v.absmin, touch->v.absmax)) continue; if (clip->trace.allsolid) From 7fcec97af4c6598ab6a65d60cf424b7775a11729 Mon Sep 17 00:00:00 2001 From: s1lentq Date: Mon, 9 Oct 2023 01:57:11 +0700 Subject: [PATCH 6/6] Add support cheats command god,notarget,noclip --- rehlds/engine/host_cmd.cpp | 110 ++++++++++++++++++++++++++++++++++++- rehlds/engine/sv_user.cpp | 2 +- 2 files changed, 109 insertions(+), 3 deletions(-) diff --git a/rehlds/engine/host_cmd.cpp b/rehlds/engine/host_cmd.cpp index 3d6558c..993e56a 100644 --- a/rehlds/engine/host_cmd.cpp +++ b/rehlds/engine/host_cmd.cpp @@ -761,6 +761,111 @@ void Host_Status_Formatted_f(void) Host_Status_Printf(conprint, log, "%i users\n", nClients); } +// Sets client to godmode +void Host_God_f(void) +{ + if (cmd_source == src_command) + { + Cmd_ForwardToServer(); + return; + } + + if (!sv_cheats.value) + return; + + sv_player->v.flags = (int)sv_player->v.flags ^ FL_GODMODE; + if (!((int)sv_player->v.flags & FL_GODMODE)) + SV_ClientPrintf("godmode OFF\n"); + else + SV_ClientPrintf("godmode ON\n"); +} + +// Sets client to notarget mode +void Host_Notarget_f(void) +{ + if (cmd_source == src_command) + { + Cmd_ForwardToServer(); + return; + } + + if (!sv_cheats.value) + return; + + sv_player->v.flags = (int)sv_player->v.flags ^ FL_NOTARGET; + if (!((int)sv_player->v.flags & FL_NOTARGET)) + SV_ClientPrintf("notarget OFF\n"); + else + SV_ClientPrintf("notarget ON\n"); +} + +// Searches along the direction ray in steps of "step" to see if +// the entity position is passible +// Used for putting the player in valid space when toggling off noclip mode +int FindPassableSpace(edict_t *pEdict, vec_t *direction, float step) +{ + int i; + + for (i = 0; i < 100; i++) + { + VectorMA(pEdict->v.origin, step, direction, pEdict->v.origin); + + if (!SV_TestEntityPosition(pEdict)) + { + // Store old origin + VectorCopy(pEdict->v.origin, pEdict->v.oldorigin); + return TRUE; + } + } + + return FALSE; +} + +void Host_Noclip_f(void) +{ + if (cmd_source == src_command) + { + Cmd_ForwardToServer(); + return; + } + + if (!sv_cheats.value) + return; + + if (sv_player->v.movetype != MOVETYPE_NOCLIP) + { + sv_player->v.movetype = MOVETYPE_NOCLIP; + SV_ClientPrintf("noclip ON\n"); + } + else + { + sv_player->v.movetype = MOVETYPE_WALK; + + // Store old origin + VectorCopy(sv_player->v.origin, sv_player->v.oldorigin); + + SV_ClientPrintf("noclip OFF\n"); + + if (SV_TestEntityPosition(sv_player)) + { + vec3_t forward, right, up; + AngleVectors(sv_player->v.v_angle, forward, right, up); + + if (!FindPassableSpace(sv_player, forward, 1.0) + && !FindPassableSpace(sv_player, right, 1.0) + && !FindPassableSpace(sv_player, right, -1.0) // left + && !FindPassableSpace(sv_player, up, 1.0) // up + && !FindPassableSpace(sv_player, up, -1.0) // down + && !FindPassableSpace(sv_player, forward, -1.0)) // back + { + Con_DPrintf("Can't find the world\n"); + } + + VectorCopy(sv_player->v.oldorigin, sv_player->v.origin); + } + } +} + void Host_Ping_f(void) { int i; @@ -3146,11 +3251,12 @@ void Host_InitCommands(void) Cmd_AddCommand("setinfo", Host_SetInfo_f); Cmd_AddCommand("fullinfo", Host_FullInfo_f); -#ifndef SWDS Cmd_AddCommand("god", Host_God_f); Cmd_AddCommand("notarget", Host_Notarget_f); - Cmd_AddCommand("fly", Host_Fly_f); Cmd_AddCommand("noclip", Host_Noclip_f); + +#ifndef SWDS + Cmd_AddCommand("fly", Host_Fly_f); Cmd_AddCommand("viewmodel", Host_Viewmodel_f); Cmd_AddCommand("viewframe", Host_Viewframe_f); Cmd_AddCommand("viewnext", Host_Viewnext_f); diff --git a/rehlds/engine/sv_user.cpp b/rehlds/engine/sv_user.cpp index f4c077d..34ec651 100644 --- a/rehlds/engine/sv_user.cpp +++ b/rehlds/engine/sv_user.cpp @@ -42,7 +42,7 @@ edict_t *sv_player; qboolean nofind; #if defined(SWDS) && defined(REHLDS_FIXES) -const char *clcommands[] = { "status", "name", "kill", "pause", "spawn", "new", "sendres", "dropclient", "kick", "ping", "dlfile", "setinfo", "sendents", "fullupdate", "setpause", "unpause", NULL }; +const char *clcommands[] = { "status", "name", "kill", "pause", "spawn", "new", "sendres", "dropclient", "kick", "ping", "dlfile", "setinfo", "sendents", "fullupdate", "setpause", "unpause", "noclip", "god", "notarget", NULL }; #else const char *clcommands[23] = { "status", "god", "notarget", "fly", "name", "noclip", "kill", "pause", "spawn", "new", "sendres", "dropclient", "kick", "ping", "dlfile", "nextdl", "setinfo", "showinfo", "sendents", "fullupdate", "setpause", "unpause", NULL }; #endif