Anti Cheat Tips -
brauf - 02.09.2018
Anti Cheat Tips
[*] Know what you're doing
Before you want to counter a cheat, you need to consider these questions:
What is the cheat?
How will this cheat affect the server?
Can this cheat be countered?
Does this cheat occur in my server daily?
Is there a pattern of how this cheat is used?
How will I counter this cheat?
[*] Here is an example
What is the cheat? Players are increasing their health, AKA using Godmode.
How will this cheat affect the server? Players are complaining that DM is unfair in my server because people are cheating so this might affect my playerbase
Can this cheat be countered? Yes it can, multiple ways.
Does this cheat occur in my server daily? Yes, everyday I atleast spot 2-3 people with this cheat. (Severity = HIGH)
Is there a pattern of how this cheat is used? This cheat is used by people with very high packet-loss and high ping meaning they might be using a VPN, so now I have to consider not banning innocents with bad internet.
How will I counter this cheat? There are multiple ways: Set the server maximum health to 99. Check if player is losing health on each shot.
[*] Trying out ideas
So, we have a owner having a problem with health cheaters, but they have thought of 2 solutions.
"Set the server maximum health to 99. Check if player is losing health on each shot.".
Okay, let's try it out!
So, the first idea was the set player health to 99. This mean if player health == 100, then they are not innocent.
I would suggest using a timer of every 500-750ms to check for every cheat. This way it would be much cleaner than using multiple timers for each cheat detection. Of course you can use OnPlayerUpdate, but we'll save that for later.
[#] First)
Let's make a command for your administrators to set a player's health and give a player some health.
Requirements: zcmd, sscanf2
PHP Code:
CMD:sethealth(playerid, params[])
{
new Float:health, targetid;
if(sscanf(params, "uf", targetid, health)) return SendClientMessage(playerid, -1, "err: /sethealth [id] [value]");
if(health > 99) SendClientMessage(playerid, -1, "err: You cannot set a player's health more than 99. ");
SetPlayerHealth(playerid, health);
}
As you can notice, we didn't just make the command. We made the command WITH checks. This is to make sure the administrator doesn't accidentally set anyones health over the limit that will ban a player. When you're trying to implement a counter for a cheat, make sure it cannot be accidentally produced manually by someone.
[#] Second)
Now, let's detect the cheat by using a timer.
PHP Code:
SetTimerEx("OnAntiCheatDetect", 750, true, "i", playerid);
Here we are making a timer with the callback "OnAntiCheatDetect". Make sure you make the timer's name very readable and clear for what purpose you're going to use it. In my case, this timer will handle all the anti cheat detections. On the second parameter, I have set the timer at 750ms on loop, with the third parameter true.
PHP Code:
forward OnAntiCheatDetect(playerid); public OnAntiCheatDetect(playerid)
{
static Float:playerHP;
GetPlayerHealth(playerid, Float:playerHP);
if(playerHP > 99)
{
Kick(playerid);
}
return 1;
}
Here in the call back we have collected the player's health on "playerHP" as a float. There was then a condition to check if player's health is greater than 99. Then inside the scope is where the code will be executed, in my case, I wrote Kick(playerid);, however, realistically I would store the value of how much times the player has been detected of cheating and then notify the admins, then kick.
[#] Third)
Now, here is the second method that we suggested.
Check if player is losing health on each shot.
Requirements: callbacks - by emmet
PHP Code:
new totalShots[MAX_PLAYERS], shotsThatDamaged[MAX_PLAYERS];
public OnPlayerTakeDamage(playerid, issuerid, Float:amount, weaponid)
{
if(!IsPlayerPaused(playerid)) shotsThatDamaged[playerid]++;
else {
totalShots[playerid] = 0; shotsThatDamaged[playerid] = 0;
}
return 1;
}
public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
if(hittype == BULLET_HIT_TYPE_PLAYER)
{
if(!IsPlayerPaused(hitid))
{
totalShots[hitid]++;
if(totalShots[hitid] - shotsThatDamaged[hitid] > 1)
{
Kick(hitid);
}
}
}
return 1;
}
public OnPlayerDisconnect(playerid, reason)
{
totalShots[playerid] = 0;
shotsThatDamaged[playerid] = 0;
return 1;
}
In here, we are checking for players
TOTAL_SHOTS_THAT_HIT_SOMEONE and players
TOTAL_SHOTS_THAT_DAMAGED_SOMEONE.
OnPlayerWeaponShot is always called before OnPlayerTakeDamage.
The logic behind the script is that, on OnPlayerWeaponShot we will count
TOTAL_SHOTS_THAT_HIT_SOMEONE, and then on OnPlayerTakeDamage we will count
TOTAL_SHOTS_THAT_DAMAGED_SOMEONE. If
TOTAL_SHOTS_THAT_HIT_SOMEONE -
TOTAL_SHOTS_THAT_DAMAGED_SOMEONE is greater than 1, then there was one shot that hit a player, but did not damage a player, so we will detect them as a cheater.
This is where you need to consider the player's packet loss and ping, because sometimes a player might not get damaged from a shot because of lag.
I would counter this by adding a global variable
PHP Code:
flagGODMODE[MAX_PLAYERS]
, then each time a player gets detected as a cheater I would increase the variable
PHP Code:
flagGODMODE[playerid]++
. Then if the variable is greater than 3,
PHP Code:
if(flagGODMODE > 3)
I would then kick the player and reset the variable for that id on OnPlayerDisconnect,
PHP Code:
flagGODMODE[playerid] = 0;
[*] How about anti-aimbot?
Well we all know, to shoot and hit a player, your cross-hair must be on the player. It must be facing at a reasonable place to hit the player.
Well anti-aimbot defies that. Apparently, if you aim metres away from the player, you will still manage to damage that player!
Well, that's easy to think of a solution! Let's use my formula:
What is the cheat? Players are using aim-bot to cheat their aim.
How will this cheat affect the server? Players are complaining that DM is unfair in my server because people are cheating so this might affect my playerbase
Can this cheat be countered? Yes it can.
Does this cheat occur in my server daily? Yes, everyday I atleast spot 2-3 people with this cheat. (Severity = HIGH)
Is there a pattern of how this cheat is used? Players are aiming near the player and not at the player
How will I counter this cheat? I can detect the coordinates when the bullets land and see if they are within a reasonable distance of the player.
Code:
|=|> #bullet
|=|> #bullet
*hit*
O *hit* O
***:::: ***
* :: *
* *
* * * *
That above is a visual representation of aimbot.
We can see there that the bullet doesn't hit the player but still does damage.
This is where
https://sampwiki.blast.hk/wiki/GetPlayerLastShotVectors is useful. With the
GetPlayerLastShotVectors function we can see where the bullet has landed.
[#] First)
PHP Code:
new aimbotWarning[MAX_PLAYERS];
public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
new Float:hitid_X, Float:hitid_Y, Float:hitid_Z;
GetPlayerPos(playerid, Float:hitid_X, Float:hitid_Y, Float:hitid_Z);
new Float:fOriginX, Float:fOriginY, Float:fOriginZ, Float:fHitPosX, Float:fHitPosY, Float:fHitPosZ;
GetPlayerLastShotVectors(playerid, Float:fOriginX, Float:fOriginY, Float:fOriginZ, Float:fHitPosX, Float:fHitPosY, Float:fHitPosZ);
if(!IsPlayerInRangeOfPoint(hitid, Float:1.5, Float:fHitPosX, Float:fHitPosY, Float:fHitPosZ))
{
aimbotWarning[hitid]++;
if(aimbotWarning[hitid] > 3)
{
Kick(hitid);
aimbotWarning[hitid] = 0;
}
return 1;
}
return 1;
}
public OnPlayerDisconnect(playerid, reason)
{
aimbotWarning[playerid] = 0;
}
From the code above, you can see that we are grabbing the player id's last shot vectors as coordinates so we can compare this to the hit id's coordinates and see if the bullet if within 1.5m of the player, if not, then kick them after a few warnings!
[*] How about more?
[*] Sorry, but I haven't got any more time today to finish off this tutorial, but I will have tomorrow! I will finish off the anti-aimbot tips and then introduce how to tackle people who c-cbug
Re: Anti Cheat Tips -
brauf - 02.09.2018
RESERVED
Re: Anti Cheat Tips -
RogueDrifter - 02.09.2018
Very very nice cant wait to see it finished keep it up
Re: Anti Cheat Tips -
brauf - 03.09.2018
Quote:
Originally Posted by RogueDrifter
Very very nice cant wait to see it finished keep it up
|
Thanks, yeah I'll try to finish it.
Re: Anti Cheat Tips -
TheToretto - 29.09.2018
The tutorial is fully understandable and clean
The content also, keep it up, I'll be watching the topic.
Re: Anti Cheat Tips -
Undef1ned - 30.09.2018
"OnPlayerWeaponShot" does not work (bug) on lag shot servers, or am I wrong?