AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Coding MM:S Plugins & SM Extensions (https://forums.alliedmods.net/forumdisplay.php?f=75)
-   -   Solved Call a function by the pointer from FunctionTable (https://forums.alliedmods.net/showthread.php?t=322445)

kadet.89 03-27-2020 10:47

Call a function by the pointer from FunctionTable
 
I have these functions from datamaps:

DEFINE_THINKFUNC( Detonate )

Code:

CBaseCSGrenadeProjectile - hegrenade_projectile
- InitializeSpawnFromWorld (Offset 0) (Input)(0 Bytes) - InitializeSpawnFromWorld
- CBaseCSGrenadeProjectileDangerSoundThink (Offset 0) (FunctionTable)(0 Bytes)
- m_hThrower (Offset 1292) (Save)(4 Bytes)
- m_bIsLive (Offset 1265) (Save)(1 Bytes)
- m_DmgRadius (Offset 1268) (Save)(4 Bytes)
- CBaseGrenadeSmoke (Offset 0) (FunctionTable)(0 Bytes)
- CBaseGrenadeExplodeTouch (Offset 0) (FunctionTable)(0 Bytes)
- CBaseGrenadeDetonateUse (Offset 0) (FunctionTable)(0 Bytes)
- CBaseGrenadePreDetonate (Offset 0) (FunctionTable)(0 Bytes)
- CBaseGrenadeDetonate (Offset 0) (FunctionTable)(0 Bytes)

I get a void* from CBaseGrenadeDetonate (and it's not nullptr), is there a way to call the function using the pointer?
PHP Code:

DEFINE_THINKFUNCDetonate ),
virtual void Detonatevoid ); 

I tried to do it like this, but it crashes the server:
PHP Code:

typedef void (*Detonate_pointer)();

voidpointer = ...

((
Detonate_pointer)pointer ())(); 

PHP Code:

voidpointer = ...
CBaseEntityptr = ...
reinterpret_castvoid(*)(CBaseEntity*) > (pointer ) (ptr ); 


UPD:
I got inputfunc_t field value from typedescription_t of the "CBaseGrenadeDetonate", I gues that should be the correct funcion pointer, but have no idea ho I can call it

kadet.89 03-27-2020 18:37

Re: Call a function by the pointer from FunctionTable
 
Here is my solution:

PHP Code:

#define EXTRACT_VOID_FUNCTIONPTR(x)        (*(void **)(&(x)))

void *UTIL_FunctionFromNamedatamap_t *pMap, const char *pName )
{
    while ( 
pMap )
    {
        for ( 
int i 0pMap->dataNumFieldsi++ )
        {
            
Assertsizeof(pMap->dataDesc[i].inputFunc) == sizeof(void *) );

            if ( 
pMap->dataDesc[i].flags FTYPEDESC_FUNCTIONTABLE )
            {
                if ( 
FStrEqpNamepMap->dataDesc[i].fieldName ) )
                {
                    return 
EXTRACT_VOID_FUNCTIONPTR(pMap->dataDesc[i].inputFunc);
                }
            }
        }
        
pMap pMap->baseMap;
    }

    
Msg"Failed to find function %s\n"pName );

    return 
NULL;
}

typedef void (CBaseEntity::*VALVE_BASEPTR)(void);
typedef void (CBaseEntity::*VALVE_ENTITYFUNCPTR)(CBaseEntity *pOther);

VALVE_BASEPTR CBaseGrenade::func_Detonate nullptr;
VALVE_ENTITYFUNCPTR CBaseGrenade::func_ExplodeTouch nullptr;

void CBaseGrenade::detonate()
{
    if(
func_Detonate != nullptr)
        return;

    
void *ptr UTIL_FunctionFromNameGetDataDescMap_Real(), "CBaseGrenadeDetonate");
    if(!
ptr)
        return;

    
memcpy(&func_Detonate, &ptrsizeof(void *));
    (
getBaseEntity()->*func_Detonate)(); //getBaseEntity() returns CBaseEntity*


For GetDataDescMap_Real use standard offset from core.games "GetDataDescMap"
It seams to be the only way to detonate grenades without delays and dealing with signatures.


All times are GMT -4. The time now is 03:50.

Powered by vBulletin®
Copyright ©2000 - 2021, vBulletin Solutions, Inc.