02.06.2018, 07:55
How to detect someone if it increases it's HP?
#define FILTERSCRIPT #include <a_samp> new Float:previousHealthValue[MAX_PLAYERS], hits[MAX_PLAYERS], noDamageCount[MAX_PLAYERS], //count how many times the player didn't lose health after being hit bool:delayer[MAX_PLAYERS], // delayer is neccessary because damage is not updated quickly enough and gives false detections bool:afterSpawnCover[MAX_PLAYERS], //to avoid false detections straight after spawn which happened to me while testing it (it's set to 3 seconds right now) bool:isDead[MAX_PLAYERS]; // hp check to see if the player is dead didn't work(the value of hp stayed the same as before last shot) //////////////////////////////// //SETTINGS #define DELAY_TIME 500 // 500ms delay works well on my syrver with 2 players online, I'm not sure what's it's going to be like on a server with over 100 players online #define AFTER_SPAWN_COVER_TIME 3000 #define NO_DAMAGE_COUNT_LIMIT 0 // number of times the script detected someone taking no damage after shot needed to: send info to admins/kick/ban //SETTINGS //////////////////////////////// public OnFilterScriptInit() { print("\n--------------------------------------"); print("Health-hack detector by monday"); print("--------------------------------------\n"); return 1; } public OnPlayerConnect(playerid) { previousHealthValue[playerid] = 0.0; hits[playerid] = 0; noDamageCount[playerid] = 0; delayer[playerid] = false; return 1; } public OnPlayerDeath(playerid, killerid, reason) { isDead[playerid] = true; return 1; } public OnPlayerSpawn(playerid) { previousHealthValue[playerid] = 0.0; hits[playerid] = 0; delayer[playerid] = false; afterSpawnCover[playerid] = true; SetTimerEx("RemoveSpawnCover", AFTER_SPAWN_COVER_TIME, false, "i", playerid); isDead[playerid] = false; return 1; } forward SwitchDelay(playerid); public SwitchDelay(playerid) { delayer[playerid] = true; return 1; } forward RemoveSpawnCover(playerid); public RemoveSpawnCover(playerid) { afterSpawnCover[playerid] = false; return 1; } public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ) { if(hittype == BULLET_HIT_TYPE_PLAYER) { new Float:h, Float:a, Float:newHealthValue, message[128], cheaterName[MAX_PLAYER_NAME]; if(hits[hitid] == 0) { GetPlayerHealth(hitid, h); GetPlayerArmour(hitid, a); previousHealthValue[hitid] = h + a; if(isDead[hitid] == true || afterSpawnCover[hitid] == true) // + here must be a check for AFK to avoid false detections { hits[hitid] = 0; } else { SetTimerEx("SwitchDelay", DELAY_TIME, false, "i", hitid); } } else if(delayer[hitid] == true) { delayer[hitid] = false; GetPlayerHealth(hitid, h); GetPlayerArmour(hitid, a); newHealthValue = h + a; if(newHealthValue == previousHealthValue[hitid] && isDead[hitid] != true && afterSpawnCover[hitid] != true) { noDamageCount[hitid]++; if(noDamageCount[hitid] > NO_DAMAGE_COUNT_LIMIT) { //send message to admins, kick, ban GetPlayerName(hitid, cheaterName, sizeof(cheaterName)); format(message,sizeof(message),"%s didn't lose health %d times after being shot since his last login.",cheaterName, noDamageCount[hitid]); SendClientMessageToAll(0xED6755AA,message); } } else { previousHealthValue[hitid] = newHealthValue; //update health value if it decreased like it should } SetTimerEx("SwitchDelay", DELAY_TIME, false, "i", hitid); // new delay before next check } hits[hitid]++; } return 1; }