[Tutorial] How to hook Functions and Callbacks.
#1

How to hook Functions & Callbacks
Introduction
Well here I'm with my 3rd tutorial regarding hooking functions & callbacks. Yet this is even possible easily using y_hooks created by ****** but I thought of posting a tutorial regarding manual hooking method for users who like to know how to hook through manual way. There are other methods too for hooking callbacks/functions, but here I'm with what I know.

Hooking
Hooking means to add something on a particular thing. Here, we refer it to adding something too on a callback or function. For example, function 'SetPlayerScore' sets the player's score. But if we are using a server sided score system, the 'SetPlayerScore' won't set it. So, we've gotta set that server sided score too by setting variables.

Here's an example
pawn Код:
public OnPlayerSpawn(playerid)
{
 SetPlayerScore(playerid, 50);
 return 1;
}
Here, it sets the score only, not our server sided score. So, if we want to set our server sided score, we've gotta set the variable for it too.

pawn Код:
enum g_PLAYER_DATA
{
  L_KILLS,
  L_DEATHS,
  L_SCORE,
  L_MONEY,
  L_HEALTH,
  L_ADMIN,
  L_CLAN,
  L_VIP
}
new L_PLAYER_INFO[MAX_PLAYERS][g_PLAYER_DATA];

//Example enum ^^

public OnPlayerSpawn(playerid)
{
  SetPlayerScore(playerid, 50);
  L_PLAYER_INFO[playerid][L_SCORE] = 50; //We've set our server sided score too.
  return 1;
}
This is the method we use when we don't hook. But, through hooking it allows it to be in one function and makes. Also, hooking callbacks allows to use it multiple times too and prevents errors and warns. So, lets get into the tutorial of hooking callbacks and functions.

Tutorial


Hooking Functions

Let's take an example that like the above. We'll hook 'SetPlayerScore' function. Inorder to hook, we can create a simple function as we create in our scripts using 'stock.'

Example stocks(functions)
pawn Код:
stock GetName(playerid)
{
  new Lname[MAX_PLAYER_NAME];
  GetPlayerName(playerid, Lname, sizeof(Lname));
  return Lname;
}
//Now this is a function which gets player's name in one single line.

//Using it.
public OnPlayerDeath(playerid, killerid, reason)
{
  new str[128];
  format(str, sizeof(str), "%s killed %s", GetName(killerid), GetName(playerid)); //Gets the name of killer and the dead person.
  SendClientMessageToAll(0xFF0000FF, str);
  return 1;
}
This is how a simple function is created. As this tutorial is based on hooking functions and callbacks, I won't be explaining other stuffs, I'll be explaining more about the related stuffs of this tutorial only.

Now, let's hook our 'SetPlayerScore' function. To hook, first we must create a simple function of the server sided score. We can use 'stock' to create the function.

pawn Код:
stock SetPlayerScoreEx(playerid, amount) //Two parameters: playerid, for the player and amount, the amount to set.
{ //Opening brackets to execute the functions below.
//We'll choose our made enum above and set it.
   L_PLAYER_INFO[playerid][L_SCORE] = amount; //It sets the server sided score to amount. Amount will be specified on the function by user itself.
   SetPlayerScore(playerid, amount); //We'll later undefine 'SetPlayerScore' function and hook it with our current stock. So it's necessary to use this function too or it doesn't make any sense it saying 'hooking SetPlayerScpre.'
   return 1; //Returning the function.
} //Closing brackets.
Now, we have created our function and this can be used as:
'SetPlayerScoreEx(playerid, amount);'
Example:
pawn Код:
public OnPlayerSpawn(playerid)
{
  SetPlayerScoreEx(playerid, 50); //Sets to 50 server sided score and also the original score.
  return 1;
}
As we've created the functions required, lets start hooking. To hook, we can use simple defines and _ALS_ functions as it's said on Samp info(Some where, I don't remember it though. :P)

pawn Код:
stock SetPlayerScoreEx(playerid, amount);
{
  L_PLAYER_INFO[playerid][L_SCORE] = amount;
  SetPlayerScore(playerid, amount);
  return 1;
}

/*Our function created.^^
For hooking, we'll detect it with _ALS_(function name) and if it isn't defined, we'll define it and then undefine the original function. We'll define the same undefined function then with our created function.
pawn Код:
stock SetPlayerScoreEx(playerid, amount);
{
  L_PLAYER_INFO[playerid][L_SCORE] = amount;
  SetPlayerScore(playerid, amount); //We must do this too because we're gonna undefine the SetPlayerScore function later and hook it with our.
  return 1;
}

/*Our function created.^^
Hooking:*/


#if defined _ALS_SetPlayerScore //If _ALS_SetPlayerScore is defined. Then:
  #undef SetPlayerScore //If yes, it will undefine SetPlayerScore function.
#else //Else if not defined
#define _ALS_SetPlayerScore //If not defined, it will define _ALS_SetPlayerScore.
#endif //As we started a PAWN function with '#if', it's necessary to use #endif or you'll get trouble with errors.

/*SetPlayerScore is now undefined, we can define it to whatever we need :P. Even this:
#define SetPlayerScore 0xFF0000
But here, we must hook it, so we must define it to our function which we have created.*/

#define SetPlayerScore SetPlayerScoreEx //As we have undefined SetPlayerScore, inorder to hook it, we must define it to the stock function which we created.
We have successfully hooked a function and can use it!

Example:
pawn Код:
public OnPlayerSpawn(playerid)
{
  SetPlayerScore(playerid, amount);
  //This do sets the original score as well as the server sided score to 50.
  return 1;
}
We have done with hooking functions.

Hooking Callbacks

This is also almost same as hooking callbacks, though it needs some more stuffs to do too. Lets hook OnPlayerSpawn.

To hook on callbacks, we don't need to create a stock/function for it. While hooking OnPlayerSpawn or any original SAMP callback, we must hook and create a callback inside the callback which needs to get hooked.

pawn Код:
public OnPlayerSpawn(playerid)
{
 //This callback is called when a player spawns.
  return 1;
}
Now, lets hook it. For example, we need to add one more parameter too. Here, lets choose a weaponid parameter which must be like this:
'public OnPlayerSpawn(playerid, weaponid)'

First, we must create another callback to hook with, like how we created a function to hook.

pawn Код:
public OnPlayerSpawn(playerid)
{
  //As we want to get the weaponid as a parameter on spawn callback, let's create a variable to get it.
  new weaponid; //Created a variable to get player's weapon.
  weaponid = GetPlayerWeapon(playerid);
   //To create a callback, we use CallLocalFunction. For more explanation about CallLocalFunction, go to wiki.sa-mp.com/wiki/CallLocalFunction
   CallLocalFunction("L_OnPlayerSpawn", "id", playerid, weaponid);
  /*"id" are the formats used. 'i' and 'd' stands for the playerid and weaponid as those are integers/number. 'i' and 'd' both, stands same though.
It's done with creating a callback.*/

   return 1; //Returning the callback.
} //Closing brackets.
Just like we hooked a function using defines, we could hook the callback too.
pawn Код:
public OnPlayerSpawn(playerid)
{
  new weaponid;
  weaponid = GetPlayerWeapon(playerid);
  CallLocalFunction("L_OnPlayerSpawn", "id", playerid, weaponid);
}

/*This was those callback and calls for the original callback we done. Now lets hook it.
Same like functions, we do use _ALS_ defining here.
In here, it's used that if _ALS_(callback name) is defined, we will undefine the callback and if it isn't defined, we'll define the _ALS_(callback name).
And then hook the callback.
*/


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

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

//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.
We can now use it as 'public OnPlayerSpawn(playerid, weaponid);'

pawn Код:
public OnPlayerSpawn(playerid, weaponid);
{
  new str[128];
  SetPlayerScore(playerid, amount); //Sets the server sided score too as we have hooked.
   format(str, sizeof(str), "You are using %d weaponid.", weaponid);
   SendClientMessage(playerid, 0xFF0000, str);
   return 1;
}
We have done with learning how to hook functions and callbacks in a manual way.If you didn't understand any part of the tutorial, you can post it here and I'll explain more better.

Examples

Some examples:
pawn Код:
public OnFilterScriptInit()
{
  SetTimer("Loopplayers", 1000, true);
  CallLocalFunction("L_OnFilterScriptInit", "");
   return 1;
}

forward Loopplayers();
public Loopplayers()
{
  for(new i = 0; i< MAX_PLAYERS; i++)
  {
    if(IsPlayerConnected(i))
    {
      if(GetPlayerHealth(i) >= 101)
      {
        SetPlayerHealth(i, 100);
      }
    }
  }
  return 1;
}

#if defined _ALS_OnFilterScriptInit
  #undef OnFilterScriptInit
#else
#define _ALS_OnFilterScriptInit
#endif

#define OnFilterScriptInit L_OnFilterScriptInit

forward L_OnFilterScriptInit();
Example 2
pawn Код:
new lhp[MAX_PLAYERS];
stock SetPlayerHp(playerid, amount)
{
  lhp[playerid] = amount;
  SetPlayerHealth(playerid, amount);
   return 1;
}


#if defined _ALS_SetPlayerHealth
  #undef SetPlayerHealth
#else
#define _ALS_SetPlayerHealth
#endif
#define SetPlayerHealth SetPlayerHp

public OnFilterScriptInit()
{
  SetTimer("Detecthp", 1000, true);
  CallLocalFunction("L_OnFilterScriptInit", "");
   return 1;
}
forward Detecthp();
public Detecthp()
{
  for(new i = 0; i< MAX_PLAYERS; i++)
  {
    if(GetPlayerHealth(i) > lhp[i])
    {
      new str[128];
      new LName[MAX_PLAYER_NAME];
      GetPlayerName(playerid, Lname, sizeof(Lname));
      format(str, sizeof(str), "%s has been banned from the server. (Reason:Health hack)", Lname);
      Ban(playerid);
     }
  }
  return 1;
}

#if defined _ALS_OnFilterScriptInit
  #undef OnFilterScriptInit
#else
#define _ALS_OnFilterScriptInit
#endif
#define OnFilterScriptInit L_OnFilterScriptInit

forward L_OnFilterScriptInit();
Note: Don't use the example as Anti-Cheat, it's not efficient. It's just an example.

Doubts, questions or anything related to this tutorial can be posted here.


-Lordz™.
Reply
#2

For hooking functions, you can just do:

pawn Код:
#define <native> <hooked function>
In this case:

pawn Код:
#define SetPlayerScore SetPlayerScoreEx
Reply
#3

Quote:
Originally Posted by Emmet_
Посмотреть сообщение
For hooking functions, you can just do:

pawn Код:
#define <native> <hooked function>
In this case:

pawn Код:
#define SetPlayerScore SetPlayerScoreEx
As I've mentioned on the introduction that I'm creating in a method I know. So I wrote it as I knew. Thanks for that new idea Emmet_, I'll check it soon when I get a PC.
Reply
#4

Emmet, you shoud still use the "_ALS_" defines though because the same rule applies to functions, too, not just callbacks.
Reply
#5

Quote:
Originally Posted by YJIET
Посмотреть сообщение
Emmet, you shoud still use the "_ALS_" defines though because the same rule applies to functions, too, not just callbacks.
Well yes, I think you're right because how come we just define it simply without undefining the original function?
Reply
#6

good one! keep it up!
Reply
#7

Quote:
Originally Posted by Emmet_
Посмотреть сообщение
For hooking functions, you can just do:

pawn Код:
#define <native> <hooked function>
In this case:

pawn Код:
#define SetPlayerScore SetPlayerScoreEx
Funny, I can't find that to be working, though, I haven't tried it out. The pre-processor also agrees with me on this one. Here is a little test I did:

Original code:
pawn Код:
#include <a_samp>

#define SetPlayerScore SetPlayerScoreEx

new playerScore[MAX_PLAYERS];

public OnPlayerConnect(playerid)
{
    SetPlayerScore(playerid, 1);
    return 1;
}

SetPlayerScoreEx(playerid, value)
{
    playerScore[playerid] = value;
    SetPlayerScore(playerid, value);
    return 1;
}
Pre-processed code:
pawn Код:
#include <a_samp>

#define SetPlayerScore SetPlayerScoreEx

new playerScore[(500)];

public OnPlayerConnect(playerid)
{
    SetPlayerScoreEx(playerid, 1);
    return 1;
}

SetPlayerScoreEx(playerid, value)
{
    playerScore[playerid] = value;
    SetPlayerScoreEx(playerid, value);
    return 1;
}
I mean SetPlayerScore under the SetPlayerScoreEx function was also defined to SetPlayerScoreEx, won't that create a loop without a loop?

Source: http://slice-vps.nl/ppg/

Quote:
Originally Posted by Lordz™
Посмотреть сообщение
pawn Код:
stock SetPlayerScoreEx(playerid, amount) //Two parameters: playerid, for the player and amount, the amount to set.
{ //Opening brackets to execute the functions below.
//We'll choose our made enum above and set it.
   L_PLAYER_INFO[playerid][L_SCORE] = amount; //It sets the server sided score to amount. Amount will be specified on the function by user itself.
   SetPlayerPos(playerid, amount); //We'll later undefine 'SetPlayerPos' function and hook it with our current stock. So it's necessary to use this function too or it doesn't make any sense it saying 'hooking SetPlayerPos.'
   return 1; //Returning the function.
} //Closing brackets.
Mistakes happen, now fix them.
Reply
#8

You might want to explain some of the optimisations from the original topic. Some more information on multiple hooking methods (pretty much in order):

https://sampforum.blast.hk/showthread.php?tid=85907
https://sampforum.blast.hk/showthread.php?tid=166016
https://sampforum.blast.hk/showthread.php?tid=194509
https://sampforum.blast.hk/showthread.php?tid=241446
https://sampforum.blast.hk/showthread.php?tid=357881
https://sampforum.blast.hk/showthread.php?tid=382029
https://sampforum.blast.hk/showthread.php?tid=387600

Some of that data should be very useful, some less so (als2 I've not tested on Linux or with the JIT plugin, although I know Slice has solved the first issue).
Reply
#9

Quote:
Originally Posted by Cell_
Посмотреть сообщение
Mistakes happen, now fix them.
Well didn't I mention that we later undefine the original native? After undefining it, it no longer works. So if we just create the function without the original native, it won't perform as the original native. It just performs those server sided scores. Isn't it?
Reply
#10

Quote:
Originally Posted by Lordz™
Посмотреть сообщение
Well didn't I mention that we later undefine the original native. After undefining it, it no longer works. So if we just create the function without the original native, it won't perform as the original native. It just performs those server sided scores. Isn't it?
And what does SetPlayerPos have to do anything with player scores?

Quote:
Originally Posted by ******
Посмотреть сообщение
You put the define UNDER the function, not above.
Ah, that sums it all up.
Reply
#11

Quote:
Originally Posted by Cell_
Посмотреть сообщение
And what does SetPlayerPos have to do anything with player scores?



Ah, that sums it all up.
Oops, didn't see that well! I'm really sorry for that mistake. And you're correct, mistakes do happen. Thanks Cell_.
Reply
#12

You put the define UNDER the function, not above.
Reply
#13

Quote:
Originally Posted by Lordz™
View Post
How to hook Functions & Callbacks
Introduction
Well here I'm with my 3rd tutorial regarding hooking functions & callbacks. Yet this is even possible easily using y_hooks created by Y_Less but I thought of posting a tutorial regarding manual hooking method for users who like to know how to hook through manual way. There are other methods too for hooking callbacks/functions, but here I'm with what I know.

Hooking
Hooking means to add something on a particular thing. Here, we refer it to adding something too on a callback or function. For example, function 'SetPlayerScore' sets the player's score. But if we are using a server sided score system, the 'SetPlayerScore' won't set it. So, we've gotta set that server sided score too by setting variables.

Here's an example
Code:
public OnPlayerSpawn(playerid)
{
 SetPlayerScore(playerid, 50);
 return 1;
}
Here, it sets the score only, not our server sided score. So, if we want to set our server sided score, we've gotta set the variable for it too.

Code:
enum g_PLAYER_DATA
{
  L_KILLS,
  L_DEATHS,
  L_SCORE,
  L_MONEY,
  L_HEALTH,
  L_ADMIN,
  L_CLAN,
  L_VIP
} 
new L_PLAYER_INFO[MAX_PLAYERS][g_PLAYER_DATA];

//Example enum ^^

public OnPlayerSpawn(playerid)
{
  SetPlayerScore(playerid, 50);
  L_PLAYER_INFO[playerid][L_SCORE] = 50; //We've set our server sided score too.
  return 1;
}
This is the method we use when we don't hook. But, through hooking it allows it to be in one function and makes. Also, hooking callbacks allows to use it multiple times too and prevents errors and warns. So, lets get into the tutorial of hooking callbacks and functions.

Tutorial


Hooking Functions

Let's take an example that like the above. We'll hook 'SetPlayerScore' function. Inorder to hook, we can create a simple function as we create in our scripts using 'stock.'

Example stocks(functions)
Code:
stock GetName(playerid)
{
  new Lname[MAX_PLAYER_NAME];
  GetPlayerName(playerid, Lname, sizeof(Lname));
  return Lname;
}
//Now this is a function which gets player's name in one single line.

//Using it.
public OnPlayerDeath(playerid, killerid, reason)
{
  new str[128];
  format(str, sizeof(str), "%s killed %s", GetName(killerid), GetName(playerid)); //Gets the name of killer and the dead person.
  SendClientMessageToAll(0xFF0000FF, str);
  return 1;
}
This is how a simple function is created. As this tutorial is based on hooking functions and callbacks, I won't be explaining other stuffs, I'll be explaining more about the related stuffs of this tutorial only.

Now, let's hook our 'SetPlayerScore' function. To hook, first we must create a simple function of the server sided score. We can use 'stock' to create the function.

Code:
stock SetPlayerScoreEx(playerid, amount) //Two parameters: playerid, for the player and amount, the amount to set.
{ //Opening brackets to execute the functions below.
//We'll choose our made enum above and set it.
   L_PLAYER_INFO[playerid][L_SCORE] = amount; //It sets the server sided score to amount. Amount will be specified on the function by user itself.
   SetPlayerScore(playerid, amount); //We'll later undefine 'SetPlayerScore' function and hook it with our current stock. So it's necessary to use this function too or it doesn't make any sense it saying 'hooking SetPlayerScpre.'
   return 1; //Returning the function.
} //Closing brackets.
Now, we have created our function and this can be used as:
'SetPlayerScoreEx(playerid, amount);'
Example:
Code:
public OnPlayerSpawn(playerid)
{
  SetPlayerScoreEx(playerid, 50); //Sets to 50 server sided score and also the original score.
  return 1;
}
As we've created the functions required, lets start hooking. To hook, we can use simple defines and _ALS_ functions as it's said on Samp info(Some where, I don't remember it though. :P)

Code:
stock SetPlayerScoreEx(playerid, amount);
{
  L_PLAYER_INFO[playerid][L_SCORE] = amount;
  SetPlayerScore(playerid, amount);
  return 1;
}

/*Our function created.^^
For hooking, we'll detect it with _ALS_(function name) and if it isn't defined, we'll define it and then undefine the original function. We'll define the same undefined function then with our created function.
Code:
stock SetPlayerScoreEx(playerid, amount);
{
  L_PLAYER_INFO[playerid][L_SCORE] = amount;
  SetPlayerScore(playerid, amount); //We must do this too because we're gonna undefine the SetPlayerScore function later and hook it with our.
  return 1;
}

/*Our function created.^^
Hooking:*/

#if defined _ALS_SetPlayerScore //If _ALS_SetPlayerScore is defined. Then:
  #undef SetPlayerScore //If yes, it will undefine SetPlayerScore function.
#else //Else if not defined
#define _ALS_SetPlayerScore //If not defined, it will define _ALS_SetPlayerScore.
#endif //As we started a PAWN function with '#if', it's necessary to use #endif or you'll get trouble with errors.

/*SetPlayerScore is now undefined, we can define it to whatever we need :P. Even this:
#define SetPlayerScore 0xFF0000
But here, we must hook it, so we must define it to our function which we have created.*/
#define SetPlayerScore SetPlayerScoreEx //As we have undefined SetPlayerScore, inorder to hook it, we must define it to the stock function which we created.
We have successfully hooked a function and can use it!

Example:
Code:
public OnPlayerSpawn(playerid)
{
  SetPlayerScore(playerid, amount);
  //This do sets the original score as well as the server sided score to 50.
  return 1;
}
We have done with hooking functions.

Hooking Callbacks

This is also almost same as hooking callbacks, though it needs some more stuffs to do too. Lets hook OnPlayerSpawn.

To hook on callbacks, we don't need to create a stock/function for it. While hooking OnPlayerSpawn or any original SAMP callback, we must hook and create a callback inside the callback which needs to get hooked.

Code:
public OnPlayerSpawn(playerid)
{
 //This callback is called when a player spawns.
  return 1;
}
Now, lets hook it. For example, we need to add one more parameter too. Here, lets choose a weaponid parameter which must be like this:
'public OnPlayerSpawn(playerid, weaponid)'

First, we must create another callback to hook with, like how we created a function to hook.

Code:
public OnPlayerSpawn(playerid)
{
  //As we want to get the weaponid as a parameter on spawn callback, let's create a variable to get it.
  new weaponid; //Created a variable to get player's weapon.
  weaponid = GetPlayerWeapon(playerid);
   //To create a callback, we use CallLocalFunction. For more explanation about CallLocalFunction, go to wiki.sa-mp.com/wiki/CallLocalFunction
   CallLocalFunction("L_OnPlayerSpawn", "id", playerid, weaponid); 
  /*"id" are the formats used. 'i' and 'd' stands for the playerid and weaponid as those are integers/number. 'i' and 'd' both, stands same though.
It's done with creating a callback.*/
   return 1; //Returning the callback.
} //Closing brackets.
Just like we hooked a function using defines, we could hook the callback too.
Code:
public OnPlayerSpawn(playerid)
{
  new weaponid;
  weaponid = GetPlayerWeapon(playerid);
  CallLocalFunction("L_OnPlayerSpawn", "id", playerid, weaponid);
}

/*This was those callback and calls for the original callback we done. Now lets hook it.
Same like functions, we do use _ALS_ defining here.
In here, it's used that if _ALS_(callback name) is defined, we will undefine the callback and if it isn't defined, we'll define the _ALS_(callback name).
And then hook the callback.
*/

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

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

//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.
We can now use it as 'public OnPlayerSpawn(playerid, weaponid);'

Code:
public OnPlayerSpawn(playerid, weaponid);
{
  new str[128];
  SetPlayerScore(playerid, amount); //Sets the server sided score too as we have hooked.
   format(str, sizeof(str), "You are using %d weaponid.", weaponid);
   SendClientMessage(playerid, 0xFF0000, str);
   return 1;
}
We have done with learning how to hook functions and callbacks in a manual way.If you didn't understand any part of the tutorial, you can post it here and I'll explain more better.

Examples

Some examples:
Code:
public OnFilterScriptInit()
{
  SetTimer("Loopplayers", 1000, true);
  CallLocalFunction("L_OnFilterScriptInit", "");
   return 1;
}

forward Loopplayers();
public Loopplayers()
{
  for(new i = 0; i< MAX_PLAYERS; i++)
  {
    if(IsPlayerConnected(i))
    {
      if(GetPlayerHealth(i) >= 101)
      {
        SetPlayerHealth(i, 100);
      }
    }
  }
  return 1;
}

#if defined _ALS_OnFilterScriptInit
  #undef OnFilterScriptInit
#else
#define _ALS_OnFilterScriptInit
#endif

#define OnFilterScriptInit L_OnFilterScriptInit

forward L_OnFilterScriptInit();
Example 2
Code:
new lhp[MAX_PLAYERS];
stock SetPlayerHp(playerid, amount)
{
  lhp[playerid] = amount;
  SetPlayerHealth(playerid, amount);
   return 1;
}


#if defined _ALS_SetPlayerHealth
  #undef SetPlayerHealth
#else
#define _ALS_SetPlayerHealth
#endif
#define SetPlayerHealth SetPlayerHp

public OnFilterScriptInit()
{
  SetTimer("Detecthp", 1000, true);
  CallLocalFunction("L_OnFilterScriptInit", "");
   return 1;
}
forward Detecthp();
public Detecthp()
{
  for(new i = 0; i< MAX_PLAYERS; i++)
  {
    if(GetPlayerHealth(i) != lhp[i])
    {
      new str[128];
      new LName[MAX_PLAYER_NAME];
      GetPlayerName(playerid, Lname, sizeof(Lname));
      format(str, sizeof(str), "%s has been banned from the server. (Reason:Health hack)", Lname);
      Ban(playerid);
     }
  }
  return 1;
}

#if defined _ALS_OnFilterScriptInit
  #undef OnFilterScriptInit
#else
#define _ALS_OnFilterScriptInit
#endif
#define OnFilterScriptInit L_OnFilterScriptInit

forward L_OnFilterScriptInit();
Doubts, questions or anything related to this tutorial can be posted here.


-Lordz™.
what does _ALS_ means
Reply
#14

Quote:
Originally Posted by dr.lozer
View Post
what does _ALS_ means
'_ALS_' is a prefix used for hooking. It wasn't introduced at very beginning but then was inorder to hook functions and callbacks.
Reply
#15

Tnx lol
Reply
#16

I got too used so y_hooks that I forgot the origins, nice tutorial, that was an amazing reminder.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)