Raised This Month: $51 Target: $400
 12% 

Detour AcceptInput


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
glhf3000
Member
Join Date: Aug 2010
Location: middle-universe
Old 02-12-2024 , 11:34   Detour AcceptInput
Reply With Quote #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(0HookType_EntityReturnType_BoolThisPointer_CBaseEntity);
    
    if (!
DHookSetFromConf(hAcceptInputhGameDataSDKConf_Signature"AcceptInput"))
        
SetFailState("Failed to load AcceptInput signature from gamedata");

    if (!
DHookEnableDetour(hAcceptInputfalseDetour_AcceptInput))
        
SetFailState("Failed to detour ExecuteStringCommand.");

}

public 
MRESReturn Detour_AcceptInput(int pThisHandle hReturnHandle hParams)
{
    
// Get args
    
static char result[128];
    static 
char command[128];
    
DHookGetParamString(hParams1commandsizeof(command));

    
variant_t params;
    
params.fieldType view_as<fieldtype_t>(DHookGetParamObjectPtrVar(hParams416ObjectValueType_Int));

    switch (
params.fieldType)
    {
        case 
FIELD_FLOAT:
        {
            
params.flValue DHookGetParamObjectPtrVar(hParams40ObjectValueType_Float);
            
FloatToString(params.flValueresultsizeof(result));
        }

        case 
FIELD_STRING:
        {
            
DHookGetParamObjectPtrString(hParams40ObjectValueType_Stringresultsizeof(result));
        }

        case 
FIELD_VECTORFIELD_POSITION_VECTOR:
        {
            
DHookGetParamObjectPtrVarVector(hParams40ObjectValueType_Vectorparams.vecValue);
            
Format(resultsizeof(result), "%f, %f, %f"params.vecValue[0], params.vecValue[1], params.vecValue[2]);
        }

        case 
FIELD_INTEGERFIELD_SHORTFIELD_CHARACTER:
        {
            
params.iValue DHookGetParamObjectPtrVar(hParams40ObjectValueType_Int);
            
IntToString(params.iValueresultsizeof(result));
        }

        case 
FIELD_BOOLEAN:
        {
            
params.bValue DHookGetParamObjectPtrVar(hParams40ObjectValueType_Bool);
            
IntToString(params.bValueresultsizeof(result));
        }

        case 
FIELD_COLOR32:
        {
            
int color DHookGetParamObjectPtrVar(hParams40ObjectValueType_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(resultsizeof(result), "%d %d %d %d"params.rgbaValue[0], params.rgbaValue[1], params.rgbaValue[2], params.rgbaValue[3]);
        }

        case 
FIELD_CLASSPTRFIELD_EHANDLE:
        {
            
params.iValue DHookGetParamObjectPtrVar(hParams40ObjectValueType_Ehandle);
            
IntToString(params.iValueresultsizeof(result));
        }

        default:
        {
            
Format(resultsizeof(result), "Unknown type: %d"params.fieldType);
        }
    }

    static 
char classname[LEN_CLASS];
    
GetEntPropString(pThisProp_Data"m_iClassname"classnamesizeof(classname));

    if( 
pThis )
        
pThis EntRefToEntIndex(pThis);

    
int entity = -1;
    if( 
DHookIsNullParam(hParams2) == false )
        
entity DHookGetParam(hParams2);

    
// Activator + classname
    
static char activator[LEN_CLASS];
    static 
char sName[128];

    
activator[0] = 0;
    
sName[0] = 0;

    if( 
entity != -)
    {
        if( 
entity && entity <= MaxClients )
            
Format(activatorsizeof(activator), "%N"entity);
        else
        {
            
GetEntPropString(entityProp_Data"m_iClassname"activatorsizeof(activator));
            if( 
entity )
                
entity EntRefToEntIndex(entity);
        }
    }

    if( 
HasEntProp(pThisProp_Data"m_iName") )
    {
        
GetEntPropString(pThisProp_Data"m_iName"sNamesizeof(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"pThisclassnamecommandsNameresultentityactivator);
        
PrintToServer("\x01Ent %4d \x04%36s \x01Cmd \x05%20s \x01Name \x03%45s \x01Param \x03%12s \x01Act \x01%4d \x04%s"pThisclassnamecommandsNameresultentityactivator);
    }

    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.
glhf3000 is offline
Spirit_12
Veteran Member
Join Date: Dec 2012
Location: Toronto, CA
Old 02-12-2024 , 16:16   Re: Detour AcceptInput
Reply With Quote #2

I would suggest you do this via vscript for a much easier access. Not sure what your goal is, but hooking an input/output is much easier.
__________________
Spirit_12 is offline
glhf3000
Member
Join Date: Aug 2010
Location: middle-universe
Old 02-13-2024 , 00:01   Re: Detour AcceptInput
Reply With Quote #3

Quote:
Originally Posted by Spirit_12 View Post
I would suggest you do this via vscript for a much easier access. Not sure what your goal is, but hooking an input/output is much easier.

In short, I added additional cars/boxes of the class prop_physics through stripper for charger-fun. But on c5m5_bridge (see screenshot), at the very beginning, one of them just disappeared after pressing the radio. It turned out that func_elevator in void CFuncElevator::MoveTo(float destinationZ) simply deletes all prop_physics entities inside func_elev to prevent players from falling down. This was complicated by the fact that a charger could push the car at the moment of pressing the button, and it just disappeared in the process. And the place and moment are interesting/funny, you can knock a car onto someone’s head, or after lowering the bridge, immediately push it into all the survivors. The option with patching CFuncElevator::MoveTo is difficult, beyond my capabilities. I made a DHookEntity on AcceptInput - but by that moment the car had already been deleted, and it was impossible to restore it. I had to hook trigger_finale, and from that moment track its parameters, in case it was pushed and it’s already flying, i.e., upon deletion, create it in the same frame, and restore the same angular and regular velocity. It turned out to be cumbersome, but works as needed. And with a detour, you can remove half of the code, and simply at the moment of AcceptInput triggering, capture the parameters and restore them in the same frame.

As for vscript, I'll read about it, I haven’t used them before. https://developer.valvesoftware.com/...unctions#Hooks looks like its what i need
Attached Thumbnails
Click image for larger version

Name:	20240213074723_1.jpg
Views:	49
Size:	96.5 KB
ID:	203206  
Attached Files
File Type: sp Get Plugin or Get Source (l4d2_add_bridge_start_car.sp - 14 views - 21.8 KB)

Last edited by glhf3000; 02-13-2024 at 01:13.
glhf3000 is offline
Marttt
Veteran Member
Join Date: Jan 2019
Location: Brazil
Old 02-13-2024 , 17:09   Re: Detour AcceptInput
Reply With Quote #4

You can try changing stuff by using Stripper as well since is map specific.
__________________
Marttt is offline
Forgetest
Member
Join Date: Aug 2020
Old 02-14-2024 , 08:34   Re: Detour AcceptInput
Reply With Quote #5

I think the detour setup is wrong. Try changing the type of "variant_t" to "object".

It seems like you're recreating them after delection, how about creating static models and replacing with physics later when elevator movement finishes?
Forgetest is offline
glhf3000
Member
Join Date: Aug 2010
Location: middle-universe
Old 02-15-2024 , 02:01   Re: Detour AcceptInput
Reply With Quote #6

Quote:
Originally Posted by Forgetest View Post
I think the detour setup is wrong. Try changing the type of "variant_t" to "object".
Nope, it didnt work

Quote:
Originally Posted by Forgetest View Post
It seems like you're recreating them after delection, how about creating static models and replacing with physics later when elevator movement finishes?
This option is unsuitable because I need to keep the ability to push the car down onto the survivors' heads at any moment of the game, whether before, during, or after the func_elevator movement starts. Otherwise, it would all look shoddy.
glhf3000 is offline
Peace-Maker
SourceMod Plugin Approver
Join Date: Aug 2008
Location: Germany
Old 02-15-2024 , 02:10   Re: Detour AcceptInput
Reply With Quote #7

You're mixing declaration of "Functions" in the gamedata and manually setting up hooks in sourcepawn code. To use the function definition in your gamedata, use "DHookCreateFromConf" instead of "DHookCreateDetour" and "DHookSetFromConf". Or add appropriate "DHookAddParam" calls to your plugin, but it seems like you want to use the gamedata file to define the hook setup.

The error is triggered because you're trying to access parameters but never told dhooks that there were any in your code, since you didn't use the definition from your gamedata file.
__________________

Last edited by Peace-Maker; 02-15-2024 at 02:11.
Peace-Maker is offline
glhf3000
Member
Join Date: Aug 2010
Location: middle-universe
Old 02-15-2024 , 11:23   Re: Detour AcceptInput
Reply With Quote #8

Quote:
Originally Posted by Peace-Maker View Post
You're mixing declaration of "Functions" in the gamedata and manually setting up hooks in sourcepawn code. To use the function definition in your gamedata, use "DHookCreateFromConf" instead of "DHookCreateDetour" and "DHookSetFromConf". Or add appropriate "DHookAddParam" calls to your plugin, but it seems like you want to use the gamedata file to define the hook setup.

The error is triggered because you're trying to access parameters but never told dhooks that there were any in your code, since you didn't use the definition from your gamedata file.
Thx a lot, got it now, works as expected
glhf3000 is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 14:58.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode