AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting Help (https://forums.alliedmods.net/forumdisplay.php?f=11)
-   -   Solved [H3LP] Hooking CBasePlayer::StartObserver (https://forums.alliedmods.net/showthread.php?t=316094)

DarthMan 05-07-2019 03:37

[H3LP] Hooking CBasePlayer::StartObserver
 
Hello. I'm having issues hooking CBasePlayer::StartObserver using Okapi. It's my first time using the module, but I'm sure that everything was done correctly. The signature is also correct. In fact, the function is hooked, because, when I join spectator, the server crashes. So it means it hooks the right 1.

Code:
#include <amxmodx> #include <okapi> new const g_hObserverSignature[] = {0x53,0x56,0x8B,"𐌻",0x57,0x33,"𐌻",0x8B,"𐌻","𐌻",0x57,0x83,"𐌻","𐌻",0x50,0x6A}; new const g_szObserverSymbol[] = "_ZN11CBasePlayer13StartObserverE6VectorS0_"; new okapi_hook: g_hSpectatorObs; new okapi_func: g_hObserverSetMode; new g_hSpectatorValue; public plugin_precache() {     if(is_linux_server())         g_hSpectatorValue = okapi_mod_get_symbol_ptr(g_szObserverSymbol);     else         g_hSpectatorValue = okapi_mod_find_sig(g_hObserverSignature, sizeof g_hObserverSignature);         g_hObserverSetMode = okapi_build_function(g_hSpectatorValue, arg_void, arg_cbase, arg_vec, arg_vec);     g_hSpectatorObs = okapi_add_hook(g_hObserverSetMode, "OnSpectatorJoin_Post", .post = true); } public plugin_pause() {     okapi_del_hook(g_hSpectatorObs); } public plugin_unpause() {     g_hSpectatorObs = okapi_add_hook(g_hObserverSetMode, "OnSpectatorJoin_Post", .post = true); } public plugin_end() {     okapi_del_hook(g_hSpectatorObs); } public OnSpectatorJoin_Post(const iID, const Float: fVecPos[], const Float: fVecViewAngle[]) {     server_print("Called"); }

Using Orpheu it would be understandable because it doesn't support vectors as parameters, but, from what I read, Okapi supports them as long as the return function type is not a vector. Looking at the HLSDK to confirm, the function is void, and there are 3 arguments: the player id and 2 vectors to store the position and the view angle. However, if I remember correctly, I read somewhere that the only possible way to hook a function that has Vector and not Vector * or &Vector as a parameter is by using Rage, Okapi and Orpheu being unsupported. Also, I'd like to say that I found this: https://forums.alliedmods.net/showth...t=40164&page=9 . So, the truth lies somewhere else. It means that Okapi is indeed capable of hooking functions that have Vector as parameter. Decompiling the function on Windows TFC I found this: int __thiscall sub_3003E080(_DWORD *this, char a2, int a3, int a4, int a5, int a6, int a7) as opossed to Linux, where it is void __cdecl CBasePlayer::StartObserver(CBasePlayer *const this, Vector *p_vecPosition, Vector *p_vecViewAngle). Thanks !

DarthMan 05-07-2019 05:03

Re: [H3LP] Hooking CBasePlayer::StartObserver
 
Solved by changing okapi_build_function to okapi_build_method :-)

HamletEagle 05-07-2019 08:04

Re: [H3LP] Hooking CBasePlayer::StartObserver
 
okapi_build_function should be used for functions without a class.
okapi_build_method should be used for functions that are member of a class.

orpheu can hook Vector&(IIRC), but not Vector. Okapi can do both. Just take care with okapi, under linux it could crash the server due to some memory bug which wasn't fixed yet.

DarthMan 05-07-2019 09:44

Re: [H3LP] Hooking CBasePlayer::StartObserver
 
Quote:

Originally Posted by HamletEagle (Post 2650747)
okapi_build_function should be used for functions without a class.
okapi_build_method should be used for functions that are member of a class.

orpheu can hook Vector&(IIRC), but not Vector. Okapi can do both. Just take care with okapi, under linux it could crash the server due to some memory bug which wasn't fixed yet.

Ah, I see. Thanks for letting me know.
Also, I noticed a bug with Okapi.
If I do new hObserverValue = wl(okapi_mod_find_sig(hObserverSignature, sizeof hObserverSignature), okapi_mod_get_symbol_ptr(szObserverSymbol)); all works fine, but if I hook the same function in another plug-in, then it gives me an error. [OKAPI] Null address provided
Same thing happens if I register hObserverValue twice in the plug-in using it, I did that just for testing purposes to see if it causes the error. That means that you can only register a hook once, so, like, it can only be registered in 1 plug-in. Registering it in multiple plug-ins will cause that error. I don't know if that's due to a problem on Okapi itself, but, most likely, it's that. I remember Arkshine saying that he stopped working on Rage/Orpheu/Okapi and he probably won't be touching them anytime in the enar future, since he's focused more on AMX Mod X rather than additional modules right now. And also, considering how slowly AMXX is advancing and 1.9 is still not a stable build, could take a year or a few more before 1.8.2 is finally replaced by 1.9 . Not to mention that there's also AMXX v1.10 available now and I've upgraded to it recently.

HamletEagle 05-07-2019 12:59

Re: [H3LP] Hooking CBasePlayer::StartObserver
 
That's not a bug, it is by design(read the okapi topic). You are supposed to build the function in precache and register the hook later(in init for example).

DarthMan 05-07-2019 13:06

Re: [H3LP] Hooking CBasePlayer::StartObserver
 
So, that's why it happens?
Hook must be registered in init/cfg/etc and the function in precache?
So it's like a rule, otherwise will throw the error?
Then how come even registering it in init if i do it twice I get that error ?

I've been told this:

- All hooks registered by the module must be un-hooked
- Sig search
- All hooks must be repatched to their previous status.

DarthMan 05-07-2019 13:50

Re: [H3LP] Hooking CBasePlayer::StartObserver
 
Quote:

Originally Posted by HamletEagle (Post 2650782)
That's not a bug, it is by design(read the okapi topic). You are supposed to build the function in precache and register the hook later(in init for example).

I tested and it still crashes. It's as I said, a bug in the module that will never be fixed.

Edit: I had another plug-in calling it and it wasn't done in plugin_precache. Seems to be working fine now.
Thanks for the help. Much appreciated !

HamletEagle 05-07-2019 14:35

Re: [H3LP] Hooking CBasePlayer::StartObserver
 
From okapi thread:
Quote:

When you use signatures to use functions, after you attach the module to a function, it modifies the bytes of the functions.
That means that if you use the same signature twice, the second will fail. This means that if you use the same signature in two
plugins, it will fail in one. To avoid this you can as an example, just to signature search in plugin_precache and hooking in plugin_init.
It doesn't have to be precache and init. The point is to build the functions at one point and hook later, so the addresses are not modified and all hooks will succeed.


All times are GMT -4. The time now is 15:42.

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