Hooking callbacks
#1

Hi there.

I've been looking at the tutorials for hooking callbacks. This is because I'm seperating my script out into includes, so obviously need to use the samp callbacks multiple times. I'm reading through these tutorials and I think I'm understanding certain parts, but when it comes to looking at the code, I'm baffled. It doesn't make sense to me, and doesn't appear to be explained very well. It may be to other people, but not to myself.

Can anyone give me the following example, as I think it will help me massively! Say I was going to hook OnPlayerConnect for my include file. Can someone explain step by step what I'd need to do, and explain the code line by line? I realise this may be a big ask, but if anyone is willing to, I'd appreciate it massively.

I've literally been looking up on this for hours and just can't get my head around it.

Many thanks
Reply
#2

#include "../include/callbacks.pwn" - like this you mean?
Reply
#3

or #include "../include/includes.pwn"
Reply
#4

I just need someone to explain to me clearly and simply enough, so that I can create a hook for OnPlayerConnect, for example. So I can then use OnPlayerConnect in perhaps "includes/vehicle.pwn" and also "includes/house.pwn".

I dont know if that makes sense
Reply
#5

http://forum.sa-mp.com/showthread.ph...Critical+Stunt
this gamemode is builded on includes
Reply
#6

If you are only going to be using the includes within your gamemode, you could also directly call the function to the include, ex:
pawn Код:
public OnPlayerConnect(playerid)
{
        houses_OnPlayerConnect(playerid);
        return 1;
}

// houses include
houses_OnPlayerConnect(playerid)
{
      // do something
      return 1;
}
If you'd rather use hooking, refer to this. It should explain what the code is doing and how to use it.
Reply
#7

Hi,

I shall explain what I have so far, and maybe someone can help me with my error now.

I have an include file called OnPlayerConnect.pwn:
Код:
public OnPlayerConnect(playerid){
	//To create a callback, we use CallLocalFunction. For more explanation about CallLocalFunction, go to wiki.sa-mp.com/wiki/CallLocalFunction
	CallLocalFunction("L_OnPlayerConnect", "i", playerid);
	return 1;
}

#if defined _ALS_OnPlayerConnect //If _ALS_OnPlayerConnect is defined:
  #undef OnPlayerConnect //If defined, it will undefine OnPlayerConnect.
#else //Else if not:
#define _ALS_OnPlayerConnect //If not, we'll define _ALS_OnPlayerConnect.
#endif //As we started a PAWN function '#if', it's necessary to use #endif or you'll get troubled.

//As the callback 'OnPlayerConnect' is undefined now, we can define it to whatever but here we are hooking it. So define it to our callback created, 'L_OnPlayerSConnect'.
#define OnPlayerConnect L_OnPlayerConnect

//Even though we hooked it, we must forward the callback too inorder to get it used.

forward L_OnPlayerSpawn(playerid, weaponid); //We must forward the callback which created itself.
And I also have a user.pwn, which is an include for stuff related to a user. In here I call OnPlayerConnect:
Код:
forward OnPlayerConnect(playerid);
public OnPlayerConnect(playerid){
	//On connect, check if username exists in database
    TogglePlayerSpectating(playerid, true);
    new query[128], playername[MAX_PLAYER_NAME];
    GetPlayerName(playerid, playername, sizeof(playername));
    mysql_format(mysql, query, sizeof(query), "SELECT `id`, `username`, `password` FROM `user` WHERE `username` = '%e' LIMIT 1;", playername);
    mysql_tquery(mysql, query, "OnUserCheck", "i", playerid);
	return 1;
}
I have then included both of these files into my main gamemode. If however, I try to use OnPlayerConnect callback in a different include or in my main gamemode, I get the following error:
Код:
error 021: symbol already defined: "L_OnPlayerConnect"
So yeah, clearly Im doing something wrong. Any ideas? DOnt know if any of what I said makes sense to anyone. I wont lie, I'm brand new to hooking
Reply
#8

I'd say it has to do with
Код:
forward OnPlayerConnect(playerid);
This is defined in the a_samp include.


Pure guess though, I subscribed to the thread as soon as you asked the question to actually have a go at hooks.
Reply
#9

IIRC each time you hook a callback you MUST use a unique prefix for the callback header.

I'm thinking you have hooked OnPlayerConnect more than once but defined 'L_OnPlayerConnect' each time. Change the 'L_' to something meaningful. For example, in your user.pwn change it to 'user_OnPlayerConnect'.

Also remember, it's better to use small prefixes because you will exceed the callback header length limit (on callbacks like 'OnPlayerDialogResponse') with larger prefixes.
Reply
#10

Quote:
Originally Posted by iggy1
Посмотреть сообщение
IIRC each time you hook a callback you MUST use a unique prefix for the callback header.

I'm thinking you have hooked OnPlayerConnect more than once but defined 'L_OnPlayerConnect' each time. Change the 'L_' to something meaningful. For example, in your user.pwn change it to 'user_OnPlayerConnect'.

Also remember, it's better to use small prefixes because you will exceed the callback header length limit (on callbacks like 'OnPlayerDialogResponse') with larger prefixes.
This unfortunately didn't work. By changing OnPlayerConnect to user_OnPlayerConnect in my user.pwn include, it was just recognised as an entire new public function called user_OnPlayerConnect

Quote:
Originally Posted by DRIFT_HUNTER
Посмотреть сообщение
I would suggest you using y_hooks.inc from YSI Framework.
You would need to include that file on top of every file that needs hooks and instead of public just use hook keyword for functions that have to be hooked.

Keep in mind that YSI 3 only allows samp functions hooks, while YSI 4 also allows hooking custom public functions.

https://github.com/Misiur/YSI-Includes/
That is the official repository for YSI 4 since ****** is no longer maintaining it. If you dont use git and instead just download zip dont forget to get that AMX folder from zeex (just click on it while on github, it will redirect you to where you need)
I tried to implement the y_hooks.inc file from the YSI framework and got the following error:

Код:
cannot read from file: "..\YSI_Internal\y_compilerpass"
I realise I'm not installing it right, but could you explain to me a little easier how I get it working with my script?

Thanks
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)