Do not spawn edicts for spawnpoints (info_player_*)

Filter players from +use Trace to prevent button stacking
This commit is contained in:
BotoX 2016-08-18 06:41:58 +02:00
parent 5119344c7d
commit fb39ae0f3c
3 changed files with 120 additions and 4 deletions

View File

@ -91,6 +91,9 @@ SMEXT_LINK(&g_Interface);
IGameConfig *g_pGameConf = NULL; IGameConfig *g_pGameConf = NULL;
CDetour *detourInputTestActivator = NULL; CDetour *detourInputTestActivator = NULL;
CDetour *detourPostConstructor = NULL;
CDetour *detourFindUseEntity = NULL;
CDetour *detourCTraceFilterSimple = NULL;
DETOUR_DECL_MEMBER1(InputTestActivator, void, inputdata_t *, inputdata) DETOUR_DECL_MEMBER1(InputTestActivator, void, inputdata_t *, inputdata)
{ {
@ -100,6 +103,42 @@ DETOUR_DECL_MEMBER1(InputTestActivator, void, inputdata_t *, inputdata)
DETOUR_MEMBER_CALL(InputTestActivator)(inputdata); DETOUR_MEMBER_CALL(InputTestActivator)(inputdata);
} }
DETOUR_DECL_MEMBER1(PostConstructor, void, const char *, szClassname)
{
if(strncmp(szClassname, "info_player_", 12) == 0)
{
CBaseEntity *pEntity = (CBaseEntity *)this;
datamap_t *pMap = gamehelpers->GetDataMap(pEntity);
typedescription_t *td = gamehelpers->FindInDataMap(pMap, "m_iEFlags");
*(uint32 *)((intptr_t)pEntity + td->fieldOffset[TD_OFFSET_NORMAL]) |= (1<<9); // EFL_SERVER_ONLY
}
DETOUR_MEMBER_CALL(PostConstructor)(szClassname);
}
volatile bool gv_InFindUseEntity = false;
DETOUR_DECL_MEMBER0(FindUseEntity, CBaseEntity *)
{
// Signal CTraceFilterSimple that we are in FindUseEntity
gv_InFindUseEntity = true;
CBaseEntity *pEntity = DETOUR_MEMBER_CALL(FindUseEntity)();
gv_InFindUseEntity = false;
return pEntity;
}
uintptr_t g_CTraceFilterNoNPCsOrPlayer = 0;
typedef bool (*ShouldHitFunc_t)( IHandleEntity *pHandleEntity, int contentsMask );
DETOUR_DECL_MEMBER3(CTraceFilterSimple, void, const IHandleEntity *, passedict, int, collisionGroup, ShouldHitFunc_t, pExtraShouldHitFunc)
{
DETOUR_MEMBER_CALL(CTraceFilterSimple)(passedict, collisionGroup, pExtraShouldHitFunc);
// If we're in FindUseEntity right now then switch out the VTable
if(gv_InFindUseEntity)
*(uintptr_t *)this = g_CTraceFilterNoNPCsOrPlayer;
}
bool CSSFixes::SDK_OnLoad(char *error, size_t maxlength, bool late) bool CSSFixes::SDK_OnLoad(char *error, size_t maxlength, bool late)
{ {
char conf_error[255] = ""; char conf_error[255] = "";
@ -114,15 +153,48 @@ bool CSSFixes::SDK_OnLoad(char *error, size_t maxlength, bool late)
CDetourManager::Init(g_pSM->GetScriptingEngine(), g_pGameConf); CDetourManager::Init(g_pSM->GetScriptingEngine(), g_pGameConf);
detourInputTestActivator = DETOUR_CREATE_MEMBER(InputTestActivator, "CBaseFilter_InputTestActivator"); detourInputTestActivator = DETOUR_CREATE_MEMBER(InputTestActivator, "CBaseFilter_InputTestActivator");
if(detourInputTestActivator == NULL) if(detourInputTestActivator == NULL)
{ {
snprintf(error, maxlength, "Could not create detour for CBaseFilter_InputTestActivator"); snprintf(error, maxlength, "Could not create detour for CBaseFilter_InputTestActivator");
return false; return false;
} }
detourInputTestActivator->EnableDetour(); detourInputTestActivator->EnableDetour();
detourPostConstructor = DETOUR_CREATE_MEMBER(PostConstructor, "CBaseEntity_PostConstructor");
if(detourPostConstructor == NULL)
{
snprintf(error, maxlength, "Could not create detour for CBaseEntity_PostConstructor");
return false;
}
detourPostConstructor->EnableDetour();
detourFindUseEntity = DETOUR_CREATE_MEMBER(FindUseEntity, "CBasePlayer_FindUseEntity");
if(detourFindUseEntity == NULL)
{
snprintf(error, maxlength, "Could not create detour for CBasePlayer_FindUseEntity");
return false;
}
detourFindUseEntity->EnableDetour();
detourCTraceFilterSimple = DETOUR_CREATE_MEMBER(CTraceFilterSimple, "CTraceFilterSimple_CTraceFilterSimple");
if(detourCTraceFilterSimple == NULL)
{
snprintf(error, maxlength, "Could not create detour for CTraceFilterSimple_CTraceFilterSimple");
return false;
}
detourCTraceFilterSimple->EnableDetour();
// Find VTable for CTraceFilterNoNPCsOrPlayer
uintptr_t pCTraceFilterNoNPCsOrPlayer;
if(!g_pGameConf->GetMemSig("CTraceFilterNoNPCsOrPlayer", (void **)(&pCTraceFilterNoNPCsOrPlayer)) || !pCTraceFilterNoNPCsOrPlayer)
{
snprintf(error, maxlength, "Failed to find CTraceFilterNoNPCsOrPlayer.\n");
SDK_OnUnload();
return false;
}
// First function in VTable
g_CTraceFilterNoNPCsOrPlayer = pCTraceFilterNoNPCsOrPlayer + 8;
void *pServerSo = dlopen("cstrike/bin/server_srv.so", RTLD_NOW); void *pServerSo = dlopen("cstrike/bin/server_srv.so", RTLD_NOW);
if(!pServerSo) if(!pServerSo)
{ {
@ -130,6 +202,7 @@ bool CSSFixes::SDK_OnLoad(char *error, size_t maxlength, bool late)
return false; return false;
} }
// Apply all patches
for(size_t i = 0; i < sizeof(gs_Patches) / sizeof(*gs_Patches); i++) for(size_t i = 0; i < sizeof(gs_Patches) / sizeof(*gs_Patches); i++)
{ {
struct SrcdsPatch *pPatch = &gs_Patches[i]; struct SrcdsPatch *pPatch = &gs_Patches[i];
@ -177,8 +250,27 @@ void CSSFixes::SDK_OnUnload()
detourInputTestActivator = NULL; detourInputTestActivator = NULL;
} }
if(detourPostConstructor != NULL)
{
detourPostConstructor->Destroy();
detourPostConstructor = NULL;
}
if(detourFindUseEntity != NULL)
{
detourFindUseEntity->Destroy();
detourFindUseEntity = NULL;
}
if(detourCTraceFilterSimple != NULL)
{
detourCTraceFilterSimple->Destroy();
detourCTraceFilterSimple = NULL;
}
gameconfs->CloseGameConfigFile(g_pGameConf); gameconfs->CloseGameConfigFile(g_pGameConf);
// Revert all applied patches
for(size_t i = 0; i < sizeof(gs_Patches) / sizeof(*gs_Patches); i++) for(size_t i = 0; i < sizeof(gs_Patches) / sizeof(*gs_Patches); i++)
{ {
struct SrcdsPatch *pPatch = &gs_Patches[i]; struct SrcdsPatch *pPatch = &gs_Patches[i];

View File

@ -9,6 +9,30 @@
"library" "server" "library" "server"
"linux" "@_ZN11CBaseFilter18InputTestActivatorER11inputdata_t" "linux" "@_ZN11CBaseFilter18InputTestActivatorER11inputdata_t"
} }
"CBaseEntity_PostConstructor"
{
"library" "server"
"linux" "@_ZN11CBaseEntity15PostConstructorEPKc"
}
"CBasePlayer_FindUseEntity"
{
"library" "server"
"linux" "@_ZN11CBasePlayer13FindUseEntityEv"
}
"CTraceFilterSimple_CTraceFilterSimple"
{
"library" "server"
"linux" "@_ZN18CTraceFilterSimpleC2EPK13IHandleEntityiPFbPS0_iE"
}
"CTraceFilterNoNPCsOrPlayer"
{
"library" "server"
"linux" "@_ZTV26CTraceFilterNoNPCsOrPlayer"
}
} }
} }
} }

View File

@ -40,7 +40,7 @@
/* Basic information exposed publicly */ /* Basic information exposed publicly */
#define SMEXT_CONF_NAME "CSSFixes" #define SMEXT_CONF_NAME "CSSFixes"
#define SMEXT_CONF_DESCRIPTION "Patches bugs in the CSS server binary." #define SMEXT_CONF_DESCRIPTION "Patches bugs in the CSS server binary."
#define SMEXT_CONF_VERSION "1.0" #define SMEXT_CONF_VERSION "1.1"
#define SMEXT_CONF_AUTHOR "BotoX" #define SMEXT_CONF_AUTHOR "BotoX"
#define SMEXT_CONF_URL "" #define SMEXT_CONF_URL ""
#define SMEXT_CONF_LOGTAG "CSSFIXES" #define SMEXT_CONF_LOGTAG "CSSFIXES"
@ -65,7 +65,7 @@
//#define SMEXT_ENABLE_DBMANAGER //#define SMEXT_ENABLE_DBMANAGER
#define SMEXT_ENABLE_GAMECONF #define SMEXT_ENABLE_GAMECONF
#define SMEXT_ENABLE_MEMUTILS #define SMEXT_ENABLE_MEMUTILS
//#define SMEXT_ENABLE_GAMEHELPERS #define SMEXT_ENABLE_GAMEHELPERS
//#define SMEXT_ENABLE_TIMERSYS //#define SMEXT_ENABLE_TIMERSYS
//#define SMEXT_ENABLE_THREADER //#define SMEXT_ENABLE_THREADER
//#define SMEXT_ENABLE_LIBSYS //#define SMEXT_ENABLE_LIBSYS