Member
Join Date: Aug 2010
Location: middle-universe
|
02-12-2024
, 11:34
Detour AcceptInput
|
#1
|
Hello!
I tried to detour CBaseEntity::AcceptInput(char const*,CBaseEntity*,CBaseEntity*,variant_t,in t) reusing @Silvers Input Hooks code and got these:
Code:
L 02/12/2024 - 19:26:09: [SM] Exception reported: Invalid Handle 245 (error 7)
L 02/12/2024 - 19:26:09: [SM] Blaming: hooktp.smx
L 02/12/2024 - 19:26:09: [SM] Call stack trace:
L 02/12/2024 - 19:26:09: [SM] [0] DHookGetParamString
L 02/12/2024 - 19:26:09: [SM] [1] Line 66, D:\SourceMod\scripting\hooktp.sp::Detour_AcceptInput
Gamedata:
Code:
"Games"
{
"left4dead2"
{
"Functions"
{
"AcceptInput"
{
"signature" "AcceptInput"
"callconv" "thiscall"
"return" "int"
"this" "entity"
"arguments"
{
"name"
{
"type" "charptr"
}
"activator"
{
"type" "cbaseentity"
}
"caller"
{
"type" "cbaseentity"
}
"variant_t"
{
"type" "objectptr"
"size" "20"
}
"output"
{
"type" "int"
}
}
}
}
"Signatures"
{
"AcceptInput"
{
"linux" "@_ZN11CBaseEntity11AcceptInputEPKcPS_S2_9variant_ti"
}
}
}
}
PHP Code:
#include <sdktools> #include <dhooks> #include <sdktools>
#define MAX_ENTS 4096 #define LEN_CLASS 64
Handle hAcceptInput;
enum fieldtype_t { FIELD_VOID = 0, FIELD_FLOAT = 1, FIELD_STRING = 2, FIELD_VECTOR = 3, FIELD_INTEGER = 5, FIELD_BOOLEAN = 6, FIELD_SHORT = 7, FIELD_CHARACTER = 8, FIELD_COLOR32 = 9, FIELD_CLASSPTR = 12, FIELD_EHANDLE = 13, FIELD_POSITION_VECTOR = 15 }
enum struct variant_t { bool bValue; int iValue; float flValue; char iszValue[256]; int rgbaValue[4]; float vecValue[3]; fieldtype_t fieldType; }
public void OnPluginStart() { Handle hGameData = LoadGameConfigFile("l4d2_accept_input"); if(!hGameData) SetFailState("Couldn't find l4d2_accept_input gamedata."); int offset = GameConfGetOffset(hGameData, "AcceptInput"); Handle hAcceptInput = DHookCreateDetour(0, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity); if (!DHookSetFromConf(hAcceptInput, hGameData, SDKConf_Signature, "AcceptInput")) SetFailState("Failed to load AcceptInput signature from gamedata");
if (!DHookEnableDetour(hAcceptInput, false, Detour_AcceptInput)) SetFailState("Failed to detour ExecuteStringCommand.");
}
public MRESReturn Detour_AcceptInput(int pThis, Handle hReturn, Handle hParams) { // Get args static char result[128]; static char command[128]; DHookGetParamString(hParams, 1, command, sizeof(command));
variant_t params; params.fieldType = view_as<fieldtype_t>(DHookGetParamObjectPtrVar(hParams, 4, 16, ObjectValueType_Int));
switch (params.fieldType) { case FIELD_FLOAT: { params.flValue = DHookGetParamObjectPtrVar(hParams, 4, 0, ObjectValueType_Float); FloatToString(params.flValue, result, sizeof(result)); }
case FIELD_STRING: { DHookGetParamObjectPtrString(hParams, 4, 0, ObjectValueType_String, result, sizeof(result)); }
case FIELD_VECTOR, FIELD_POSITION_VECTOR: { DHookGetParamObjectPtrVarVector(hParams, 4, 0, ObjectValueType_Vector, params.vecValue); Format(result, sizeof(result), "%f, %f, %f", params.vecValue[0], params.vecValue[1], params.vecValue[2]); }
case FIELD_INTEGER, FIELD_SHORT, FIELD_CHARACTER: { params.iValue = DHookGetParamObjectPtrVar(hParams, 4, 0, ObjectValueType_Int); IntToString(params.iValue, result, sizeof(result)); }
case FIELD_BOOLEAN: { params.bValue = DHookGetParamObjectPtrVar(hParams, 4, 0, ObjectValueType_Bool); IntToString(params.bValue, result, sizeof(result)); }
case FIELD_COLOR32: { int color = DHookGetParamObjectPtrVar(hParams, 4, 0, ObjectValueType_Int); params.rgbaValue[0] = color & 0xFF; params.rgbaValue[1] = (color >> 8) & 0xFF; params.rgbaValue[2] = (color >> 16) & 0xFF; params.rgbaValue[3] = (color >> 24) & 0xFF;
Format(result, sizeof(result), "%d %d %d %d", params.rgbaValue[0], params.rgbaValue[1], params.rgbaValue[2], params.rgbaValue[3]); }
case FIELD_CLASSPTR, FIELD_EHANDLE: { params.iValue = DHookGetParamObjectPtrVar(hParams, 4, 0, ObjectValueType_Ehandle); IntToString(params.iValue, result, sizeof(result)); }
default: { Format(result, sizeof(result), "Unknown type: %d", params.fieldType); } }
static char classname[LEN_CLASS]; GetEntPropString(pThis, Prop_Data, "m_iClassname", classname, sizeof(classname));
if( pThis < 0 ) pThis = EntRefToEntIndex(pThis);
int entity = -1; if( DHookIsNullParam(hParams, 2) == false ) entity = DHookGetParam(hParams, 2);
// Activator + classname static char activator[LEN_CLASS]; static char sName[128];
activator[0] = 0; sName[0] = 0;
if( entity != -1 ) { if( entity > 0 && entity <= MaxClients ) Format(activator, sizeof(activator), "%N", entity); else { GetEntPropString(entity, Prop_Data, "m_iClassname", activator, sizeof(activator)); if( entity < 0 ) entity = EntRefToEntIndex(entity); } }
if( HasEntProp(pThis, Prop_Data, "m_iName") ) { GetEntPropString(pThis, Prop_Data, "m_iName", sName, sizeof(sName)); } if(StrEqual(classname, "func_elevator") && StrEqual(command, "MoveToFloor")) { // Print PrintToChatAll("\x01Ent %4d \x04%36s \x01Cmd \x05%20s \x01Name \x03%45s \x01Param \x03%12s \x01Act \x01%4d \x04%s", pThis, classname, command, sName, result, entity, activator); PrintToServer("\x01Ent %4d \x04%36s \x01Cmd \x05%20s \x01Name \x03%45s \x01Param \x03%12s \x01Act \x01%4d \x04%s", pThis, classname, command, sName, result, entity, activator); }
return MRES_Ignored; }
What am i missing?
Background: i used HookEntitySingleOutput in one of the plugins, but up to 50 frames can pass between Output and Input, and I had to track the state of several entities for those 50-100 frames. Using a detour for AcceptInput, it would be possible to reduce the complexity/code length by half.
Last edited by glhf3000; 02-12-2024 at 11:48.
|
|