Detecting native SA-MP functions -
KingHual - 08.02.2012
WARNING: This tutorial is not for PAWN newbies!
Introduction:
OK, first - I want to tell you I wanted to post this, because I recently began scripting for a MiniGames server, and there are like 100 gamemode scripts (The MiniGames themselves). And this surely helps on not having to actually replace all the functions. That's why I thought it would be useful to post it. Please don't start saying "OMG It's shit" and stuff.
This tutorial is a tutorial on how to detect native SA-MP functions which aren't detected by default, like: SetPlayerScore, GivePlayerMoney, GetPlayerScore and etc. and add new functions to them. This is useful if you've got a gamemode and you want to do something every time the server calls the default function. I'll now show you with my example function: SetPlayerScore(playerid, score);
Why you need this?
Well, let's imagine you've got a gamemode, in which you're using SetPlayerScore() like 100+ times. Now, you want to detect when this SetPlayerScore() function is called. Well, wouldn't it be a pain in the ass to add a CallRemoteFunction EVERY TIME you need to add this, plus you'll need a variable every time to save the score... Well, this tutorial solves it all. This method is used to hook a callback with default SA-MP functions and execute a piece of code WHILE doing what the function does by default. And all of that, when you type the original function code.
Tutorial:
1st. Open "a_players.inc". You can find it in your "YourServer/pawno/include" folder. Now, find the line
pawn Код:
native SetPlayerScore(playerid,score);
Now, on a new line below it, type this:
pawn Код:
native CUSTOM_SetPlayerScore = SetPlayerScore;
This piece of code initiates the new function "CUSTOM_SetPlayerScore" to act like "SetPlayerScore" and to actually set your score. Save the .inc file with the name "a_players.inc" (Yes, the same name of the file you opened).
2nd. Open the "a_samp.inc", located in the same directory as "a_players.inc". Go to the bottom line (Something like 330 by default in 0.3d). In a new line (The last line for the file) type:
pawn Код:
stock My_SetPlayerScore(playerid, score)
{
new CurScore = score - GetPlayerScore(playerid);
CUSTOM_SetPlayerScore(playerid, score);
CallRemoteFunction("OnPlayerScoreStateChange", "iii", playerid, CurScore, GetPlayerScore(playerid));
}
(The simple function) or
pawn Код:
stock My_SetPlayerScore(playerid, score)
{
CUSTOM_SetPlayerScore(playerid, score);
CallRemoteFunction("OnPlayerScoreStateChange", "i", playerid);
}
(The advanced function)
Now let me explain the lines above - The
pawn Код:
stock My_SetPlayerScore(playerid, score)
creates a new stock, you'll see what it's used for later. The
pawn Код:
CUSTOM_SetPlayerScore(playerid, score);
calls the custom SetPlayerScore function we created earlier. The
pawn Код:
CallRemoteFunction("OnPlayerScoreStateChange", "i", playerid);
calls the function in which you can add code that will be executed when the function "SetPlayerScore" (For this example) is detected.
3rd. Now, on a new line, below the stock, add
pawn Код:
#if defined _ALS_SetPlayerScore //This checks if SetPlayerScore is defined
#undef SetPlayerScore //This undefines it, so you can hook it with the function above
#else
#define _ALS_SetPlayerScore //This defines it if it's not defined
#endif
#define SetPlayerScore My_SetPlayerScore //This defines the default function as our function "My_SetPlayerScore"
You can change all of these to whatever you want (But ALWAYS keep the "_ALS_" in front of the functions)
4th. Under the above line, type
pawn Код:
forward OnPlayerScoreStateChange(playerid);
(The simple example from above) or
pawn Код:
forward OnPlayerScoreStateChange(playerid, difference, newscore);
(The advanced example from above[/pawn]
This is used to declare the function.
5th. Now, save the include. You can place the
pawn Код:
public OnPlayerScoreStateChange(playerid) {//Code here }
(The simple example from above) or
pawn Код:
public OnPlayerScoreStateChange(playerid, difference, newscore) {//Code here }
(The advanced example from above) anywhere in your scripts, and type what you want to happen when "SetPlayerScore" gets detected. My example for this:
pawn Код:
public OnPlayerScoreStateChange(playerid, difference, newscore)
{
SendClientMessage(playerid, 0xff0000ff, "Your score has changed");
}
(For the simple function) Or:
pawn Код:
public OnPlayerScoreStateChange(playerid, difference, newscore)
{
new str[64];
format(str, sizeof(str), "Difference:%i New score:%i", difference, newscore);
SendClientMessage(playerid, 0xff0000ff, str);
}
(For the advanced function)
NOTE: You HAVE TO recompile all the scripts that use "SetPlayerScore" for this to work.
NOTE: You don't have to add the next part to your scripts! It's just a test
Here's the output of the functions. I put this script under "OnPlayerCommandText":
pawn Код:
if (strcmp("/give", cmdtext, true, 10) == 0)
{
SetPlayerScore(playerid, GetPlayerScore(playerid) + 5);
return 1;
}
Also, have a look at this: A link for overall use of hooking, supported by ******:
https://sampforum.blast.hk/showthread.php?tid=85907
Here are the results:
*Advanced function:
*Simple function:
I hope this was useful.
Presented to you by: King_Hual
Re: Detecting native SA-MP functions - T0pAz - 08.02.2012
This is something which hasn't been done before. Nice work!
Re: Detecting native SA-MP functions -
KingHual - 08.02.2012
Thanks. That hooking actually mindfucked me until I figured it out
Re: Detecting native SA-MP functions -
Itachi_Avenger - 08.02.2012
Hi
u are pro
Bai
Re: Detecting native SA-MP functions -
KingHual - 08.02.2012
Quote:
Originally Posted by Itachi_Avenger
Hi
u are pro
Bai
|
What the....
Re: Detecting native SA-MP functions -
zgintasz - 10.02.2012
It's amazing. Can I make it with SetPlayerHealth and SetPlayerAmour for anti health-hack?
Re: Detecting native SA-MP functions -
KingHual - 10.02.2012
Quote:
Originally Posted by ******
You're joking right? There isn't much documentation on it so a tutorial is useful, but this technique was developed years ago:
https://sampforum.blast.hk/showthread.php?tid=85907
Also, I would advise against modifying the original includes - you don't actually need the second native at all as your method will bypass other hooks despite detecting them. Just call "SetPlayerScore" in your custom function, not "CUSTOM_SetPlayerScore". It comes before the "#define" so won't get replaced.
|
Ah, well I only found this some time ago. Thanks for the feedback, I didn't really look into the hooks... Also, I'm not sure if I understood you correctly, but I'm using CUSTOM_SetPlayerScore, because later the original SetPlayerScore gets replaced by A_SetPlayerScore... Well, I'm probably wrong, but what can I do lol
EDIT: I read your post once more and now I understand. But when I tested with SetPlayerScore, the compiler crashed...
Re: Detecting native SA-MP functions - T0pAz - 10.02.2012
Quote:
Originally Posted by ******
You're joking right? There isn't much documentation on it so a tutorial is useful, but this technique was developed years ago:
https://sampforum.blast.hk/showthread.php?tid=85907
And used in every decent library since then!
Also, I would advise against modifying the original includes - you don't actually need the second native at all as your method will bypass other hooks despite detecting them. Just call "SetPlayerScore" in your custom function, not "CUSTOM_SetPlayerScore". It comes before the "#define" so won't get replaced.
|
Never saw that ******. I was also not active on 2010.
Re: Detecting native SA-MP functions -
KingHual - 11.02.2012
Ah, ******, I read that topic. Gotta admit, it's explained alot better than this one is... There are some other things too, so I'll include the link to the tutorial.