Skip to content

Commit 9138316

Browse files
authored
Spray handling improvements - Freezetime, disabled spray, shutdown (#1218)
* Allow impulse 201 (spray) in freezetime * Prevent impulse 201 if the client disabled spray * Delete custom downloaded sprays on both startup and shutdown. Both mostly due to workaround filesystem API bug. * Also delete the 2-hex directories if they're empty * fixes #1205
1 parent 6247516 commit 9138316

File tree

3 files changed

+122
-4
lines changed

3 files changed

+122
-4
lines changed

src/game/client/c_te_playerdecal.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,16 @@
2222
// memdbgon must be the last include file in a .cpp file!!!
2323
#include "tier0/memdbgon.h"
2424

25+
#ifdef NEO
26+
// So that server/player.cpp can utilize cl_spraydisable to disable impulse 201
27+
static ConVar cl_spraydisable( "cl_spraydisable", "0", FCVAR_USERINFO | FCVAR_ARCHIVE, "Disable player sprays." );
28+
#else
2529
#ifdef TF_CLIENT_DLL
2630
static ConVar cl_spraydisable( "cl_spraydisable", "1", FCVAR_CLIENTDLL | FCVAR_ARCHIVE, "Disable player sprays." );
2731
#else
2832
static ConVar cl_spraydisable( "cl_spraydisable", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE, "Disable player sprays." );
2933
#endif
34+
#endif
3035

3136
#ifdef NEO
3237
extern ConVar sv_neo_spraydisable;

src/game/client/cdll_client_int.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,11 +187,13 @@ bool g_bOBSDetected = false;
187187
#include <tchar.h>
188188
#include <psapi.h>
189189
#include <tlhelp32.h>
190+
#include <direct.h>
190191
#undef CreateEvent
191192
#endif
192193

193194
#ifdef LINUX
194195
#include "neo_fixup_glshaders.h"
196+
#include <unistd.h>
195197
#endif
196198

197199
#endif
@@ -1303,6 +1305,90 @@ static void NeoClantag_ChangeCallback(IConVar *cvar, [[maybe_unused]] const char
13031305
}
13041306
#endif
13051307

1308+
#ifdef NEO
1309+
#define SZ_USERCUSTOM_DIR "download/user_custom"
1310+
// NEO NOTE (nullsystem): Delete custom downloaded sprays from other players on
1311+
// startup and shutdown.
1312+
// NEO JANK (nullsystem): It's done on both startup and shutdown mostly to
1313+
// mitigate SDK filesystem API bug so it likely remove all the expected files
1314+
// on shutdown.
1315+
static void NeoDeleteDownloadedSprays()
1316+
{
1317+
// NEO NOTE (nullsystem): Only deal with the .dat hexdec named files directly,
1318+
// no other directories (IFilesystem can't delete directories) or files deleted.
1319+
FileFindHandle_t findHdlFL;
1320+
for (const char *pszFNameFLDir = filesystem->FindFirst(SZ_USERCUSTOM_DIR "/*", &findHdlFL);
1321+
pszFNameFLDir && findHdlFL != FILESYSTEM_INVALID_FIND_HANDLE;
1322+
pszFNameFLDir = filesystem->FindNext(findHdlFL))
1323+
{
1324+
// Sanity check, expects directory of two character hexadecimal
1325+
const bool bIsValidFLDir = filesystem->FindIsDirectory(findHdlFL)
1326+
&& (V_strlen(pszFNameFLDir) == 2)
1327+
&& V_isxdigit(pszFNameFLDir[0])
1328+
&& V_isxdigit(pszFNameFLDir[1]);
1329+
if (!bIsValidFLDir)
1330+
{
1331+
continue;
1332+
}
1333+
1334+
char szSLRelPath[MAX_PATH];
1335+
V_sprintf_safe(szSLRelPath, SZ_USERCUSTOM_DIR "/%s", pszFNameFLDir);
1336+
1337+
char szSLSearch[MAX_PATH];
1338+
V_sprintf_safe(szSLSearch, "%s/*.dat", szSLRelPath);
1339+
1340+
FileFindHandle_t findHdlSL;
1341+
for (const char *pszFNameSLDat = filesystem->FindFirst(szSLSearch, &findHdlSL);
1342+
pszFNameSLDat && findHdlSL != FILESYSTEM_INVALID_FIND_HANDLE;
1343+
pszFNameSLDat = filesystem->FindNext(findHdlSL))
1344+
{
1345+
// Filename sanity check: Make sure filename is of this format: 00000000.dat - ffffffff.dat
1346+
static constexpr int BASE_FNAMESIZE = 8;
1347+
const int iFNameSLDatSize = V_strlen(pszFNameSLDat);
1348+
const bool bIsExpectedFNameSize = (iFNameSLDatSize == (BASE_FNAMESIZE + sizeof(".dat") - 1));
1349+
const bool bIsFile = !filesystem->FindIsDirectory(findHdlSL);
1350+
if (!bIsExpectedFNameSize || !bIsFile)
1351+
{
1352+
continue;
1353+
}
1354+
1355+
bool bFNameIsHexDigit = true;
1356+
for (int i = 0; bFNameIsHexDigit && i < BASE_FNAMESIZE; ++i)
1357+
{
1358+
bFNameIsHexDigit = V_isxdigit(pszFNameSLDat[i]);
1359+
}
1360+
if (!bFNameIsHexDigit)
1361+
{
1362+
continue;
1363+
}
1364+
1365+
char szFullFPathSLDat[MAX_PATH];
1366+
V_sprintf_safe(szFullFPathSLDat, SZ_USERCUSTOM_DIR "/%s/%s", pszFNameFLDir, pszFNameSLDat);
1367+
1368+
// NEO JANK (nullsystem): filesystem API seems buggy having earlier file(s) in alphanum order
1369+
// unable to recognize those files and remove them. When RemoveFile was called wasn't the issue
1370+
// and changing to calling it after Find... usages didn't solve it.
1371+
// So instead, doing this cleanup on both startup and shutdown could somewhat mitigate it.
1372+
filesystem->RemoveFile(szFullFPathSLDat);
1373+
}
1374+
filesystem->FindClose(findHdlSL);
1375+
1376+
// Remove this assumingly empty directory with rmdir
1377+
// It only removes empty directory so generally safe call
1378+
// and don't need to double check.
1379+
char szFullPath[MAX_PATH];
1380+
filesystem->RelativePathToFullPath_safe(szSLRelPath, "MOD", szFullPath);
1381+
#if defined(WIN32)
1382+
// Both slash deliminator is valid in Windows, don't need to convert
1383+
_rmdir(szFullPath);
1384+
#elif defined(LINUX)
1385+
rmdir(szFullPath);
1386+
#endif
1387+
}
1388+
filesystem->FindClose(findHdlFL);
1389+
}
1390+
#endif
1391+
13061392
//-----------------------------------------------------------------------------
13071393
// Purpose: Called after client & server DLL are loaded and all systems initialized
13081394
//-----------------------------------------------------------------------------
@@ -1409,6 +1495,8 @@ void CHLClient::PostInit()
14091495
{
14101496
V_memset(gStreamerModeNames[i], '.', 5);
14111497
}
1498+
1499+
NeoDeleteDownloadedSprays();
14121500
#endif // NEO
14131501

14141502
if ( !r_lightmap_bicubic_set.GetBool() && materials )
@@ -1427,6 +1515,10 @@ void CHLClient::PostInit()
14271515
//-----------------------------------------------------------------------------
14281516
void CHLClient::Shutdown( void )
14291517
{
1518+
#ifdef NEO
1519+
NeoDeleteDownloadedSprays();
1520+
#endif
1521+
14301522
if (g_pAchievementsAndStatsInterface)
14311523
{
14321524
g_pAchievementsAndStatsInterface->ReleasePanel();

src/game/server/player.cpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3887,19 +3887,35 @@ void CBasePlayer::PlayerRunCommand(CUserCmd *ucmd, IMoveHelper *moveHelper)
38873887
(developer.GetInt() == 0 && gpGlobals->eLoadType == MapLoad_NewGame && gpGlobals->curtime < 3.0));
38883888

38893889
#ifdef NEO
3890-
if (originalCheck || static_cast<CNEO_Player*>(this)->GetNeoFlags() & NEO_FL_FREEZETIME)
3890+
static constexpr byte IMPULSE_SPRAY = 201;
3891+
if (ucmd->impulse == IMPULSE_SPRAY)
3892+
{
3893+
const char *pszPlayerClDisableSpray = engine->GetClientConVarValue(entindex(), "cl_spraydisable");
3894+
const bool bPlayerClDisableSpray = StrToInt(pszPlayerClDisableSpray) != 0;
3895+
if (bPlayerClDisableSpray)
3896+
{
3897+
ucmd->impulse = 0;
3898+
}
3899+
}
3900+
3901+
const bool bPlayerInFreezeTime = static_cast<CNEO_Player*>(this)->GetNeoFlags() & NEO_FL_FREEZETIME;
3902+
if (originalCheck || bPlayerInFreezeTime)
38913903
#else
38923904
if (originalCheck)
38933905
#endif
38943906
{
38953907
ucmd->forwardmove = 0;
38963908
ucmd->sidemove = 0;
38973909
ucmd->upmove = 0;
3898-
ucmd->impulse = 0;
3899-
39003910
#ifdef NEO
3901-
if (!originalCheck && static_cast<CNEO_Player*>(this)->GetNeoFlags() & NEO_FL_FREEZETIME)
3911+
if (!originalCheck && bPlayerInFreezeTime)
39023912
{
3913+
// Also allow spraying impulse in freeze time (like in playing rounds)
3914+
if ((ucmd->impulse != IMPULSE_SPRAY) && (GetTeamNumber() == TEAM_JINRAI || GetTeamNumber() == TEAM_NSF))
3915+
{
3916+
ucmd->impulse = 0;
3917+
}
3918+
39033919
ucmd->buttons &= ~(IN_ATTACK | IN_ATTACK3 | IN_JUMP | IN_SPEED |
39043920
IN_ALT1 | IN_ALT2 | IN_BACK | IN_FORWARD | IN_MOVELEFT | IN_MOVERIGHT | IN_RUN | IN_ZOOM);
39053921
const bool isTachi = (dynamic_cast<CWeaponTachi*>(GetActiveWeapon()) != NULL);
@@ -3908,7 +3924,12 @@ void CBasePlayer::PlayerRunCommand(CUserCmd *ucmd, IMoveHelper *moveHelper)
39083924
ucmd->buttons &= ~IN_ATTACK2;
39093925
}
39103926
}
3927+
else
3928+
{
3929+
ucmd->impulse = 0;
3930+
}
39113931
#else
3932+
ucmd->impulse = 0;
39123933
ucmd->buttons = 0;
39133934
#endif
39143935

0 commit comments

Comments
 (0)