Solution for anti-fake killing.
#21

Quote:
Originally Posted by Raul_Ro
View Post
pawn Code:
// Anti FakeKill Flood by RuNix

#include <a_samp>

new XDeaths[MAX_PLAYERS];
new LastDeath[MAX_PLAYERS];

public OnFilterScriptInit()
{
    print("\n----------------------------------------");
    print(" Anti FakeKill Flood FilterScript by RuNix");
    print("----------------------------------------\n");
    return 1;
}

public OnFilterScriptExit()
{
    return 1;
}

public OnPlayerConnect(playerid)
{
    XDeaths[playerid] = 0;
    LastDeath[playerid] = 0;
    return 1;
}

public OnPlayerDeath(playerid, killerid, reason)
{
    if(XDeaths[playerid] == 0)
    {
       LastDeath[playerid] = gettime();
    }
    XDeaths[playerid]++;
    if(XDeaths[playerid] == 5)
    {
        if((gettime() - LastDeath[playerid]) <= 5)
        {
            SendClientMessage(playerid,0,"{FFBF00}Hey n0b, flood your mother!");
            BanEx(playerid,"Banned for FakeKill Flood");
        }else
        if((gettime() - LastDeath[playerid]) > 5)
        {
            XDeaths[playerid]=0;
        }
    }
    return 1;
}
I use this script on my server Romania Super Stunt and works perfectly.
This script is old of 0.3c and i don't used OnPlayerTakeDamage...
So what if somebody has a rocket and there are 5 noobs next to each other who die?
Reply
#22

Quote:
Originally Posted by RobinOwnz
View Post
So what if somebody has a rocket and there are 5 noobs next to each other who die?
That wouldn't matter, he is using somvariable[playerid]. So it would only count if THAT player died 5x in a row, not if all on the server added together died 5x in the same row.
Reply
#23

Quote:
Originally Posted by RobinOwnz
View Post
So what if somebody has a rocket and there are 5 noobs next to each other who die?
Then they deserve that since they're most likely to be cheating.
Reply
#24

Quote:
Originally Posted by Calgon
View Post
That's err...pretty simple to make. Or better yet, you could check if the player is streamed in to the player.

pawn Code:
public OnPlayerDeath(playerid, killerid, reason) {
    if(IsPlayerStreamedIn(playerid, killerid)) { // No need for a VW check, you don't stream in to other clients if they're in different VWs to you (presumably...)
        if(GetPlayerInterior(playerid) == GetPlayerInterior(killerid)) {
            if(GetPlayerWeapon(killerid) == reason) {
                print("OH HERRO!!!1!1!1");
            }
        }
    }
    return 1;
}
I'm sorry to bother but I don't understand this.
As far as I know, the weapon the killerid is using, SHOULD mach to the reason of the death, right?
If so this wouldn't work. And if not, could you tell me why?
Reply
#25

It's an attempt at a few extra layers of protection; there's still margin for error, but it's better than nothing. The reason does equal to the killerid's weapon, I see no problem with the code.
Reply
#26

Quote:
Originally Posted by Calgon
View Post
It's an attempt at a few extra layers of protection; there's still margin for error, but it's better than nothing. The reason does equal to the killerid's weapon, I see no problem with the code.
so if reason equals to the killerid's weapon, it's a fake kill?
Reply
#27

If it's not, it's a fake kill. As I said before, the code was more proof-of-concept and I made it in a rush, so the if statements are effectively the wrong way around.
Reply
#28

Quote:
Originally Posted by Calgon
View Post
If it's not, it's a fake kill. As I said before, the code was more proof-of-concept and I made it in a rush, so the if statements are effectively the wrong way around.
Yeah, but shouldn't it then be
pawn Code:
if(GetPlayerWeapon != reason)
or what I am not getting?
Reply
#29

Quote:

so the if statements are effectively the wrong way around.

You need to read that part.
Reply
#30

Quote:
Originally Posted by Calgon
View Post
You need to read that part.
oh sorry, brains aren't just working at night.
Reply
#31

pawn Code:
new LastDeath[ MAX_PLAYERS ];
new DeathSpam[ MAX_PLAYERS char ];

public OnPlayerDeath(playerid, killerid, reason)
{
    new time = gettime( );
    switch( time - LastDeath[ playerid ] )
    {
        case 0 .. 3:
        {
            DeathSpam{ playerid }++;
            if( DeathSpam{ playerid } == 3 )
            {
                BanEx( playerid, "Fake-kill" );
                return 1;
            }
        }
        default: DeathSpam{ playerid } = 0;
    }
    LastDeath[ playerid ] = time;
    return 1;
}
Created by Cessil, sent privately however, it's useful... Tested by me and works.

[NOTE]: MAKE SURE YOU RESET THE VARIABLES!
Reply
#32

Or just use PVar's?

But to be fair, with his code, resetting the variables would be easier.
Reply
#33

The cheat requires you to be streamed into your target before doing fake kill? Can anyone confirm that?
Reply
#34

Nope, it will fuck everyone. Even non-streamed.
Reply
#35

You don't need to reset those variables.

Also a bit suprised you mentioned that script and didn't mention the other tip I gave you.

Note down all weapon damages
for example:
{ 30, 9.900000, },//ak-47
{ 31, 9.900000, },//m4
Then frequently get the players health (using OPU would be ideal) and when they die check if their health was greater than the reason for their death.

So if they had 40hp and they suddenly die from a 9mm pistol which deals a damage of 8.25 then it's suspicious and you should alert the admins, however if it's a faster firing weapon you might get incorrect warnings due to OPU not getting called fast enough which is why you could note down the firing speed of each weapon and set a safe zone of a few bullets so you get less false positives.
This is how I got the weapon firing speeds, I found that it works best if you walk while you're firing, and fire up into the air so the game doesn't generate dust or sparks which could interfere with the testing results.

pawn Code:
public OnPlayerKeyStateChange(playerid,newkeys,oldkeys)
{
    if(HOLDING(KEY_FIRE))
    {
        SetPVarInt(playerid,"firing",1);
    }
    else
    {
        DeletePVar(playerid,"firing");
    }
    return 1;
}
new lastShotTime;
new lastAmmo;
new lastWeapon;
public OnPlayerUpdate(playerid)
{
    if(GetPVarInt(playerid,"firing"))
    {
        if(lastWeapon == GetPlayerWeapon(playerid) && GetPlayerAmmo(playerid) < lastAmmo)
        {
            printf("%d %d %d",lastWeapon,lastAmmo - GetPlayerAmmo(playerid),GetTickCount() - lastShotTime);
            lastShotTime = GetTickCount();
        }
        lastAmmo = GetPlayerAmmo(playerid);
        lastWeapon = GetPlayerWeapon(playerid);
    }
    return 1;
}
Now you're probably thinking what if there are multiple people firing at one person and they die from all of them?
Well you can use OnPlayerTakeDamage and count how many different other players the player has taken damage from and use that number in figuring out if its a fake kill or not.

Here's the check following no scripting rules whatsoever

Code:
If Last_Health > MaxDamage[reason] * Leniency[reason] * PlayersAttacking[playerid]
But this also raises the question about what if the other players attacking aren't using the same weapon which could be likely.

Code:
variable HealthLimit
Loop Through Players
{
  if itteration shot player and time shot is less than X (I'd say about 2 seconds)
  {
    increase HealthLimit to MaxDamage weapon used to damage * Leniency of weapon used
  }
}
if Last_Health > HealthLimit something seems a little suspicious
One more thing that came into mind when writing this and it's if the player is on low health and a group of players all shoot at the same time and that doesn't give OPTD to note everything before OPD is called, this could be a problem and a possible solution is to use OPGD as well, as that should be called before OPTD, I understand lag shooting where you have to aim in front however you'll find a lot of players that lag shoot will often hit their skin unintentionally.

There is one more thing I have experienced and that's vehicle explosions that causes the closest player to become killerid with their equipped weapon, and for this I will just paste things from the Anti-Carjack bug thread which can be found here https://sampforum.blast.hk/showthread.php?tid=305601


pawn Code:
GetVehicleHealth(GetPVarInt(playerid,"vehicleid"),Health);
        if(Health > 250.0)
        {
            //possible car jack bug
        }
I seem to remember that GetPlayerVehicleID also works under OPD (needs confirming)


So lastly to recap on all the things mentioned here I'll quickly write up and example (most likely non working) pawn script which you'll be able to modify and hopefully reduce the cheaters and false positives
pawn Code:
new PlayerDamagedPlayer[MAX_PLAYERS][MAX_PLAYERS] = { 255, ... };//sets default Value to 255 (unknown) this variable will store the weaponid used to attack
new PlayerDamagedPlayerTime[MAX_PLAYERS][MAX_PLAYERS];//this will store the time in seconds when the player was attacked
new Float:LastPlayerHealthUpdate[MAX_PLAYERS];

//PlayerDamagedPlayer will be in the format of [damagerid][victimid]

public OnPlayerSpawn(playerid)
{
  for(new i=0;i<MAX_PLAYERS;i++)
  {
//reset the variables when they respawn or after the checks in OPD
    PlayerDamagedPlayer[playerid][i] = 255;
    PlayerDamagedPlayer[i][playerid] = 255;
  }
}

stock Float:GetMaxWeaponDamage(weaponid)
{
  switch(weaponid)
  {
    case 22: return 8.25;//9mm
    case 23: return 13.20;//silencer
    case 24: return 46.20;//deagle
  }
  return 255.0;//just because it safely exceeds 200 (100 health + 100 armour)
}

//returns ticks inbetween each shot fired
stock GetWeaponFiringRate(weaponid)
{
  switch(weaponid)
  {
    case 22: return 100;//9mm
    case 23: return 250;//silencer
    case 24: return 600;//deagle
  }
}

public OnPlayerTakeDamage(playerid, issuerid, Float:amount, weaponid)
{
    PlayerDamagedPlayer[issuerid][playerid] = weaponid;
    PlayerDamagedPlayerTime[issuerid][playerid] = gettime();
}

public OnPlayerGiveDamage(playerid, damagedid, Float:amount, weaponid)
{
    PlayerDamagedPlayer[playerid][damagedid] = weaponid;
    PlayerDamagedPlayerTime[playerid][damagedid] = gettime();
}

public OnPlayerUpdate(playerid)
{
  new Float:health;
  GetPlayerHealth(playerid,health);
  LastPlayerHealthUpdate[playerid] = health;
}

public OnPlayerDeath(playerid,killerid,reason)
{
  new Float:TotalMaxDamage = 0.0;
  new CurrentTime = gettime();
  if(killerid != INVALID_PLAYERID)//killed by another player
  {
      for(new i=0;i<MAX_PLAYERS;i++)
      {
        if(PlayerDamagePlayer[i][playerid] != 255 && PlayerDamagePlayerTime[i][playerid] + 2 > CurrentTime)
        {
          new Float:MaxDamageFromPlayer = 0.0;
          MaxDamageFromplayer = GetMaxWeaponDamage(PlayerDamagePlayer[i][playerid]);
          switch(GetWeaponFiringRate(PlayerDamagePlayer[i][playerid]))
          {
             case 0 .. 100:
             {
               MaxDamageFromPlayer *= 4;
             }
             case 101 .. 200:
             {
               MaxDamageFromPlayer *= 2;
             }
          }
          TotalMaxDamage += MaxDamageFromPlayer;
        }
      }
      if(LastPlayerHealthUpdate[playerid] > TotalMaxDamage)
      {
        new Float:VehicleHealth;
        GetVehicleHealth(GetPlayerVehicleID(vehicleid),VehicleHealth);

        if(!IsPlayerInAnyVehicle(playerid) || VehicleHealth > 250.0)
        {
          //posible fake kill
        }
      }
  }
}
This was only meant to be a short post but I got a little carried away, the script probably won't compile but as long as you understand what I meant then that's all that matters, also there's loop holes in the script that could be exploited but you can patch them up when you discover them.
Reply


Forum Jump:


Users browsing this thread: 4 Guest(s)