bug fixes

- Remove spam from DHooks regarding null entities by using a method by gammacase
- Fix waitTime problems by using only OnTrigger
- Use FindEntityByName instead of looping through everything
This commit is contained in:
hermansimensen 2021-03-17 02:51:09 +01:00
parent 9abb5d22c1
commit c5d9768232
2 changed files with 144 additions and 36 deletions

View File

@ -25,7 +25,25 @@
"windows" "\x55\x8B\xEC\x83\xE4\xF8\x81\xEC\x58\x02\x00\x00\xA1\x2A\x2A\x2A\x2A" "windows" "\x55\x8B\xEC\x83\xE4\xF8\x81\xEC\x58\x02\x00\x00\xA1\x2A\x2A\x2A\x2A"
"linux" "\x55\x89\xE5\x57\x56\x53\x81\xEC\xBC\x01\x00\x00\xA1\x2A\x2A\x2A\x2A" "linux" "\x55\x89\xE5\x57\x56\x53\x81\xEC\xBC\x01\x00\x00\xA1\x2A\x2A\x2A\x2A"
} }
"FindEntityByName"
{
"windows" "\x55\x8B\xEC\x53\x8B\x5D\x0C\x85\xDB\x74\x2A"
"linux" "\x55\x89\xE5\x57\x56\x53\x83\xEC\x2C\x8B\x4D\x14"
}
}
"Offsets"
{
"m_angRotation"
{
"class" "CBaseEntity"
"prop" "m_angRotation"
}
"m_RefEHandle"
{
"windows" "12"
"linux" "12"
}
} }
} }
"cstrike" "cstrike"
@ -37,6 +55,26 @@
"windows" "\x55\x8B\xEC\x56\x57\x8B\xF9\xB9\x2A\x2A\x2A\x2A\x6A\x38\xE8\x2A\x2A\x2A\x2A\x8B\xF0\x85\xF6\x74\x2A\xC7\x46\x0C\xFF\xFF\xFF\xFF\xC7\x46\x10\xFF\xFF\xFF\xFF\xC7\x46\x18\xFF\xFF\xFF\xFF\xC7\x46\x1C\x00\x00\x00\x00\xC7\x46\x28\xFF\xFF\xFF\xFF\xC7\x46\x2C\x00\x00\x00\x00\xEB\x2A\x33\xF6\xA1\x2A\x2A\x2A\x2A\xF3\x0F\x10\x40\x0C" "windows" "\x55\x8B\xEC\x56\x57\x8B\xF9\xB9\x2A\x2A\x2A\x2A\x6A\x38\xE8\x2A\x2A\x2A\x2A\x8B\xF0\x85\xF6\x74\x2A\xC7\x46\x0C\xFF\xFF\xFF\xFF\xC7\x46\x10\xFF\xFF\xFF\xFF\xC7\x46\x18\xFF\xFF\xFF\xFF\xC7\x46\x1C\x00\x00\x00\x00\xC7\x46\x28\xFF\xFF\xFF\xFF\xC7\x46\x2C\x00\x00\x00\x00\xEB\x2A\x33\xF6\xA1\x2A\x2A\x2A\x2A\xF3\x0F\x10\x40\x0C"
"linux" "@_ZN11CEventQueue8AddEventEPKcS1_9variant_tfP11CBaseEntityS4_i" "linux" "@_ZN11CEventQueue8AddEventEPKcS1_9variant_tfP11CBaseEntityS4_i"
} }
"FindEntityByName"
{
"windows" "\x55\x8B\xEC\x53\x8B\x5D\x0C\x56\x8B\xF1\x85\xDB\x74\x2A"
"linux" "@_ZN17CGlobalEntityList16FindEntityByNameEP11CBaseEntityPKcS1_S1_S1_P17IEntityFindFilter"
}
}
"Offsets"
{
"m_angRotation"
{
"class" "CBaseEntity"
"prop" "m_angRotation"
}
"m_RefEHandle"
{
"windows" "32"
"linux" "32"
}
} }
} }
} }

View File

@ -15,10 +15,22 @@
#pragma semicolon 1 #pragma semicolon 1
#define MAX_EDICT_BITS 11
#define MAX_EDICTS (1 << MAX_EDICT_BITS)
#define NUM_ENT_ENTRY_BITS (MAX_EDICT_BITS + 2)
#define NUM_ENT_ENTRIES (1 << NUM_ENT_ENTRY_BITS)
#define INVALID_EHANDLE_INDEX 0xFFFFFFFF
#define NUM_SERIAL_NUM_BITS 16 // (32 - NUM_ENT_ENTRY_BITS)
#define NUM_SERIAL_NUM_SHIFT_BITS (32 - NUM_SERIAL_NUM_BITS)
#define ENT_ENTRY_MASK (( 1 << NUM_SERIAL_NUM_BITS) - 1)
ArrayList g_aPlayerEvents[MAXPLAYERS+1]; ArrayList g_aPlayerEvents[MAXPLAYERS+1];
ArrayList g_aOutputWait[MAXPLAYERS+1]; ArrayList g_aOutputWait[MAXPLAYERS+1];
bool g_bLateLoad; bool g_bLateLoad;
Handle g_hFindEntityByName;
int g_iRefOffset;
enum struct event_t enum struct event_t
{ {
@ -33,7 +45,7 @@ enum struct event_t
enum struct entity_t enum struct entity_t
{ {
int outputID; int caller;
float waitTime; float waitTime;
} }
@ -49,6 +61,7 @@ public Plugin myinfo =
public void OnPluginStart() public void OnPluginStart()
{ {
LoadDHooks(); LoadDHooks();
HookEntityOutput("trigger_multiple", "OnTrigger", OnTrigger);
} }
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
@ -77,11 +90,12 @@ public void OnClientPutInServer(int client)
if(g_aPlayerEvents[client] == null) if(g_aPlayerEvents[client] == null)
{ {
g_aPlayerEvents[client] = new ArrayList(sizeof(event_t)); g_aPlayerEvents[client] = new ArrayList(sizeof(event_t));
} else }
else
{ {
g_aPlayerEvents[client].Clear(); g_aPlayerEvents[client].Clear();
} }
if(g_aOutputWait[client] == null) if(g_aOutputWait[client] == null)
{ {
g_aOutputWait[client] = new ArrayList(sizeof(entity_t)); g_aOutputWait[client] = new ArrayList(sizeof(entity_t));
@ -115,6 +129,21 @@ void LoadDHooks()
{ {
SetFailState("Failed to load eventfix gamedata"); SetFailState("Failed to load eventfix gamedata");
} }
int m_RefEHandleOff = gamedataConf.GetOffset("m_RefEHandle");
int ibuff = gamedataConf.GetOffset("m_angRotation");
g_iRefOffset = ibuff + m_RefEHandleOff;
StartPrepSDKCall(SDKCall_Static);
PrepSDKCall_SetFromConf(gamedataConf, SDKConf_Signature, "FindEntityByName");
PrepSDKCall_SetReturnInfo(SDKType_CBaseEntity, SDKPass_Pointer);
PrepSDKCall_AddParameter(SDKType_CBaseEntity, SDKPass_Pointer, VDECODE_FLAG_ALLOWNULL | VDECODE_FLAG_ALLOWWORLD);
PrepSDKCall_AddParameter(SDKType_String, SDKPass_Pointer);
PrepSDKCall_AddParameter(SDKType_CBaseEntity, SDKPass_Pointer, VDECODE_FLAG_ALLOWNULL | VDECODE_FLAG_ALLOWWORLD);
PrepSDKCall_AddParameter(SDKType_CBaseEntity, SDKPass_Pointer, VDECODE_FLAG_ALLOWNULL | VDECODE_FLAG_ALLOWWORLD);
PrepSDKCall_AddParameter(SDKType_CBaseEntity, SDKPass_Pointer, VDECODE_FLAG_ALLOWNULL | VDECODE_FLAG_ALLOWWORLD);
PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
g_hFindEntityByName = EndPrepSDKCall();
/* /*
Handle acceptInput = DHookCreateDetour(Address_Null, CallConv_THISCALL, ReturnType_Bool, ThisPointer_CBaseEntity); Handle acceptInput = DHookCreateDetour(Address_Null, CallConv_THISCALL, ReturnType_Bool, ThisPointer_CBaseEntity);
@ -157,7 +186,7 @@ void LoadDHooks()
DHookAddParam(addEventThree, HookParamType_CharPtr); DHookAddParam(addEventThree, HookParamType_CharPtr);
DHookAddParam(addEventThree, HookParamType_Object, 20, DHookPass_ByVal|DHookPass_ODTOR|DHookPass_OCTOR|DHookPass_OASSIGNOP); DHookAddParam(addEventThree, HookParamType_Object, 20, DHookPass_ByVal|DHookPass_ODTOR|DHookPass_OCTOR|DHookPass_OASSIGNOP);
DHookAddParam(addEventThree, HookParamType_Float); DHookAddParam(addEventThree, HookParamType_Float);
DHookAddParam(addEventThree, HookParamType_CBaseEntity); DHookAddParam(addEventThree, HookParamType_Int);
DHookAddParam(addEventThree, HookParamType_CBaseEntity); DHookAddParam(addEventThree, HookParamType_CBaseEntity);
DHookAddParam(addEventThree, HookParamType_Int); DHookAddParam(addEventThree, HookParamType_Int);
if(!DHookEnableDetour(addEventThree, false, DHook_AddEventThree)) if(!DHookEnableDetour(addEventThree, false, DHook_AddEventThree))
@ -214,6 +243,27 @@ public MRESReturn DHook_AddEventTwo(Handle hParams)
return MRES_Ignored; return MRES_Ignored;
} */ } */
//Credits to gammacase for this workaround.
int EntityToBCompatRef(Address player)
{
if(player == Address_Null)
return INVALID_EHANDLE_INDEX;
int m_RefEHandle = LoadFromAddress(player + view_as<Address>(g_iRefOffset), NumberType_Int32);
if(m_RefEHandle == INVALID_EHANDLE_INDEX)
return INVALID_EHANDLE_INDEX;
// https://github.com/perilouswithadollarsign/cstrike15_src/blob/29e4c1fda9698d5cebcdaf1a0de4b829fa149bf8/public/basehandle.h#L137
int entry_idx = m_RefEHandle & ENT_ENTRY_MASK;
if(entry_idx >= MAX_EDICTS)
return m_RefEHandle | (1 << 31);
return entry_idx;
}
public MRESReturn DHook_AddEventThree(Handle hParams) public MRESReturn DHook_AddEventThree(Handle hParams)
{ {
event_t event; event_t event;
@ -221,29 +271,36 @@ public MRESReturn DHook_AddEventThree(Handle hParams)
DHookGetParamString(hParams, 2, event.targetInput, 64); DHookGetParamString(hParams, 2, event.targetInput, 64);
DHookGetParamObjectPtrString(hParams, 3, 0, ObjectValueType_String, event.variantValue, sizeof(event.variantValue)); DHookGetParamObjectPtrString(hParams, 3, 0, ObjectValueType_String, event.variantValue, sizeof(event.variantValue));
event.delay = DHookGetParam(hParams, 4); event.delay = DHookGetParam(hParams, 4);
event.activator = DHookGetParam(hParams, 5); event.activator = EntityToBCompatRef(view_as<Address>(DHookGetParam(hParams, 5)));
event.caller = DHookGetParam(hParams, 6); event.caller = DHookGetParam(hParams, 6);
event.outputID = DHookGetParam(hParams, 7); event.outputID = DHookGetParam(hParams, 7);
#if defined DEBUG #if defined DEBUG
PrintToChatAll("AddEventThree: %s, %s, %s, %f, %i, %i, %i", event.target, event.targetInput, event.variantValue, event.delay, event.activator, event.caller, event.outputID); PrintToChatAll("AddEventThree: %s, %s, %s, %f, %i, %i, %i", event.target, event.targetInput, event.variantValue, event.delay, event.activator, event.caller, event.outputID);
#endif #endif
if((event.activator < 65 && event.activator > 0)) if((event.activator < 65 && event.activator > 0))
{ {
float m_flWait = 0.0; g_aPlayerEvents[event.activator].PushArray(event);
if(!IsValidClient(event.caller)) return MRES_Supercede;
{ }
m_flWait = GetEntPropFloat(event.caller, Prop_Data, "m_flWait");
} return MRES_Ignored;
}
public Action OnTrigger(const char[] output, int caller, int activator, float delay)
{
if(activator <= MAXPLAYERS && activator > 0)
{
float m_flWait = GetEntPropFloat(caller, Prop_Data, "m_flWait");
bool bFound; bool bFound;
entity_t ent; entity_t ent;
for(int i = 0; i < g_aOutputWait[event.activator].Length; i++) for(int i = 0; i < g_aOutputWait[activator].Length; i++)
{ {
g_aOutputWait[event.activator].GetArray(i, ent); g_aOutputWait[activator].GetArray(i, ent);
if(ent.outputID == event.outputID) if(caller == ent.caller)
{ {
bFound = true; bFound = true;
break; break;
@ -252,16 +309,17 @@ public MRESReturn DHook_AddEventThree(Handle hParams)
if(!bFound) if(!bFound)
{ {
g_aPlayerEvents[event.activator].PushArray(event); ent.caller = caller;
ent.outputID = event.outputID;
ent.waitTime = m_flWait; ent.waitTime = m_flWait;
g_aOutputWait[event.activator].PushArray(ent); g_aOutputWait[activator].PushArray(ent);
return Plugin_Continue;
} }
return MRES_Supercede; else
} {
return Plugin_Handled;
return MRES_Ignored; }
}
return Plugin_Continue;
} }
public void ServiceEvent(event_t event) public void ServiceEvent(event_t event)
@ -278,25 +336,37 @@ public void ServiceEvent(event_t event)
targetEntity = event.caller; targetEntity = event.caller;
AcceptEntityInput(targetEntity, event.targetInput, event.activator, event.caller, event.outputID); AcceptEntityInput(targetEntity, event.targetInput, event.activator, event.caller, event.outputID);
} }
else if(!strcmp("!self", event.target, false))
{
targetEntity = event.caller;
AcceptEntityInput(targetEntity, event.targetInput, event.activator, event.caller, event.outputID);
}
else else
{ {
for (int entity = 0; entity < GetMaxEntities()*2; entity++) if(!strcmp("kill", event.targetInput, false))
{ {
if (!IsValidEntity(entity)) { for(int i = 0; i < 32; i++)
continue; {
} targetEntity = SDKCall(g_hFindEntityByName, 0, event.target, event.caller, event.activator, event.caller, NULL_STRING);
if(targetEntity != -1)
char buffer[64]; {
GetEntPropString(entity, Prop_Data, "m_iName", buffer, 64); AcceptEntityInput(targetEntity, event.targetInput, event.activator, event.caller, event.outputID);
} else
if (!strcmp(event.target, buffer, false)) {
break;
}
}
}
else
{
targetEntity = SDKCall(g_hFindEntityByName, 0, event.target, event.caller, event.activator, event.caller, NULL_STRING);
if(targetEntity != -1)
{ {
targetEntity = entity;
AcceptEntityInput(targetEntity, event.targetInput, event.activator, event.caller, event.outputID); AcceptEntityInput(targetEntity, event.targetInput, event.activator, event.caller, event.outputID);
} }
} }
} }
#if defined DEBUG #if defined DEBUG
PrintToChat(event.activator, "Performing output: %s, %i, %i, %s %s, %i, %f", event.target, targetEntity, event.caller, event.targetInput, event.variantValue, event.outputID, GetGameTime()); PrintToChat(event.activator, "Performing output: %s, %i, %i, %s %s, %i, %f", event.target, targetEntity, event.caller, event.targetInput, event.variantValue, event.outputID, GetGameTime());
#endif #endif