PDA

View Full Version : Health and Armour Hacks Anticheat


JaKe Elite
30/10/2013, 11:11 AM
So i've been working on in a anti-cheat.
And i've been finding a solution for this but i can't it always fail.

The anti-cheat always detect me as Health/Armour Hack User.

Example. If i damage myself/receives damage, I get banned.

But it doesn't ban me when connecting/disconnecting (well because i set the key - the vars)

Here's how i do it.


public OnPlayerTakeDamage(playerid, issuerid, Float: amount, weaponid)
{
new Float:armour; GetPlayerArmour(playerid, armour);
if(armour > 0)
{
ACArmour[playerid] = ACArmour[playerid] - amount;
SetPlayerArmourEx(playerid, ACArmour[playerid]);
}
else
{
new Float:hp; GetPlayerHealth(playerid, hp);
ACHealth[playerid] = ACHealth[playerid] - amount;
SetPlayerHealthEx(playerid, ACHealth[playerid]);
}
return 1;
}

public OnPlayerGiveDamage(playerid, damagedid, Float: amount, weaponid)
{
new Float:armour; GetPlayerArmour(damagedid, armour);
if(armour > 0)
{
ACArmour[damagedid] = ACArmour[damagedid] - amount;
SetPlayerArmourEx(damagedid, ACArmour[damagedid]);
}
else
{
new Float:hp; GetPlayerHealth(damagedid, hp);
ACHealth[damagedid] = ACHealth[damagedid] - amount;
SetPlayerHealthEx(damagedid, ACHealth[damagedid]);
}
return 1;
}

//ACHealth[playerid] = 100.0; ACArmour[playerid] = 0.0; OnPlayerConnect/Disconnect
//ACHealth[playerid] = 0.0; OnPlayerDeath.

public AntiCheat()
{
new Query[200],
ip[24]
;
new string[250];
foreach(new i : Player)
{
new weap = GetPlayerWeapon(i),
Float:health,
Float:armour
;
GetPlayerHealth(i, health);
GetPlayerArmour(i, armour);
if(health > 0 && health != ACHealth[i])
{
ClearChatBox(i, 100);
GetPlayerIp(i, ip, 24);
format(string, sizeof string, " %s(%d) has been banned by AntiCheat | Reason: Health Hack", GetName(i), i);
SendClientMessageToAllEx(COLOR_RED, string);
SendClientMessageEx(i, COLOR_YELLOW, "AntiCheat: "white"[30] Wassup with your heal, Hahaha i caught you!");
SendClientMessageEx(i, COLOR_RED, "You've been banned from the server, Reason: Health Hacks!");
SendClientMessageEx(i, COLOR_GREEN, "If you think this is mistake create a ban appeal on the forum!");
format(Query, sizeof(Query), "UPDATE `bans` SET `Temporary` = 0, `IP` = '%s', `Month` = 1, `Days` = 1, `Years` = 1970, `NAME` = '%s', `REASON` = 'Health Hacks', `BannedBy` = 'AC' WHERE `NAME` = '%s'", ip, DB_Escape(GetName(i)), DB_Escape(GetName(i)));
db_query(Database, Query);
db_free_result(db_query(Database, Query));
KickDelay(i);
format(string, sizeof string, "%s has been banned by Anitcheat, Reason: Health Hack", GetName(i));
SaveLogs("aclog", string);
return 1;
}
if(armour > 0 && armour != ACArmour[i])
{
ClearChatBox(i, 100);
GetPlayerIp(i, ip, 24);
format(string, sizeof string, " %s(%d) has been banned by AntiCheat | Reason: Armour Hack", GetName(i), i);
SendClientMessageToAllEx(COLOR_RED, string);
SendClientMessageEx(i, COLOR_YELLOW, "AntiCheat: "white"[30] Wassup with your armour shield, Hahaha i caught you!");
SendClientMessageEx(i, COLOR_RED, "You've been banned from the server, Reason: Armour Hacks!");
SendClientMessageEx(i, COLOR_GREEN, "If you think this is mistake create a ban appeal on the forum!");
format(Query, sizeof(Query), "UPDATE `bans` SET `Temporary` = 0, `IP` = '%s', `Month` = 1, `Days` = 1, `Years` = 1970, `NAME` = '%s', `REASON` = 'Armour Hacks', `BannedBy` = 'AC' WHERE `NAME` = '%s'", ip, DB_Escape(GetName(i)), DB_Escape(GetName(i)));
db_query(Database, Query);
db_free_result(db_query(Database, Query));
KickDelay(i);
format(string, sizeof string, "%s has been banned by Anitcheat, Reason: Armour Hack", GetName(i));
SaveLogs("aclog", string);
return 1;
}
}
return 1;
}

forward SetPlayerHealthEx(playerid, Float:health);
public SetPlayerHealthEx(playerid, Float:health)
{
ACHealth[playerid] = health;
return SetPlayerHealth(playerid, ACHealth[playerid]);
}
forward SetPlayerArmourEx(playerid, Float:armour);
public SetPlayerArmourEx(playerid, Float:armour)
{
ACArmour[playerid] = armour;
return SetPlayerArmour(playerid, ACArmour[playerid]);
}

JaKe Elite
31/10/2013, 08:44 AM
BUMP guys.

iJumbo
31/10/2013, 08:53 AM
Mh try if issuerid is equal to INVALID_PLAYER_ID protect them from ban with some temp variable.

Ninad
31/10/2013, 08:53 AM
Its complicated! :(

iJumbo
31/10/2013, 08:57 AM
Well you don't need to reply "Its complicated" just for make messages this is Scripting Help not Everyting and nothing. If you have something in mind just edit your reply.

JaKe Elite
31/10/2013, 10:36 AM
iJumbo it didn't work.
I did this


if(issuerid == INVALID_PLAYER_ID)
{
//code
}

iJumbo
31/10/2013, 10:43 AM
I mean something like that

public OnPlayerTakeDamage(playerid, issuerid, Float: amount, weaponid)
{
if(issuerid != INVALID_PLAYER_ID) {
new Float:armour; GetPlayerArmour(playerid, armour);
if(armour > 0)
{
ACArmour[playerid] = ACArmour[playerid] - amount;
SetPlayerArmourEx(playerid, ACArmour[playerid]);
}
else
{
new Float:hp; GetPlayerHealth(playerid, hp);
ACHealth[playerid] = ACHealth[playerid] - amount;
SetPlayerHealthEx(playerid, ACHealth[playerid]);
}
} else {
SetPVarInt(playerid,"SafeBan",1);
new Float:hp; GetPlayerHealth(playerid, hp);
ACHealth[playerid] = ACHealth[playerid] - amount;
SetPlayerHealthEx(playerid, ACHealth[playerid]);
}
return 1;
}

public OnPlayerGiveDamage(playerid, damagedid, Float: amount, weaponid)
{
new Float:armour; GetPlayerArmour(damagedid, armour);
if(armour > 0)
{
ACArmour[damagedid] = ACArmour[damagedid] - amount;
SetPlayerArmourEx(damagedid, ACArmour[damagedid]);
}
else
{
new Float:hp; GetPlayerHealth(damagedid, hp);
ACHealth[damagedid] = ACHealth[damagedid] - amount;
SetPlayerHealthEx(damagedid, ACHealth[damagedid]);
}
return 1;
}

//ACHealth[playerid] = 100.0; ACArmour[playerid] = 0.0; OnPlayerConnect/Disconnect
//ACHealth[playerid] = 0.0; OnPlayerDeath.

public AntiCheat()
{
new Query[200],
ip[24]
;
new string[250];
foreach(new i : Player)
{
new weap = GetPlayerWeapon(i),
Float:health,
Float:armour
;
GetPlayerHealth(i, health);
GetPlayerArmour(i, armour);
if(health > 0 && health != ACHealth[i])
{
if(GetPVarInt(playerid,"SafeBan") == 0) {
ClearChatBox(i, 100);
GetPlayerIp(i, ip, 24);
format(string, sizeof string, " %s(%d) has been banned by AntiCheat | Reason: Health Hack", GetName(i), i);
SendClientMessageToAllEx(COLOR_RED, string);
SendClientMessageEx(i, COLOR_YELLOW, "AntiCheat: "white"[30] Wassup with your heal, Hahaha i caught you!");
SendClientMessageEx(i, COLOR_RED, "You've been banned from the server, Reason: Health Hacks!");
SendClientMessageEx(i, COLOR_GREEN, "If you think this is mistake create a ban appeal on the forum!");
format(Query, sizeof(Query), "UPDATE `bans` SET `Temporary` = 0, `IP` = '%s', `Month` = 1, `Days` = 1, `Years` = 1970, `NAME` = '%s', `REASON` = 'Health Hacks', `BannedBy` = 'AC' WHERE `NAME` = '%s'", ip, DB_Escape(GetName(i)), DB_Escape(GetName(i)));
db_query(Database, Query);
db_free_result(db_query(Database, Query));
KickDelay(i);
format(string, sizeof string, "%s has been banned by Anitcheat, Reason: Health Hack", GetName(i));
SaveLogs("aclog", string);
return 1;
} else {
SetPVarInt(playerid,"SafeBan",0);
}
}
if(armour > 0 && armour != ACArmour[i])
{
ClearChatBox(i, 100);
GetPlayerIp(i, ip, 24);
format(string, sizeof string, " %s(%d) has been banned by AntiCheat | Reason: Armour Hack", GetName(i), i);
SendClientMessageToAllEx(COLOR_RED, string);
SendClientMessageEx(i, COLOR_YELLOW, "AntiCheat: "white"[30] Wassup with your armour shield, Hahaha i caught you!");
SendClientMessageEx(i, COLOR_RED, "You've been banned from the server, Reason: Armour Hacks!");
SendClientMessageEx(i, COLOR_GREEN, "If you think this is mistake create a ban appeal on the forum!");
format(Query, sizeof(Query), "UPDATE `bans` SET `Temporary` = 0, `IP` = '%s', `Month` = 1, `Days` = 1, `Years` = 1970, `NAME` = '%s', `REASON` = 'Armour Hacks', `BannedBy` = 'AC' WHERE `NAME` = '%s'", ip, DB_Escape(GetName(i)), DB_Escape(GetName(i)));
db_query(Database, Query);
db_free_result(db_query(Database, Query));
KickDelay(i);
format(string, sizeof string, "%s has been banned by Anitcheat, Reason: Armour Hack", GetName(i));
SaveLogs("aclog", string);
return 1;
}
}
return 1;
}

forward SetPlayerHealthEx(playerid, Float:health);
public SetPlayerHealthEx(playerid, Float:health)
{
ACHealth[playerid] = health;
return SetPlayerHealth(playerid, ACHealth[playerid]);
}
forward SetPlayerArmourEx(playerid, Float:armour);
public SetPlayerArmourEx(playerid, Float:armour)
{
ACArmour[playerid] = armour;
return SetPlayerArmour(playerid, ACArmour[playerid]);
}


Or you can try run the function (anticheat) between getplayerhealth and setplayerhealthex without a timer

JaKe Elite
01/11/2013, 01:59 PM
Your code didn't work.
But, I, finally made it work.

Now i'm having another issue.
Now it works fine (When in god mode). I set the god mode in 160.0 (Since getplayerhealth always return this value when reached the health target).

The god mode works fine and always return this


160.000000 | 160.000000 //Setting the health
155.050003 | 155.050003 //Damaged (OnPlayerTakeDamage is called)


But here what happens when there is no god mode. (100.0)


100.000000 | 100.000000 (Jake_Hero turn off his /god)
95.050003 | 95.050003 (Jake_Hero is damaged, OnPlayerTakeDamage is called)
AC: 95.000000 | 95.050003 (Jake_Hero is banned)


See that? It works perfectly. But the AntiCheat detects it wrongly.
Yes in the first two value it displays the correct value. But after the decimal it displays this.


.000000


Not the current player health, this:


.050003


I've put debug in the function and it returns equal. But when there is no god mode, It always return unequal (The decimal numbers are displayed wrongly and the anticheat is called when the health and the var achealth is unequal)


forward SetPlayerHealthEx(playerid, Float:health);
public SetPlayerHealthEx(playerid, Float:health)
{
ACHealth[playerid] = health;
printf("%f | %f", ACHealth[playerid], health);
return SetPlayerHealth(playerid, health);
}
forward SetPlayerArmourEx(playerid, Float:armour);
public SetPlayerArmourEx(playerid, Float:armour)
{
ACArmour[playerid] = armour;
printf("%f | %f", ACArmour[playerid], armour);
return SetPlayerArmour(playerid, armour);
}
public AntiCheat()
{
new Query[900],
ip[24]
;
new string[250];
foreach(new i : Player)
{
if(GetPlayerState(i) == PLAYER_STATE_NONE || GetPlayerState(i) == PLAYER_STATE_WASTED || GetPlayerState(i) == PLAYER_STATE_SPECTATING) return 1;
if(GetPlayerWeaponState(i) == WEAPONSTATE_NO_BULLETS)
{
for(new x=0;x<47;x++) Weapon[i][x] = false;
}
new weap = GetPlayerWeapon(i),
Float:health,
Float:armour
;
GetPlayerHealth(i, health);
GetPlayerArmour(i, armour);
if(health != ACHealth[i])
{
printf("AC: %f | %f", health, ACHealth[i]);
ClearChatBox(i, 100);
GetPlayerIp(i, ip, 24);
format(string, sizeof string, " %s(%d) has been banned by AntiCheat | Reason: Health Hack", GetName(i), i);
SendClientMessageToAllEx(COLOR_RED, string);
SendClientMessageEx(i, COLOR_YELLOW, "AntiCheat: "white"[30] Wassup with your heal, Hahaha i caught you!");
SendClientMessageEx(i, COLOR_RED, "You've been banned from the server, Reason: Health Hacks!");
SendClientMessageEx(i, COLOR_GREEN, "If you think this is mistake create a ban appeal on the forum!");
format(Query, sizeof(Query), "UPDATE `bans` SET `Temporary` = 0, `IP` = '%s', `Month` = 1, `Days` = 1, `Years` = 1970, `NAME` = '%s', `REASON` = 'Health Hacks', `BannedBy` = 'AC' WHERE `NAME` = '%s'", ip, DB_Escape(GetName(i)), DB_Escape(GetName(i)));
db_query(Database, Query);
db_free_result(db_query(Database, Query));
KickDelay(i);
format(string, sizeof string, "%s has been banned by Anitcheat, Reason: Health Hack", GetName(i));
SaveLogs("aclog", string);
return 1;
}
if(armour != ACArmour[i])
{
ClearChatBox(i, 100);
GetPlayerIp(i, ip, 24);
format(string, sizeof string, " %s(%d) has been banned by AntiCheat | Reason: Armour Hack", GetName(i), i);
SendClientMessageToAllEx(COLOR_RED, string);
SendClientMessageEx(i, COLOR_YELLOW, "AntiCheat: "white"[30] Wassup with your armour shield, Hahaha i caught you!");
SendClientMessageEx(i, COLOR_RED, "You've been banned from the server, Reason: Armour Hacks!");
SendClientMessageEx(i, COLOR_GREEN, "If you think this is mistake create a ban appeal on the forum!");
format(Query, sizeof(Query), "UPDATE `bans` SET `Temporary` = 0, `IP` = '%s', `Month` = 1, `Days` = 1, `Years` = 1970, `NAME` = '%s', `REASON` = 'Armour Hacks', `BannedBy` = 'AC' WHERE `NAME` = '%s'", ip, DB_Escape(GetName(i)), DB_Escape(GetName(i)));
db_query(Database, Query);
db_free_result(db_query(Database, Query));
KickDelay(i);
format(string, sizeof string, "%s has been banned by Anitcheat, Reason: Armour Hack", GetName(i));
SaveLogs("aclog", string);
return 1;
}
}
return 1;
}

public OnPlayerTakeDamage(playerid, issuerid, Float: amount, weaponid)
{
if(issuerid == INVALID_PLAYER_ID)
{
if(ACArmour[playerid])
{
ACArmour[playerid] -= amount;
SetPlayerArmourEx(playerid, ACArmour[playerid]);
}
else
{
if(ACArmour[playerid] - amount >= 0)
{
ACArmour[playerid] -= amount;
SetPlayerArmourEx(playerid, ACArmour[playerid]);
}
else
{
ACHealth[playerid] -= (amount - ACArmour[playerid]);
ACArmour[playerid] = 0;
SetPlayerHealthEx(playerid, ACHealth[playerid]);
}
}
}
return 1;
}

public OnPlayerGiveDamage(playerid, damagedid, Float: amount, weaponid)
{
if(ACArmour[damagedid])
{
ACArmour[damagedid] -= amount;
SetPlayerArmourEx(damagedid, ACArmour[damagedid]);
}
else
{
if(ACArmour[damagedid] - amount >= 0)
{
ACArmour[damagedid] -= amount;
SetPlayerArmourEx(damagedid, ACArmour[damagedid]);
}
else
{
ACHealth[damagedid] -= (amount - ACArmour[damagedid]);
ACArmour[damagedid] = 0;
SetPlayerHealthEx(damagedid, ACHealth[damagedid]);
}
}
return 1;
}

Konstantinos
01/11/2013, 02:08 PM
If it's about the amount after the dot then you don't need to worry. If the health is 95.000 and the other is 95.500, both are 95 so that what it matters, right?


// In AntiCheat()
if( floatround( health ) != floatround( ACHealth[ i ] ) )
{
// Ban..
}

JaKe Elite
01/11/2013, 02:19 PM
Ahhh! Finally! It works fine no wrong detection.
When i use a cleo mod to spawn some health and armour it works fine! Thanks bud.

By the way, Is the way how i check the health and armour in each script is correct? (Asking for correction not codes)

Konstantinos
01/11/2013, 02:33 PM
The first thing is the size of the Query (900) and the string (250). You can use only 1 string for all the messages and with a lesser size.


// OnPlayerTakeDamage:
if(ACArmour[playerid])
{
ACArmour[playerid] -= amount;
SetPlayerArmourEx(playerid, ACArmour[playerid]);
}


So if ACArmour[playerid] is 5.0 and the amount (damage) is 10.0 then it'll won't decrease the health too.

RizkyX
21/12/2015, 10:35 PM
please help me
pwn(4128 ) : error 028: invalid subscript (not an array or too many subscripts): "ACHealth"
pwn(4128 ) : warning 215: expression has no effect
pwn(4128 ) : error 001: expected token: ";", but found "]"
pwn(4128 ) : error 029: invalid expression, assumed zero
pwn(4128 ) : fatal error 107: too many error messages on one line


4125 forward SetPlayerHealthEx(playerid, Float:health);
4126 public SetPlayerHealthEx(playerid, Float:health)
4127 {
4128 ACHealth[playerid] = health;
printf("%f | %f", ACHealth[playerid], health);
return SetPlayerHealth(playerid, health);
}