[Tutorial] Easy Anti-Health hack.
#1

INTRODUCTION



Alright, so, basically, today i will show you how to script an Easy Anti-Health hack, which works pretty well.
It is also used in my game-mode.



---------------------------------------------------------------------------------------------------------------------
REQUIREMENTS



You will need this plugin:
Y_INI -> https://sampforum.blast.hk/showthread.php?tid=175565


---------------------------------------------------------------------------------------------------------------------
SCRIPTING



Alright, let's get started!

#1:

After you've added the Y_INI plugin, add this to the enum:
pawn Code:
enum pInfo
{
    //other stuff
    pAdmin,
    pACDetected
}
Then, you add this at "OnPlayerDisconnect"

pawn Code:
new INI:File = INI_Open(UserPath(playerid));
    INI_SetTag(File,"data");
    //other stuff here
    INI_WriteInt(File,"Admin",PlayerInfo[playerid][pAdmin]);
    INI_WriteInt(File,"ACDetected",PlayerInfo[playerid][pACDetected]);
    INI_Close(File);
And finally, at "Loaduser_data", add

pawn Code:
forward LoadUser_data(playerid,name[],value[]);
public LoadUser_data(playerid,name[],value[])
{
    //other stuff here
    INI_Int("Admin",PlayerInfo[playerid][pAdmin]);
    //other stuff here
    INI_Int("ACDetected",PlayerInfo[playerid][pACDetected]);
    return 1;
}
That's about it i suppose.

----

#2:

Find the "OnPlayerTakeDamage" call-back, we will script it in there.

For you, it will probably look like this(At the start):

pawn Code:
public OnPlayerTakeDamage(playerid, issuerid, Float: amount, weaponid)
{
    return 1;
}
Alright, now add this:
pawn Code:
if(PlayerInfo[playerid][pAdmin] == 0) //if he isn't an admin
                        {
It basically checks if the player is NOT an admin, so it looks like
pawn Code:
public OnPlayerTakeDamage(playerid, issuerid, Float: amount, weaponid)
{
    if(PlayerInfo[playerid][pAdmin] == 0) //if he isn't an admin
    {
        //script will be here
    }
    return 1;
}
Alright, now we will add this:

pawn Code:
if(PlayerInfo[playerid][pACDetected] == 0) //Y_INI enum, if the player hasn't been detected by the anti-cheat
    {
Under that;

pawn Code:
new Float:armour;
GetPlayerArmour(playerid, armour);
That will get the players(Possible hackers) armour.

For now, it looks like this:

pawn Code:
public OnPlayerTakeDamage(playerid, issuerid, Float: amount, weaponid)
{
    if(PlayerInfo[playerid][pAdmin] == 0) //if he isn't an admin
    {
        if(PlayerInfo[playerid][pACDetected] == 0) //Y_INI enum, if the player hasn't been detected by the anti-cheat
        {
            new Float:armour;
            GetPlayerArmour(playerid, armour);
        }
    }
    return 1;
}
Now, we will add this line, under "GetPlayerArmour(....);"

pawn Code:
if(armour == 0) //if his armour is 0
                {
As the comment says, it checks if the players(hackers) armour is 0!

Under the if(armour == 0), we will add these lines:

pawn Code:
new string[94];
new name[MAX_PLAYER_NAME];
GetPlayerName(playerid, name, sizeof(name));
new Float:health;
GetPlayerHealth(playerid,health);
new string: We will need this to format a message to the admins
new name: We will get the players(hackers) name, so we can add it in the string, and so admins know WHO is actually hacking.
new Float:health, and the line below it: Will get the players(hackers) health.

So, for now, it should look something like this:
pawn Code:
public OnPlayerTakeDamage(playerid, issuerid, Float: amount, weaponid)
{
    if(PlayerInfo[playerid][pAdmin] == 0) //if he isn't an admin
    {
        if(PlayerInfo[playerid][pACDetected] == 0) //Y_INI enum, if the player hasn't been detected by the anti-cheat
        {
            new Float:armour;
            GetPlayerArmour(playerid, armour);
            if(armour == 0) //if his armour is 0
            {
                new string[94]; //String for a message
                new name[MAX_PLAYER_NAME]; //Gets the hackers(players) name
                GetPlayerName(playerid, name, sizeof(name));
                new Float:health; //Gets the hackers(players) health
                GetPlayerHealth(playerid,health);
            }
        }
    }
    return 1;
}
Alright, now we need to do this:
pawn Code:
if(health >= 99) //If his health is 99 or more
{
    format(string, sizeof(string), "[ANTI-CHEAT] - %s[%d] is POSSIBLY using Health-Hacks!", name, playerid);
    SendMessageToAdmins(COLOR_ORANGE, string); //Sends the message to admins
    PlayerInfo[playerid][pACDetected] = 1; //Sets him as "Detected by Anti-Cheat", also avoids spam!
}
So, basically, if his ARMOUR is 0, and after all those shots, his health is 99 or more, then the ADMINS get warned.

Here's the FULL script:

pawn Code:
public OnPlayerTakeDamage(playerid, issuerid, Float: amount, weaponid)
{
    if(PlayerInfo[playerid][pAdmin] == 0) //if he isn't an admin
    {
        if(PlayerInfo[playerid][pACDetected] == 0) //Y_INI enum, if the player hasn't been detected by the anti-cheat
        {
            new Float:armour;
            GetPlayerArmour(playerid, armour);
            if(armour == 0) //if his armour is 0
            {
                new string[94]; //String for a message
                new name[MAX_PLAYER_NAME]; //Gets the hackers(players) name
                GetPlayerName(playerid, name, sizeof(name));
                new Float:health; //Gets the hackers(players) health
                GetPlayerHealth(playerid,health);
                if(health >= 99) //If his health is 99 or more
                {
                    format(string, sizeof(string), "[ANTI-CHEAT] - %s[%d] is POSSIBLY using Health-Hacks!", name, playerid);
                    SendMessageToAdmins(COLOR_ORANGE, string); //Sends the message to admins
                    PlayerInfo[playerid][pACDetected] = 1; //Sets him as "Detected by Anti-Cheat", also avoids spam!
                    return 1;      
                }
            }
        }
    }
    return 1;
}
----------

#3:

And to finish it, we need the "SendMessageToAdmins", and here it is:

pawn Code:
stock SendMessageToAdmins(color, text[])
{
    for(new i = 0; i < MAX_PLAYERS; i++) //loops trough all the players
    {
        if(PlayerInfo[i][pAdmin] >= 1) //if his(their) level 1 or more
        {
            SendClientMessage(i, color, text); //he(they) receive(s) the message
        }
    }
}
I've tested this 3 - 4x, and It worked 99%.
Reply
#2

Nice!
Reply
#3

If you tested it 3 to 4x how can it work 99percent ? You would need to test 100 times to be sure.
Reply
#4

yea it's good i thought about that once but it was so complicated so. thanks for doing this helpfull

btw it's nice that you made the admin get warned not the player that is possible health hack to get banned because im still not sure it's 99% percent
Reply
#5

Quote:
Originally Posted by [uL]Pottus
View Post
If you tested it 3 to 4x how can it work 99percent ? You would need to test 100 times to be sure.
Nothing can be 100% perfect..
But it works, it doesn't do false-warnings/false-bans.
If you're still unsure, you can add a "3x warning = Ban" thing.


Quote:
Originally Posted by Omar55555
View Post
yea it's good i thought about that once but it was so complicated so. thanks for doing this helpfull

btw it's nice that you made the admin get warned not the player that is possible health hack to get banned because im still not sure it's 99% percent
Thanks, and i actually edited it(In my game-mode), so it bans players, and so far i haven't gotten any false results.
Reply
#6

What's the purpose of y_INI here? To declare variables or arrays, you don't need y_INI. And this thing won't work well. What if SetPlayerHealth is being done? You haven't done much relating. Dude, test it well once again.
Referring damage only doesn't make it a good anti-cheat.
Reply
#7

Quote:
Originally Posted by Lordz™
View Post
What's the purpose of y_INI here? To declare variables or arrays, you don't need y_INI. And this thing won't work well. What if SetPlayerHealth is being done? You haven't done much relating. Dude, test it well once again.
In my script/gamemode(Call it w.e you want), I've added it so nobodies health can be set over 99.
For me, it works good, as i said above.
And as i said again, i did test it 3 - 4x, and all of the times, i didn't have any false results/warnings or w.e.
+, it says "Name[ID] is >>POSSIBLY<< health-hacking", not just straight "Name[ID] is health-hacking, 100% sure about it".
EDIT:
pawn Code:
if(health >= 99 || health < 102) //Change the health < 102 to 101 or 100 or w.e you want to, needs to be MORE than 99
Reply
#8

I believe Health Hack can be easily detected starting in 0.3z because there is a new callback called OnPlayerWeaponShot, I am not sure if my code will work it is un-tested but I know you can detect Health Hack using OnPlayerWeaponShot

pawn Code:
static stock
    AC_StartHPTick[ MAX_PLAYERS ];

#define MAX_HPWARNING (3)

public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
    new
        string[ 90 ], name[ MAX_PLAYER_NAME ], Float:Health, Float:Armour;

    GetPlayerArmour(hitid, Armour), GetPlayerHealth(hitid, Health), GetPlayerName(hitid, name, MAX_PLAYER_NAME);

    if(hittype == BULLET_HIT_TYPE_PLAYER)
    {
        if(Health >= 99.0 && Armour <= 0.0)
        {  
            ++ AC_StartHPTick[ playerid ];
        }
        else if(AC_StartHPTick[ playerid ] >= MAX_HPWARNING)
        {
            format(string, sizeof(string), "[ANTI-CHEAT] - %s[%d] is POSSIBLY using Health-Hacks!", name, playerid);
            SendClientMessageToAll(-1, string);
        }
        else
        {
            AC_StartHPTick[ playerid ] = 0;
        }
    }
    return true;
}
Reply
#9

Quote:
Originally Posted by pds2k12
View Post
I believe Health Hack can be easily detected starting in 0.3z because there is a new callback called OnPlayerWeaponShot, I am not sure if my code will work it is un-tested but I know you can detect Health Hack using OnPlayerWeaponShot

pawn Code:
static stock
    AC_StartHPTick[ MAX_PLAYERS ];

#define MAX_HPWARNING (3)

public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
    new
        string[ 90 ], name[ MAX_PLAYER_NAME ], Float:Health, Float:Armour;

    GetPlayerArmour(hitid, Armour), GetPlayerHealth(hitid, Health), GetPlayerName(hitid, name, MAX_PLAYER_NAME);

    if(hittype == BULLET_HIT_TYPE_PLAYER)
    {
        if(Health >= 99.0 && Armour <= 0.0)
        {  
            ++ AC_StartHPTick[ playerid ];
        }
        else if(AC_StartHPTick[ playerid ] >= MAX_HPWARNING)
        {
            format(string, sizeof(string), "[ANTI-CHEAT] - %s[%d] is POSSIBLY using Health-Hacks!", name, playerid);
            SendClientMessageToAll(-1, string);
        }
        else
        {
            AC_StartHPTick[ playerid ] = 0;
        }
    }
    return true;
}
You need to get player's armour and health after the if(hittype == BULLET_HIT_TYPE_PLAYER) check, otherwise you are applying them functions on objects and vehicles which is wrong.

It would be like this:

pawn Code:
static stock
    AC_StartHPTick[ MAX_PLAYERS ];

#define MAX_HPWARNING (3)

public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
    if(hittype == BULLET_HIT_TYPE_PLAYER)
    {
        new
        string[ 90 ], name[ MAX_PLAYER_NAME ], Float:Health, Float:Armour;

        GetPlayerArmour(hitid, Armour), GetPlayerHealth(hitid, Health), GetPlayerName(hitid, name, MAX_PLAYER_NAME);

        if(Health >= 99.0 && Armour <= 0.0)
        {  
            ++ AC_StartHPTick[ playerid ];
        }
        else if(AC_StartHPTick[ playerid ] >= MAX_HPWARNING)
        {
            format(string, sizeof(string), "[ANTI-CHEAT] - %s[%d] is POSSIBLY using Health-Hacks!", name, playerid);
            SendClientMessageToAll(-1, string);
        }
        else
        {
            AC_StartHPTick[ playerid ] = 0;
        }
    }
    return true;
}
Also what is 'static stock' and what's wrong with using the 'new' parameter?


About anti-cheat:

You really need to read cessil's thread about making a successful anti-cheat. The way you made it, if somebody uses a vending machine 3 times, it will get him banned. You need to take care of every possible way someone can get healed on your server means, you need to make completely server side health system such as make custom shops, remove vending machines and a lot more.
Reply
#10

Quote:
Originally Posted by Kyance
View Post
In my script/gamemode(Call it w.e you want), I've added it so nobodies health can be set over 99.
For me, it works good, as i said above.
And as i said again, i did test it 3 - 4x, and all of the times, i didn't have any false results/warnings or w.e.
+, it says "Name[ID] is >>POSSIBLY<< health-hacking", not just straight "Name[ID] is health-hacking, 100% sure about it".
EDIT:
pawn Code:
if(health >= 99 || health < 102) //Change the health < 102 to 101 or 100 or w.e you want to, needs to be MORE than 99
What the fuck am I reading, if health is greater than/equal to 99 or less than 102, it will always be less than 102, health is naturally 100, I'm going to assume you meant the AND operator which is &&
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)