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

Planned SourceHook changes


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
PM
hello, i am pm
Join Date: Jan 2004
Location: Canalization
Old 05-10-2007 , 13:21   Planned SourceHook changes
Reply With Quote #1

Hello!

We are planning some SourceHook changes for SourceMM 1.5.

First of all, all hooks now have an id. Consequently, the SH_ADD_HOOK macros return a non-zero integral hook id. A return value of 0 means failure.
This change of the return value (int->bool) may lead to warnings on some platforms if you are saving the return value in a bool variable.

Secondly, the macros have changed:
Now we have:
  • SH_ADD_HOOK(class name, function name, instance pointer, handler, post or not?)
  • SH_ADD_VPHOOK(class name, function name, representative instance pointer, handler, post or not?)
  • SH_ADD_DVPHOOK(class name, function name, vtable pointer, handler, post or not?)
  • SH_ADD_MANUALHOOK(manual hook name, instance pointer, handler, post or not?)
  • SH_ADD_MANUALVPHOOK(manual hook name, representative instance pointer, handler, post or not?)
  • SH_ADD_MANUALDVPHOOK(manual hook name, vtable pointer, handler, post or not?)

handler can be either SH_STATIC(non-member function / static member function) or SH_MEMBER(instance, &Class::Function)

Of course, the old macros with _STATICFUNC / _MEMFUNC will continue working. I just wanted to get rid of that because otherwise we'd have 16 ADD_HOOK_ macros now. I like the new way much more.

There is also SH_REMOVE_HOOK_ID which removes a hook by id. This means that you can store the return value of the SH_ADD_*HOOK macro and then pass this to SH_REMOVE_HOOK_ID. The old SH_REMOVE_HOOK macros continue working as well - however, SH_REMOVE_HOOK_ID is the only way to remove VP hooks and manual VP hooks.

Also note that now it is safe to remove hooks even on instances which have been already deleted.

VP hooks behave like normal hooks - except for the fact that they are not bound to a specific instance of the class but are called everytime the Virtual function Pointer (that's why they are called VP) gets executed. The "representative instance pointer" is a pointer to an instance of the class on whose vtable you want to install the hook. I think it's easiest to see this on a code example:

Code:
class Base
{
public:
  virtual void Function() = 0;
};

class Derived1 : public Base
{
public:
  void Function()
  {
    // Function 1
  }
};

class Derived2 : public Base
{
public:
  void Function()
  {
    // Function 2
  }
};

void HookFunctionNormal()
{
   printf("Normal hook Called!\n");
}

void HookFunctionVP()
{
   printf("VP hook Called!\n");
}

void Test()
{
  // Both Derived1 and Derived2 implement Function()

  Derived1 d1_instance1;
  Derived1 d1_instance2;
  Derived2 d2_instance1;

  Base *pd1_instance1 = &d1_instance1;
  Base *pd1_instance2 = &d1_instance2;
  Base *pd2_instance1 = &d2_instance1;

  // Now add a normal hook on d1_instance1
  int hook1 = SH_ADD_HOOK(Base, Function, pd1_instance1, SH_STATIC(HookFunctionNormal), false);

  // And add a VP hook.
  int hook2 = SH_ADD_VPHOOK(Base, Function, pd1_instance1, SH_STATIC(HookFunctionVP), false);

  // Try to call some functions.
  pd1_instance1->Function();  // Prints "VP hook Called", then "Normal hook called"

  pd1_instance2->Function();  // Only prints "VP hook Called"

  pd2_instance1->Function();  // Doesn't print anything.

  SH_REMOVE_HOOK_ID(hook1);
  SH_REMOVE_HOOK_ID(hook2);

  pd1_instance1->Function();  // Prints nothing
  pd1_instance2->Function();  // Prints nothing
  pd2_instance1->Function();  // Prints nothing
}
(no, I haven't even compiled this, but it should work)

So, you see, normal hooks are only executed on one specific instance; VP hooks are executed on all instances of a class (attention; if you have a magic pointer from somewhere, and this pointer is in fact a DERIVED class of what you think it is, it has its own vtable and thus VP hooks on what you think it is aren't called on it!).

Alternatively, you can use "direct vp hooks" (SH_ADD_DVPHOOK or SH_ADD_MANUALDVPHOOK): here, you give sourcemod a pointer to the vtable instead of a representative instance pointer. This lets you compute the vtable address using an offset without having a real instance. Note that SH expects a pointer to the beginning of the vtable - it then still adds vtable index * sizeof(void*) to it.

It's also pretty important to note that vp hooks are called in the order they were installed (which is not necessarily the order of their hook ids - ids get reused), but ALWAYS before SH starts calling normal hooks. This is also the reason why the above example first prints "VP hook called" even though the VP hook was the second declared hook.

There's also one very important change: The concept of SH_CALL and callclasses was bound to interfaces. This means that it did not work anymore for VP hooks.
As of today, CallClasses are NOT used anymore. SH_CALL's first parameter is now the this pointer. You do NOT need to request and release a call class amymore. I've done some template and macro magic in order to make the new system source compatible (so the old code with SH_GET_CALLCLASS etc. will compile, but it is completely unnecessary and I'd encourage you to convert the code to the new method). Also, the ISourceHook interface continues to provide support for CallClasses so that old plugins should still work (however, if a new plugin uses a VP hook, old plugins might cause the hook to be called even if using SH_CALL).

In order to use this, you will need the newest sourcehook.h from SVN. Plugins compiled with this file need a new version of sourcemm, which you can get in my testing post in this forum. Before we release this, we need to be sure that it's backwards compatible with older plugins.

So, have fun with it
__________________
hello, i am pm

Last edited by PM; 05-12-2007 at 05:19.
PM is offline
L. Duke
Veteran Member
Join Date: Apr 2005
Location: Walla Walla
Old 05-10-2007 , 18:15   Re: Planned SourceHook changes
Reply With Quote #2

nice!

This will make hooking player functions much easier!

I assume each weapon "type" will have to be hooked separately though (USP, AWP, etc.)?
L. Duke is offline
BAILOPAN
Join Date: Jan 2004
Old 05-11-2007 , 09:06   Re: Planned SourceHook changes
Reply With Quote #3

Yes, because each one has a different vtable.
__________________
egg
BAILOPAN is offline
PM
hello, i am pm
Join Date: Jan 2004
Location: Canalization
Old 05-12-2007 , 05:29   Re: Planned SourceHook changes
Reply With Quote #4

Edited the above post. Re-read please, look for "direct VP hooks" and "new SH_CALL".

Note that I'll have to wait for bail to come back so that he can run the build scripts before there will be a new test binary which supports the new SH_CALL and direct VP hooks in the other post.
__________________
hello, i am pm
PM is offline
c0ldfyr3
AlliedModders Donor
Join Date: Aug 2005
Location: Ireland
Old 05-13-2007 , 10:17   Re: Planned SourceHook changes
Reply With Quote #5

Can someone let me know when they've successfully implemented this? This looks really neat as in a few of my plugins I hook a function for all clients and this would make it a lot easier than hooking and unhooking each client as they connect.

I have one question though, if my understanding is correct, if i hook a CBE function it will be hooked on all clients that connect without any interaction from me after the initial hook? Secondly, as Duke asked about hooking each weapon separately, if I hook one instance of CBaseCombatKnife (not sure that's correct but u know what I'm talking about), will it hook all instances of the knife that will be created during the game without further interaction?

Thanks!
__________________

Last edited by c0ldfyr3; 05-13-2007 at 10:38.
c0ldfyr3 is offline
Send a message via MSN to c0ldfyr3 Send a message via Yahoo to c0ldfyr3
BAILOPAN
Join Date: Jan 2004
Old 05-13-2007 , 11:12   Re: Planned SourceHook changes
Reply With Quote #6

It has all been implemented as of revision 396 in the sourcemm nightly builds.
__________________
egg
BAILOPAN is offline
L. Duke
Veteran Member
Join Date: Apr 2005
Location: Walla Walla
Old 05-13-2007 , 11:17   Re: Planned SourceHook changes
Reply With Quote #7

That's my understanding. The "CBE function" on the player would be on CCSPlayer and catch all clients, and "CBaseCombatKnife" would work on all of the knives.

I haven't had time to test this yet, but I hope to soon as I hook every player and weapon in a couple of my plugins.
L. Duke is offline
c0ldfyr3
AlliedModders Donor
Join Date: Aug 2005
Location: Ireland
Old 05-14-2007 , 05:50   Re: Planned SourceHook changes
Reply With Quote #8

Ok excellent, Duke can you let me know when you've successfully tested it? I know you use pretty much the same methods as I do in ZM so if it works for you it'll work for me ;)
__________________

Last edited by c0ldfyr3; 05-14-2007 at 05:54.
c0ldfyr3 is offline
Send a message via MSN to c0ldfyr3 Send a message via Yahoo to c0ldfyr3
PM
hello, i am pm
Join Date: Jan 2004
Location: Canalization
Old 05-14-2007 , 13:46   Re: Planned SourceHook changes
Reply With Quote #9

Quote:
Originally Posted by L. Duke View Post
That's my understanding. The "CBE function" on the player would be on CCSPlayer and catch all clients, and "CBaseCombatKnife" would work on all of the knives.

I haven't had time to test this yet, but I hope to soon as I hook every player and weapon in a couple of my plugins.
Are the classes derived from CBaseCombatKnife? (that's what the "Base" thing suggests)

If yes, you might have to hook each derived class' vtable separately.
The easiest way to find out is to try it out
__________________
hello, i am pm
PM is offline
mooman2
Member
Join Date: Apr 2007
Old 05-30-2007 , 01:24   Re: Planned SourceHook changes
Reply With Quote #10

PM: How do you configure which vfunc index you want to hook when using SH_ADD_MANUALDVPHOOK? I tried using MANUALHOOK_RECONFIGURE but that gave me random crashes. I passed into that stuff a pointer to the vtable obtained from dlsym() and the vfunc index. Or am I just getting all of this wrong?

edit: BTW, you need to add testvphooks.cpp to the test suite vcproj :p

Last edited by mooman2; 05-30-2007 at 01:43.
mooman2 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 11:32.


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