Raised This Month: $7 Target: $400
 1% 

Passing a reference parameter to CreateVCall


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
TheDS1337
Veteran Member
Join Date: Jun 2012
Old 03-16-2019 , 11:19   Passing a reference parameter to CreateVCall
Reply With Quote #1

Hello guys, I'm trying to call the function CorpseGib from CBaseCombatCharacter with this code
PHP Code:
bool CorpseGib(CBaseEntity *clientEntity, const CTakeDamageInfoHack &damageInfo)
{
    
CONSOLE_DEBUGGER("Call started!");

    static 
ICallWrapper *pCallWrapper nullptr;

    if( !
pCallWrapper )
    {
        
PassInfo info[2];

        
info[0].flags PASSFLAG_BYREF PASSFLAG_OCTOR PASSFLAG_OCOPYCTOR;
        
info[0].size sizeof(CTakeDamageInfoHack);
        
info[0].type PassType_Object;
        
info[1].type PassType_Basic;
        
info[1].flags PASSFLAG_BYVAL;
        
info[1].size sizeof(bool);

        
pCallWrapper g_pExtension->m_pBinTools->CreateVCall(31000, &info[1], info1);

        if( !
pCallWrapper )
        {
            
CONSOLE_DEBUGGER("Failed to create a call to CBaseCombatCharacter:CorpseGib");
            return 
false;
        }

        
g_pExtension->m_pBinCallWrappers.push_back(pCallWrapper);
    }

    
unsigned char params[sizeof(CBaseEntity *) + sizeof(CTakeDamageInfoHack)];
    
unsigned char *vparams params;

    *(
CBaseEntity **) vparams clientEntityvparams += sizeof(CBaseEntity *);
    
memcpy(vparams, &damageInfosizeof(CTakeDamageInfoHack));

    
bool gibbed false;
    
pCallWrapper->Execute(params, &gibbed);

    
CONSOLE_DEBUGGER("Call ended!");

    return 
gibbed;

As you can see, the reference is making things a bit harder and I took a look at SDKTools's AcceptEntityInput, it is the only one using PassType_Object (apart from the ValveCaller);

The offset is: 310, and just to be sure I tested both 309 and 311. Although 310 seems the 'only' one giving gibbed = true as a result, I am confused, I mean the function is probably getting called but nothing is happening?

PS: I'm using the takedamageinfohack header and source file from SDKHooks to wrap around CTakeDamageInfo

Last edited by TheDS1337; 03-16-2019 at 11:21.
TheDS1337 is offline
Fyren
FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren
Join Date: Feb 2106
Old 03-19-2019 , 03:25   Re: Passing a reference parameter to CreateVCall
Reply With Quote #2

Off the top of my head, you don't want to memcpy the contents of CTakeDamageInfo. You want to put its address there and bintools/SH will do the right thing.

But, to debug, you should probably set a breakpoint on the actual virtual function you want to be calling. You'll be able to verify it's being called because your breakpoint will get hit and then you can inspect the stack to make sure the right address of your CTakeDamageInfo is there. It's also possible the game itself doesn't use that function or it does nothing. A breakpoint will let you know that as well.
Fyren is offline
TheDS1337
Veteran Member
Join Date: Jun 2012
Old 03-19-2019 , 04:23   Re: Passing a reference parameter to CreateVCall
Reply With Quote #3

Quote:
Originally Posted by Fyren View Post
Off the top of my head, you don't want to memcpy the contents of CTakeDamageInfo. You want to put its address there and bintools/SH will do the right thing.

But, to debug, you should probably set a breakpoint on the actual virtual function you want to be calling. You'll be able to verify it's being called because your breakpoint will get hit and then you can inspect the stack to make sure the right address of your CTakeDamageInfo is there. It's also possible the game itself doesn't use that function or it does nothing. A breakpoint will let you know that as well.
Thanks for the explication, I really appreciate that because I dont know infact how the Bintools work exactly, I just took of SDKTool's examples and modified them...

Now, that I've tried to call that function inside a sourcemod plugin instead of an extension I just found out that VALVe removed the very functionality I needed from it... (this is in CS:GO), this function used to tear the player apart into peaces with the SpawnRandomGibs function, now only SpawnRandomHeadGibs works, the others dont

EDIT: here's some randomness for anybody if they want to try it...
PHP Code:
#include <sourcemod>
#include <sdktools>
#include <dhooks>
 
#pragma newdecls required

Handle hSpawnHeadGibhSpawnRandomGibshCorpseGibhInitGibhSpawnGib;

Handle hHasHumanGibshHasAlienGibs;

public 
void OnPluginStart()
{
    
Handle config LoadGameConfigFile("zitests.games");
    
    if( 
config == null )
    {
        
SetFailState("Failed to load the config");
    }
    
    
bool prep_finished false;
    
    
StartPrepSDKCall(SDKCall_Player);
    
    
prep_finished PrepSDKCall_SetFromConf(configSDKConf_Signature"SpawnHeadGib");
    
    if( 
prep_finished )
    {
        
PrintToServer("Preparation for the SpawnHeadGib SDK call is a success!");        
    }
    
    
PrepSDKCall_AddParameter(SDKType_CBasePlayerSDKPass_Pointer);
    
hSpawnHeadGib EndPrepSDKCall();
        
    if( 
hSpawnHeadGib == null )
    {
        
PrintToServer("Failed to start SpawnHeadGib call");
    }
    
    
    
StartPrepSDKCall(SDKCall_Player);
    
    
prep_finished PrepSDKCall_SetFromConf(configSDKConf_Signature"SpawnRandomGibs");
    
    if( 
prep_finished )
    {
        
PrintToServer("Preparation for the SpawnRandomGibs SDK call is a success!");
    }
    
    
PrepSDKCall_AddParameter(SDKType_CBasePlayerSDKPass_Pointer);
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_Plain);
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_ByValue);
    
hSpawnRandomGibs EndPrepSDKCall();
        
    if( 
hSpawnRandomGibs == null )
    {
        
PrintToServer("Failed to start SpawnRandomGibs call");
    }    
//
    
StartPrepSDKCall(SDKCall_Player);
    
    
prep_finished PrepSDKCall_SetFromConf(configSDKConf_Signature"CorpseGib");
    
    if( 
prep_finished )
    {
        
PrintToServer("Preparation for the CorpseGib SDK call is a success!");
    }
/*
    Vector            m_vecDamageForce;
    Vector            m_vecDamagePosition;
    Vector            m_vecReportedPosition;    // Position players are told damage is coming from
    EHANDLE            m_hInflictor;
    EHANDLE            m_hAttacker;
    EHANDLE            m_hWeapon;
    float            m_flDamage;
    float            m_flMaxDamage;
    float            m_flBaseDamage;            // The damage amount before skill leve adjustments are made. Used to get uniform damage forces.
    int                m_bitsDamageType;
    int                m_iDamageCustom;
    int                m_iDamageStats;
    int                m_iAmmoType;            // AmmoType of the weapon used to cause this damage, if any
    float            m_flRadius;
    
    // CS:GO
    int                m_iDamagedOtherPlayers;
    int                m_iObjectsPenetrated;
    uint32            m_uiBulletID;
    uint8            m_uiRecoilIndex;
*/    
    
PrepSDKCall_SetReturnInfo(SDKType_BoolSDKType_PlainOldData);
    
    
PrepSDKCall_AddParameter(SDKType_VectorSDKPass_ByRef);
    
PrepSDKCall_AddParameter(SDKType_VectorSDKPass_ByRef);
    
PrepSDKCall_AddParameter(SDKType_VectorSDKPass_ByRef);
    
PrepSDKCall_AddParameter(SDKType_CBaseEntitySDKPass_Pointer);
    
PrepSDKCall_AddParameter(SDKType_CBaseEntitySDKPass_Pointer);
    
PrepSDKCall_AddParameter(SDKType_CBaseEntitySDKPass_Pointer);
    
PrepSDKCall_AddParameter(SDKType_FloatSDKPass_ByRef);
    
PrepSDKCall_AddParameter(SDKType_FloatSDKPass_ByRef);
    
PrepSDKCall_AddParameter(SDKType_FloatSDKPass_ByRef);
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_ByRef);
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_ByRef);
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_ByRef);
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_ByRef);
    
PrepSDKCall_AddParameter(SDKType_FloatSDKPass_ByRef);
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_ByRef);
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_ByRef);
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_ByRef);
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_ByRef);
    
    
hCorpseGib EndPrepSDKCall();
        
    if( 
hCorpseGib == null )
    {
        
PrintToServer("Failed to start CorpseGib call");
    }
    
    
    
StartPrepSDKCall(SDKCall_Entity);
    
    
prep_finished PrepSDKCall_SetFromConf(configSDKConf_Signature"SpawnGib");
    
    if( 
prep_finished )
    {
        
PrintToServer("Preparation for the SpawnGib SDK call is a success!");        
    }
    
    
PrepSDKCall_AddParameter(SDKType_StringSDKPass_Pointer);    
    
hSpawnGib EndPrepSDKCall();
        
    if( 
hSpawnGib == null )
    {
        
PrintToServer("Failed to start SpawnGib call");
    }
    
    
    
StartPrepSDKCall(SDKCall_Entity);
    
    
prep_finished PrepSDKCall_SetFromConf(configSDKConf_Signature"InitGib");
    
    if( 
prep_finished )
    {
        
PrintToServer("Preparation for the InitGib SDK call is a success!");        
    }
    
    
PrepSDKCall_AddParameter(SDKType_CBasePlayerSDKPass_Pointer);
    
PrepSDKCall_AddParameter(SDKType_FloatSDKPass_ByValue);
    
PrepSDKCall_AddParameter(SDKType_FloatSDKPass_ByValue);
    
hInitGib EndPrepSDKCall();
        
    if( 
hInitGib == null )
    {
        
PrintToServer("Failed to start InitGib call");
    }
    
    
    
hHasHumanGibs DHookCreate(312HookType_EntityReturnType_BoolThisPointer_CBaseEntityPreHasHumanGibs);
    
hHasAlienGibs DHookCreate(313HookType_EntityReturnType_BoolThisPointer_CBaseEntityPreHasAlienGibs);
}

public 
void OnMapStart()
{
    
    
PrecacheModel("models/gibs/hgibs.mdl"true);
    
AddFileToDownloadsTable("models/gibs/hgibs.mdl");
    
PrecacheModel("models/gibs/hgibs_rib.mdl"true);
    
AddFileToDownloadsTable("models/gibs/hgibs_rib.mdl");
    
PrecacheModel("models/gibs/hgibs_scapula.mdl"true);
    
AddFileToDownloadsTable("models/gibs/hgibs_scapula.mdl");
    
PrecacheModel("models/gibs/hgibs_spine.mdl"true);
    
AddFileToDownloadsTable("models/gibs/hgibs_spine.mdl");
    
AddFileToDownloadsTable("materials/models/gibs/hgibs/rib.vmt");
    
AddFileToDownloadsTable("materials/models/gibs/hgibs/scapula.vmt");
    
AddFileToDownloadsTable("materials/models/gibs/hgibs/skull1.vmt");
    
AddFileToDownloadsTable("materials/models/gibs/hgibs/spine.vmt");
    
    
AddFileToDownloadsTable("materials/models/gibs/hgibs/skull1.vmt");    
    
PrecacheModel("materials/models/gibs/hgibs/skull1.vmt"true);
    
PrecacheGeneric("materials/models/gibs/hgibs/skull1.vmt"true);
    
    
PrecacheModel("models/gibs/agibs.mdl"true);
    
AddFileToDownloadsTable("models/gibs/agibs.mdl");
}

void ChangeBloodColor(int clientint bloodColor)
{
    
SetEntProp(clientProp_Data"m_bloodColor"bloodColor);
}
 
void SpawnHeadGib(int client)
{
    
SDKCall(hSpawnHeadGibclientclient);
}

void SpawnRandomGibs(int clientint gibsint gibsType)
{
    
SDKCall(hSpawnRandomGibsclientclientgibsgibsType);
}

void SpawnGib(int gibEntity, const char[] gibModel)
{
    
SDKCall(hSpawnGibgibEntitygibModel);
}

void InitGib(int gibEntityint clientfloat minVelocityfloat maxVelocity)
{
    
SDKCall(hInitGibgibEntityclientminVelocitymaxVelocity);
}

#define    HUMAN_GIB_COUNT 6
#define ALIEN_GIB_COUNT 4

void SpawnRandomGibs2(int clientint gibsint gibType )
{
    
int gibEntity = -1;
    for( 
int splat 0splat gibssplat++ )
    {
        
gibEntity CreateEntityByName("gib");
        
        if( 
gibEntity == -)
        {
            
PrintToChat(client"Failed to create gib entity");
            continue;
        }

        if( 
gibType == )
        {
            
// Human        
            
SpawnGib(gibEntity"models/gibs/hgibs.mdl");
            
SetEntProp(gibEntityProp_Data"m_nBody"GetRandomInt(1HUMAN_GIB_COUNT 1)); 
            
            
PrintToChat(client"HUMAN GIBs!");
        }            
        else if( 
gibType == )
        {    
            
// Alien
            
SpawnGib(gibEntity"models/gibs/agibs.mdl");            
            
SetEntProp(gibEntityProp_Data"m_nBody"GetRandomInt(0ALIEN_GIB_COUNT 1));     

            
PrintToChat(client"ALIEN GIBs!");
        }
        
        
float origin[3];
        
GetClientAbsOrigin(clientorigin);
        
        
origin[2] += 1.0;
        
        
float velocity[3];
        
GetEntPropVector(clientProp_Data"m_vecVelocity"velocity);
        
        
velocity[0] += GetRandomFloat (-0.250.25);
        
velocity[1] += GetRandomFloat (-0.250.25);
        
velocity[2] += GetRandomFloat (-0.250.25);

        
velocity[0] *= GetRandomFloat(300.0400.0) / 250.0;
        
velocity[1] *= GetRandomFloat(300.0400.0) / 250.0;
        
velocity[2] *= GetRandomFloat(300.0400.0) / 250.0;
        
        
float angularVelocity[3];               
//        GetEntPropVector(gibEntity, Prop_Data, "m_vecAngularVelocity", angularVelocity);
        
        
angularVelocity[0] = GetRandomFloat 100200 );
        
angularVelocity[1] = GetRandomFloat 100300 );
        
//        SetEntPropVector(gibEntity, Prop_Data, "m_vecAngularVelocity", angularVelocity);        
        
SetEntProp(gibEntityProp_Data"m_bloodColor"GetEntProp(clientProp_Data"m_bloodColor"));
        
SetEntProp(gibEntityProp_Data"m_nSolidType"2);
        
SetEntProp(gibEntityProp_Send"m_CollisionGroup"1);
        
        
TeleportEntity(gibEntityoriginNULL_VECTORvelocity);
        
//        InitGib(gibEntity, client, 300.0, 400.0);
    
}
}

any CorpseGib(int clientfloat damageForce[3], float damagePos[3], float reportedPos[3], int inflictorint attacker,
               
int weaponfloat damagefloat maxDamagefloat baseDamageint damageTypeint damageCustomint damageStats,
               
int ammoTypefloat radiusint damagedOtherPlayersint objectsPenetratedint bulletIdint recoilIndex)
{
    return 
SDKCall(hCorpseGibclientdamageForcedamagePosreportedPosinflictorattackerweapondamage,
                               
maxDamagebaseDamagedamageTypedamageCustomdamageStatsammoTyperadius
                               
damagedOtherPlayersobjectsPenetratedbulletIdrecoilIndex);
}

public 
void OnClientPutInServer(int client)
{
    
DHookEntity(hHasHumanGibsfalseclient);
    
DHookEntity(hHasAlienGibsfalseclient);
}

public 
MRESReturn PreHasHumanGibs(int clientHandle hReturn)
{
    
DHookSetReturn(hReturntrue);
    return 
MRES_Supercede;
}

public 
MRESReturn PreHasAlienGibs(int clientHandle hReturn)
{
    
DHookSetReturn(hReturnfalse);
    return 
MRES_Supercede;
}

public 
void OnClientSayCommand_Post(int client, const char[] command, const char[] sArgs)
{
    if( !
IsPlayerAlive(client) )
    {
        return;
    }
    
    
int i 0;
//    int bloodColor = GetRandomInt(0, 5);
//    ChangeBloodColor(client, bloodColor);
//    PrintToChat(client, "Your blood color has been changed to %d", bloodColor);
    
    
if( strcmp(sArgs"corpse"false) == && hCorpseGib )
    {
        
bool gibbed true;
        
        
gibbed CorpseGib(client, {0.00.00.0}, {0.00.00.0}, {0.00.00.0}, 11690.00.00.00000,
                            
0.00000);
        
        
PrintToChat(client"Corpse gibs should be spawned by now! [Gibbed: %s, Gib: Alien]"gibbed "True" "False");
    }
    else if( 
strcmp(sArgs"head"false) == && hSpawnHeadGib )
    {
        for( 
010i++ )
        {
            
SpawnHeadGib(client);
        }
        
        
PrintToChat(client"Head gibs should be spawned by now!");
    }
    else if( 
strcmp(sArgs"random"false) == && hSpawnRandomGibs )
    {
        for( 
05i++ )
        {
            
SpawnRandomGibs(client40);
            
SpawnRandomGibs(client41);
        }
            
        
PrintToChat(client"Random corpse gibs should be spawned by now!");
    }
    else if( 
strcmp(sArgs"random2"false) == && hSpawnRandomGibs )
    {
        for( 
05i++ )
        {
            
SpawnRandomGibs2(client40);
            
SpawnRandomGibs2(client41);
        }    
            
        
PrintToChat(client"Random corpse gibs should be spawned by now!");
    }

Sigs:
PHP Code:
"Games"
{
    
"#default"
    
{
        
"Signatures"
        
{
            
"CorpseGib"
            
{
                
"library"    "server"
                "windows"    "\x53\x56\x51\x68\x2A\x2A\x2A\x2A\x8B\xF1"    
                "linux"        ""
            
}
            
"SpawnRandomGibs"
            
{
                
"library"    "server"
                "windows"    "\x55\x8B\xEC\x83\xEC\x08\x89\x55\xFC"    
                "linux"        ""
            
}
            
"SpawnHeadGib"
            
{
                
"library"    "server"
                "windows"    "\x55\x8B\xEC\x83\xEC\x24\x53\x56\x57\x8B\xD9"    
                "linux"        ""
            
}
            
"InitGib"
            
{
                
"library"    "server"
                "windows"    "\x55\x8B\xEC\x83\xEC\x0C\x56\x8B\xF1\x8B\x86\xD4\x00\x00\x00\xC1\xE8\x0C\xA8\x01\x74\x2A\xE8\x2A\x2A\x2A\x2A\xF3\x0F\x7E\x86\x7C\x01\x00\x00"    
                "linux"        ""
            
}
            
"SpawnGib"
            
{
                
"library"    "server"
                "windows"    "\x55\x8B\xEC\x83\xEC\x08\x53\x56\x57\x6A\x01\x6A\x05"    
                "linux"        ""
            
}
        }
    }


Last edited by TheDS1337; 03-19-2019 at 04:24.
TheDS1337 is offline
Reply


Thread Tools
Display Modes

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 05:03.


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