AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Coding MM:S Plugins & SM Extensions (https://forums.alliedmods.net/forumdisplay.php?f=75)
-   -   Like what, manual callclasses! (https://forums.alliedmods.net/showthread.php?t=40005)

PM 05-14-2006 15:07

Like what, manual callclasses!
 
Hello people, it's me again.

Today I've decided to implement manual callclasses.

What you need: In fact, the only thing you need to use the new manual callclasses is the newest sourcehook.h from CVS (the one commited today :) ). You don't need to update sourcemm or anything.

How to use them:

The first thing you need to do is request a manual callclass:

Code:

SourceHook::ManualCallClass *mcc = SH_GET_MCALLCLASS(ptr, size);
Here, ptr is the interface pointer, size is the interface size. Make sure that size is at least sizeof(void*). In fact, almost everyone should use sizeof(void*). I'll say more about size soon.

When you're done with the callclass, release it using SH_RELEASE_CALLCLASS as with normal callclasses.

Assuming that you have declared a manual hook:
Code:

SH_DECL_MANUALHOOK0_void(Some_Hook, vtable index, vtable offset, this ptr offset);
you can now call the original function using:
Code:

SH_MCALL(mcc, Some_Hook)();
You may also want to call a function without having a hook declaration. This is also possible. You first need a MFP that corresponds to that function. The class doesn't matter. I always use SourceHook::EmptyClass, but you can use whatever you want. Let's say your function returns an int and takes 2 parameters, const char * and bool:
Code:

typedef int (SourceHook::EmptyClass::*MFP_MyFunc)(const char *, bool);
Now you can call the function using:
Code:

int ret = SH_MCALL2(mcc, MFP_MyFunc(), vtable index, vtable offset, this pointer offset)("hello", true);
Yes, I know that 99% (probably 100%) of all users will use 0 for vtable offset and this pointer offset. I still included them because someone may find it useful one day. Writing two zeros isn't that much of a problem either.

So, what about the size thing passed to SH_GET_MCALLCLASS ? Well, it should be larger than the maximal sum of vtable offset and this ptr offset you use on that callclass. Whatever, you most likely just need to use sizeof(void*), so that the callclass includes the first machine word (which is usually the vtable pointer) of the object.

Have fun, report problems, if everything works, please say that it works for you.

If you feel like it, you can add info about its usage to the wiki, otherwise I'll do it once I find my password.

Thanks,
your PM.

BAILOPAN 05-14-2006 15:11

Nicely done, PM :) this is very cool!

As mentioned on IRC, you can very well use this to call virtual functions you don't even bother hooking, if you just want the call ability.

PM 05-14-2006 15:30

Quote:

Originally Posted by BAILOPAN
As mentioned on IRC, you can very well use this to call virtual functions you don't even bother hooking, if you just want the call ability.

Yes, also note that using this, you always call the original function, even if some other plugin has hooked it. Of course this comes with a certian (should not be very large) runtime cost though.

TommyV 05-15-2006 01:34

Very nice PM, that's a useful addition to sourcehook.

I'll try switching some of my non-hooked vfunc calls to this method and let you know how I get on.

c0ldfyr3 05-15-2006 06:16

LoL @ // The pope is dead. -> :(

c0ldfyr3 05-15-2006 07:34

The fixes for SH_CALL worked like a charm, thanks =)

TommyV 05-15-2006 11:01

Worked flawlessly for me too, calling a couple of CBaseCombatCharacter functions via offsets, and if I can ues it then anyone can :)

c0ldfyr3 05-17-2006 08:00

Ok this isn't working for the call classes...

Code:

SourceHook::ManualCallClass *mcc = SH_GET_MCALLCLASS( g_Players[iPlayer].pPlayer, sizeof(void*));
SH_MCALL( mcc, Teleport_Hook)( &vecLocation, &qAngles, &vecVelocity );
SH_RELEASE_CALLCLASS( mcc );


c0ldfyr3 05-17-2006 08:13

Neither is this...
Code:

typedef void (SourceHook::EmptyClass::*MFP_Teleport)( const Vector *, const QAngle *, const Vector * );
SourceHook::ManualCallClass *mcc = SH_GET_MCALLCLASS( g_Players[iPlayer].pPlayer, sizeof(void*) );
SH_MCALL2( mcc, MFP_Teleport(), CBASEANIMATING_TELEPORT, 0, 0)( &vecLocation, &qAngles, &vecVelocity );
SH_RELEASE_CALLCLASS( mcc );

And i'm not sure if I should credit this error location :\
Quote:

> baadf00d()
zombie_mm.dll!SourceHook::MExecutableClass3<v oid,Vector const *,QAngle const *,Vector const *>::operator()(const Vector * p1=0x0012e18c, const QAngle * p2=0x0012e198, const Vector * p3=0x0012e180) Line 3452 C++
zombie_mm.dll!ZombiePlugin::Slap(int iPlayer=1148846080) Line 2682 C++
Always on the same line..
Code:

sourcehook.h:3452
RetType operator()(Param1 p1, Param2 p2, Param3 p3) const
                        SH_MAKE_MEXECUTABLECLASS_OB((p1, p2, p3), (Param1, Param2, Param3))


PM 05-17-2006 08:58

The topmost stack frame's address is 0xbaadf00d, so SH_MCALL actually jumped to that address).

I've seen that you do:
Code:

SH_MCALL( mcc, Teleport_Hook)( &vecLocation, &qAngles, &vecVelocity );
That's why I'd like to ask: Is that Teleport_Hook hook in use? If yes, does it actually work?


All times are GMT -4. The time now is 07:19.

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