From 911b4a65e143294ce74d6ded3c552fb98fde4872 Mon Sep 17 00:00:00 2001 From: BotoX Date: Sun, 17 Nov 2019 18:28:39 +0100 Subject: [PATCH] Use bitfields instead of char arrays, make natives more useful for blocking TriggerMoved and SolidMoved. --- extension.cpp | 76 ++++++++++++++++++-------------------------- include/CSSFixes.inc | 22 +++++-------- smsdk_config.h | 2 +- 3 files changed, 40 insertions(+), 60 deletions(-) diff --git a/extension.cpp b/extension.cpp index e5b6821..15202f5 100644 --- a/extension.cpp +++ b/extension.cpp @@ -38,6 +38,10 @@ #include #include +#define SetBit(A,I) ((A)[(I) >> 5] |= (1 << ((I) & 31))) +#define ClearBit(A,I) ((A)[(I) >> 5] &= ~(1 << ((I) & 31))) +#define CheckBit(A,I) !!((A)[(I) >> 5] & (1 << ((I) & 31))) + bool UTIL_ContainsDataTable(SendTable *pTable, const char *name) { const char *pname = pTable->GetName(); @@ -520,21 +524,16 @@ void Physics_SimulateEntity_CustomLoop(CBaseEntity **ppList, int Count, float St } int g_TriggerEntityMoved; -char *g_pFilterTriggerTouchPlayers = NULL; -int g_FilterTriggerMoved = -1; +int *g_pFilterTriggerTouchPlayers = NULL; +int *g_pBlockTriggerMoved = NULL; // void IVEngineServer::TriggerMoved( edict_t *pTriggerEnt, bool testSurroundingBoundsOnly ) = 0; SH_DECL_HOOK2_void(IVEngineServer, TriggerMoved, SH_NOATTRIB, 0, edict_t *, bool); void TriggerMoved(edict_t *pTriggerEnt, bool testSurroundingBoundsOnly) { g_TriggerEntityMoved = gamehelpers->IndexOfEdict(pTriggerEnt); - // Allow all - if(g_FilterTriggerMoved == -1) - { - RETURN_META(MRES_IGNORED); - } - // Block All - else if(g_FilterTriggerMoved == 0) + // Block if bit is set + if(g_pBlockTriggerMoved && CheckBit(g_pBlockTriggerMoved, g_TriggerEntityMoved)) { RETURN_META(MRES_SUPERCEDE); } @@ -547,7 +546,7 @@ void TriggerMoved(edict_t *pTriggerEnt, bool testSurroundingBoundsOnly) SH_DECL_HOOK1(CTriggerMoved, EnumElement, SH_NOATTRIB, 0, IterationRetval_t, IHandleEntity *); IterationRetval_t TriggerMoved_EnumElement(IHandleEntity *pHandleEntity) { - if(g_FilterTriggerMoved <= 0 && !g_pFilterTriggerTouchPlayers) + if(!g_pFilterTriggerTouchPlayers) { RETURN_META_VALUE(MRES_IGNORED, ITERATION_CONTINUE); } @@ -562,14 +561,8 @@ IterationRetval_t TriggerMoved_EnumElement(IHandleEntity *pHandleEntity) RETURN_META_VALUE(MRES_IGNORED, ITERATION_CONTINUE); } - // block touching any clients here if map exists and evaluates to true - if(g_pFilterTriggerTouchPlayers && g_pFilterTriggerTouchPlayers[g_TriggerEntityMoved]) - { - RETURN_META_VALUE(MRES_SUPERCEDE, ITERATION_CONTINUE); - } - - // if filter is active block touch from all other players - if(g_FilterTriggerMoved > 0 && index != g_FilterTriggerMoved) + // block touching any clients here if bit is set + if(CheckBit(g_pFilterTriggerTouchPlayers, g_TriggerEntityMoved)) { RETURN_META_VALUE(MRES_SUPERCEDE, ITERATION_CONTINUE); } @@ -578,16 +571,20 @@ IterationRetval_t TriggerMoved_EnumElement(IHandleEntity *pHandleEntity) RETURN_META_VALUE(MRES_IGNORED, ITERATION_CONTINUE); } -cell_t FilterTriggerMoved(IPluginContext *pContext, const cell_t *params) +cell_t BlockTriggerMoved(IPluginContext *pContext, const cell_t *params) { - g_FilterTriggerMoved = params[1]; + if(params[2]) + pContext->LocalToPhysAddr(params[1], &g_pBlockTriggerMoved); + else + g_pBlockTriggerMoved = NULL; + return 0; } cell_t FilterTriggerTouchPlayers(IPluginContext *pContext, const cell_t *params) { if(params[2]) - pContext->LocalToPhysAddr(params[1], (cell_t **)&g_pFilterTriggerTouchPlayers); + pContext->LocalToPhysAddr(params[1], &g_pFilterTriggerTouchPlayers); else g_pFilterTriggerTouchPlayers = NULL; @@ -595,32 +592,21 @@ cell_t FilterTriggerTouchPlayers(IPluginContext *pContext, const cell_t *params) } int g_SolidEntityMoved; -int g_BlockSolidMoved = -1; -char *g_pFilterClientEntityMap = NULL; +int *g_pBlockSolidMoved = NULL; +int *g_pFilterClientEntityMap = NULL; // void IVEngineServer::SolidMoved( edict_t *pSolidEnt, ICollideable *pSolidCollide, const Vector* pPrevAbsOrigin, bool testSurroundingBoundsOnly ) = 0; SH_DECL_HOOK4_void(IVEngineServer, SolidMoved, SH_NOATTRIB, 0, edict_t *, ICollideable *, const Vector *, bool); void SolidMoved(edict_t *pSolidEnt, ICollideable *pSolidCollide, const Vector *pPrevAbsOrigin, bool testSurroundingBoundsOnly) { g_SolidEntityMoved = gamehelpers->IndexOfEdict(pSolidEnt); - // Allow all - if(g_BlockSolidMoved == -1) - { - RETURN_META(MRES_IGNORED); - } - // Block all - else if(g_BlockSolidMoved == 0) + // Block if bit is set + if(g_pBlockSolidMoved && CheckBit(g_pBlockSolidMoved, g_TriggerEntityMoved)) { RETURN_META(MRES_SUPERCEDE); } - // Block filtered entity - if(g_SolidEntityMoved == g_BlockSolidMoved) - { - RETURN_META(MRES_SUPERCEDE); - } - - // Allow all others + // Decide per entity in TouchLinks_EnumElement RETURN_META(MRES_IGNORED); } @@ -650,12 +636,8 @@ IterationRetval_t TouchLinks_EnumElement(IHandleEntity *pHandleEntity) RETURN_META_VALUE(MRES_IGNORED, ITERATION_CONTINUE); } - // SourcePawn char map[MAXPLAYERS + 1][2048] - // Contiguous memory, shift array by client idx * 2048 - int arrayIdx = g_SolidEntityMoved * 2048 + index; - // Block player from touching this entity if it's filtered - if(g_pFilterClientEntityMap[arrayIdx]) + if(CheckBit(g_pFilterClientEntityMap, g_SolidEntityMoved * 2048 + index)) { RETURN_META_VALUE(MRES_SUPERCEDE, ITERATION_CONTINUE); } @@ -666,14 +648,18 @@ IterationRetval_t TouchLinks_EnumElement(IHandleEntity *pHandleEntity) cell_t BlockSolidMoved(IPluginContext *pContext, const cell_t *params) { - g_BlockSolidMoved = params[1]; + if(params[2]) + pContext->LocalToPhysAddr(params[1], &g_pBlockSolidMoved); + else + g_pBlockSolidMoved = NULL; + return 0; } cell_t FilterClientEntityMap(IPluginContext *pContext, const cell_t *params) { if(params[2]) - pContext->LocalToPhysAddr(params[1], (cell_t **)&g_pFilterClientEntityMap); + pContext->LocalToPhysAddr(params[1], &g_pFilterClientEntityMap); else g_pFilterClientEntityMap = NULL; @@ -945,7 +931,7 @@ bool CSSFixes::SDK_OnLoad(char *error, size_t maxlength, bool late) const sp_nativeinfo_t MyNatives[] = { - { "FilterTriggerMoved", FilterTriggerMoved }, + { "BlockTriggerMoved", BlockTriggerMoved }, { "BlockSolidMoved", BlockSolidMoved }, { "FilterClientEntityMap", FilterClientEntityMap }, { "FilterTriggerTouchPlayers", FilterTriggerTouchPlayers }, diff --git a/include/CSSFixes.inc b/include/CSSFixes.inc index ed2c198..de9998e 100644 --- a/include/CSSFixes.inc +++ b/include/CSSFixes.inc @@ -8,23 +8,17 @@ forward void OnPrePlayerThinkFunctions(); forward void OnPostPlayerThinkFunctions(); forward void OnRunThinkFunctionsPost(bool simulating); -// -1 = Ignore, normal operation. -// 0 = Block ALL SV_TriggerMoved. -// >0 = Entity index for which to allow EnumElement to be called. -// REMEMBER TO CALL THIS AGAIN WITH -1 AFTER USING IT !!! -native void FilterTriggerMoved(int entity); +// Block TriggerMoved from being called at all for an entity by setting the bit to 1. +native void BlockTriggerMoved(int map[2048 / 32], bool set); -// -1 = Ignore, normal operation. -// 0 = Block ALL SV_SolidMoved. -// >0 = Entity index for which to allow SV_SolidMoved to be called. -// REMEMBER TO CALL THIS AGAIN WITH -1 AFTER USING IT !!! -native void BlockSolidMoved(int entity); +// Block SolidMoved from being called at all for an entity by setting the bit to 1. +native void BlockSolidMoved(int map[2048 / 32], bool set); -// Block clients SolidMoved from touching an entity by setting it to 1 in the clients map. -native void FilterClientEntityMap(char map[MAXPLAYERS + 1][2048], bool set); +// Block clients SolidMoved from touching an entity by setting the bit to 1 in the clients map. +native void FilterClientEntityMap(int map[((MAXPLAYERS + 1) * 2048) / 32], bool set); -// Block triggers TriggerMoved from touching any client by setting it to 1 for the entity index. -native void FilterTriggerTouchPlayers(char map[2048], bool set); +// Block triggers TriggerMoved from touching any client by setting the bit to 1 for the entity index. +native void FilterTriggerTouchPlayers(int map[2048 / 32], bool set); // Map entities to client entity in FireBullets/SwingOrStab ShouldHitEntity. // Aka. shoot and knife through physboxes that are parented to teammates (white knight, gandalf, horse, etc.) diff --git a/smsdk_config.h b/smsdk_config.h index d72d0b2..1bb1ff9 100644 --- a/smsdk_config.h +++ b/smsdk_config.h @@ -40,7 +40,7 @@ /* Basic information exposed publicly */ #define SMEXT_CONF_NAME "CSSFixes" #define SMEXT_CONF_DESCRIPTION "Patches bugs in the CSS server binary and more..." -#define SMEXT_CONF_VERSION "1.14" +#define SMEXT_CONF_VERSION "1.15" #define SMEXT_CONF_AUTHOR "BotoX" #define SMEXT_CONF_URL "" #define SMEXT_CONF_LOGTAG "CSSFIXES"