#include <a_samp>

#define COLOR_LIGHTRED 		0xFF6347AA

#define RconProgram		1 	// Защита от взлома Rcon Программой 				| 1 - Включить | 0 - Выключить
#define Rcon			1	// Защита от взлома Rcon 							| 1 - Включить | 0 - Выключить
#define Ping			1	// Защита от пинга 							        | 1 - Включить | 0 - Выключить
#define Name			1	// Защита от ников 							        | 1 - Включить | 0 - Выключить
#define Connect			1	// Защита от ботов 							        | 1 - Включить | 0 - Выключить
#define Color			0	// Защита от подмены цветов							| 1 - Включить | 0 - Выключить
#define Swim			1	// Защита от Fly									| 1 - Включить | 0 - Выключить
#define Ped			    1	// Защита от Sobeit									| 1 - Включить | 0 - Выключить
#define Jet				1	// Защита от Jetpack								| 1 - Включить | 0 - Выключить
#define Weapon			1	// Защита от Оружия									| 1 - Включить | 0 - Выключить
#define Speed			1	// Защита от SpeedHack'a							| 1 - Включить | 0 - Выключить
#define Gm				1	// Защита от GodMod'a								| 1 - Включить | 0 - Выключить
#define Vehicle         0   // Защита от Тюнинга                                | 1 - Включить | 0 - Выключить
#define SendAdminMes    1   // Вывод сообщений Rcon Админу                      | 1 - Включить | 0 - Выключить

#define NoRcon			2 	// Попытка взлома Rcon   							| 0 - Бездействие | 1 - Кик | 2 - Бан | 3 - Сообщение Админам
#define Bots            2   // При входе ботов  								| 0 - Бездействие | 1 - Кик | 2 - Бан | 3 - Сообщение Админам
#define Fly           	3   // Fly												| 0 - Бездействие | 1 - Кик | 2 - Бан | 3 - Сообщение Админам
#define Sobeit          3  // Sobeit											| 0 - Бездействие | 1 - Кик | 2 - Бан | 3 - Сообщение Админам
#define MaxSpeed        3   // Speedhack										| 0 - Бездействие | 1 - Кик | 2 - Бан | 3 - Сообщение Админам
#define Veh             1   // За тюнинг										| 0 - Бездействие | 1 - Кик | 2 - Бан | 3 - Сообщение Админам

#define Eror			1 	// Максимум неверных Rcon паролей
#define MaxPing			400	// Максимальный пинг
#define MAX_SPEED 		110 // Максимальная скорость

#define SendKick        "Вы были кикнуты за читерство. Пожалуйста удалите читы!!! )" //Сообщение при кике игрока
#define SendBan         "Вы забанены за использование читов!!! )"                   //Сообщение при бане игрока
#define SendPing        "У Вас превышен пинг! Снижайте или Вас кикнут!!!"          //Сообщение при пинге выше MaxPing'a
#define SendRcon        "[A] Игрок %s [ID %d] Подозревается в взломе Rcon!"        //Сообщение при взлому ркон
#define SendAdm         "[A] Игрок %s [ID %d] Подозревается в читерстве!"          //Сообщение Админам при читерстве игрока
#define SendConnect     "[A] Игрок %s [ID %d] авторизировался(ась) на сервере!"    //Сообщение Админам при входе игрока
#define SendDisConnect  "[A] Игрок %s [ID %d] отсоеденился(ась) от сервера [%s]"  //Сообщение Админам при выходе игрока

forward Update();

new SendAdmin;
new AntiCheat[16], Max[2], Slap[7];
new PlayerName[MAX_PLAYER_NAME], players[MAX_PLAYERS];
new TOTALAIR[MAX_PLAYERS];

new string[144];

public OnFilterScriptInit()
{
	print("\n*--------------------------------------*");
	print("*                                        *");
	print("*                                        *");
	print("*                                        *");
	print("*--------------------------------------*\n");
	return true;
}

public OnGameModeInit()
{
	if(AntiCheat[0] == 1) SendRconCommand("rcon 0");
 	SetTimer("Update", 1000, 1);
 	SetTimer("Updats", 1000, 1);
 	AntiCheat[0] = RconProgram;
 	Max[0] = Eror, Max[1] = MaxPing;
	AntiCheat[1] = Rcon, AntiCheat[2] = Ping, AntiCheat[3] = Name, AntiCheat[4] = Connect;
    AntiCheat[6] = Color, AntiCheat[7] = Swim, AntiCheat[8] = Ped;
	AntiCheat[9] = Jet, AntiCheat[10] = Weapon, AntiCheat[11] = Speed, AntiCheat[12] = Gm;
	Slap[0] = NoRcon, Slap[1] = Bots, Slap[3] = Fly, Slap[4] = Sobeit, Slap[5] = MaxSpeed;
	AntiCheat[13] = Vehicle, AntiCheat[14] = Veh; SendAdmin = SendAdminMes;
	return true;
}

public OnPlayerConnect(playerid)
{
    TOTALAIR[playerid] = 0;
	if(AntiCheat[3] == 1)
	{
		GetPlayerName(playerid, PlayerName, sizeof(PlayerName));
		if(strlen(PlayerName) > 22)
		{
			strdel(PlayerName, 20, 22);
			SetPlayerName(playerid, PlayerName);
		}
	}
	if(AntiCheat[4] == 1)
	{
		if(!IsPlayerConnected(playerid))
		{
			switch(Slap[1])
   			{
      			case 0: return true;
				case 1: return SendClientMessage(playerid, COLOR_LIGHTRED, SendKick), Kick(playerid);
				case 2: return SendClientMessage(playerid, COLOR_LIGHTRED, SendBan), Ban(playerid);
				case 3: { format(string, 70, SendAdm ,sendername(playerid), playerid); return SendAdminMessage(COLOR_LIGHTRED, string); }
			}
		}
	}
	if(SendAdmin == 1)
	{
		format(string, 70, SendConnect ,sendername(playerid), playerid);
		return SendAdminMessage(COLOR_LIGHTRED, string);
	}
	return true;
}

public OnPlayerDisconnect(playerid, reason)
{
	if(SendAdmin == 1)
	{
		new disreason[10];
		switch(reason) { case 0: disreason = "Тайм-аут"; case 1: disreason = "Выход"; case 2: disreason = "Кикнут"; }
	   	format(string, 127, SendDisConnect,sendername(playerid), playerid, disreason);
		return SendAdminMessage(COLOR_LIGHTRED, string);
	}
	return true;
}

public OnPlayerDeath(playerid, killerid, reason)
{
	if(SendAdmin == 1)
	{
		new gunname[32]; GetWeaponName(reason,gunname,sizeof(gunname));
		if(strlen(gunname) > 1 && killerid != 65535) format(string, 120,"[A] Игрок %s [ID: %d] убил игрока %s [ID: %d] с оружия %s [ID: %d]",sendername(killerid),killerid,sendername(playerid),playerid,gunname,reason);
		else if(killerid != INVALID_PLAYER_ID && strlen(gunname) < 1) format(string, 100, "[A] Игрок %s [ID: %d] убил игрока %s [ID: %d] кулаками [ID: 0]",sendername(killerid),killerid,sendername(playerid),playerid);
		else if(killerid == INVALID_PLAYER_ID || killerid == 65535) format(string, 50, "[A] Игрок %s [ID: %d] погиб",sendername(playerid), playerid);
		return SendAdminMessage(COLOR_LIGHTRED,string);
	}
	return true;
}

public OnPlayerSpawn(playerid)
{
    if(AntiCheat[6] == 1)
    {
		if(GetPlayerColor(playerid) != 0xFF) return true;
		SendClientMessage(playerid, COLOR_LIGHTRED, SendKick), Kick(playerid);
	}
	return true;
}

public OnPlayerText(playerid, text[])
{
    if(strfind(text, "http", true) != -1) return false;
    if(strfind(text, ".ru", true) != -1) return false;
    if(strfind(text, ".com", true) != -1) return false;
    if(strfind(text, ".ua", true) != -1) return false;
    if(strfind(text, "\\", true) != -1) return false;
    if(strfind(text, ":", true) != -1) return false;
	return true;
}

public OnVehicleMod(playerid, vehicleid, componentid)
{
	if(AntiCheat[13] == 1)
	{
        if(GetPlayerInterior(playerid) == 0 && GetPlayerState(playerid) == PLAYER_STATE_DRIVER)
        {
	    	switch(AntiCheat[14])
   			{
            	case 0: return true;
	            case 1: return SendClientMessage(playerid, COLOR_LIGHTRED, SendKick), Kick(playerid);
	            case 2: return SendClientMessage(playerid, COLOR_LIGHTRED, SendBan), Ban(playerid);
                case 3: { format(string, 70, SendAdm ,sendername(playerid), playerid); return SendAdminMessage(COLOR_LIGHTRED, string); }
			}
        }
	}
	return true;
}

public OnRconLoginAttempt(ip[], password[], success)
{
    new ips[16];
    if(!success)
    {
		if(AntiCheat[1] == 1)
		{
			for(new i = GetMaxPlayers() - 1; i != -1; i--)
			{
				GetPlayerIp(i, ips, sizeof(ips));
				if(strcmp(ip, ips, true)) return true;
				players[i]++;
				if(players[i] == Max[0])
				{
     				switch(Slap[0])
                    {
                        case 0: return true;
						case 1: return SendClientMessage(i, COLOR_LIGHTRED, SendKick), Kick(i);
						case 2: return SendClientMessage(i, COLOR_LIGHTRED, SendBan), Ban(i);
						case 3: { format(string, 70, SendRcon ,sendername(i), i); return SendAdminMessage(COLOR_LIGHTRED, string); }
					}
				}
			}
		}
	}
    return true;
}

public OnPlayerUpdate(playerid)
{
	new animlib[30], animname[30];
	GetAnimationName(GetPlayerAnimationIndex(playerid), animlib, sizeof(animlib), animname, sizeof(animname));
	if(AntiCheat[2] == 1) { if(GetPlayerPing(playerid) > Max[1]) SendClientMessage(playerid, COLOR_LIGHTRED, SendPing), Kick(playerid); }
	if(AntiCheat[7] == 1)
	{
		if(!IsPlayerInAnyVehicle(playerid) && GetPlayerState(playerid) != 9)
		{
		    new Float:Cord[3];
		    GetPlayerPos(playerid, Cord[0], Cord[1], Cord[2]);
		    if(Cord[2] >= 2)
		    {
		        if(strcmp(animlib, "SWIM", true) == 0 && strcmp(animname, "SWIM_crawl", true) == 0)
		        {
  					switch(Slap[3])
                    {
                        case 0: return true;
						case 1: SendClientMessage(playerid, COLOR_LIGHTRED, SendKick), Kick(playerid);
						case 2: SendClientMessage(playerid, COLOR_LIGHTRED, SendBan), Ban(playerid);
						case 3: { format(string, 70, SendAdm ,sendername(playerid), playerid); return SendAdminMessage(COLOR_LIGHTRED, string); }
					}
		        }
		    }
		}
	}
	if(AntiCheat[8] == 1)
	{
	 	if(GetPlayerState(playerid) == PLAYER_STATE_ONFOOT)
		{
		    if(strcmp(animlib, "PED", true) == 0 && strcmp(animname, "RUN_PLAYER", true) == 0)
		    {
				switch(Slap[4])
	   			{
	      			case 0: return true;
				    case 1: SendClientMessage(playerid, COLOR_LIGHTRED, SendKick), Kick(playerid);
			        case 2: SendClientMessage(playerid, COLOR_LIGHTRED, SendBan), Ban(playerid);
			        case 3: { format(string, 70, SendAdm ,sendername(playerid), playerid); return SendAdminMessage(COLOR_LIGHTRED, string); }
				}
		    }
		}
	}
	return true;
}

public Update()
{
	new weapons[13][3];
	for(new i = GetMaxPlayers() - 1; i != -1; i--)
	{
	    if(GetPVarInt(i, "AntiBreik") > 0) SetPVarInt(i, "AntiBreik", GetPVarInt(i, "AntiBreik") - 1);
		for(new j = 0; j < 13; j++)
		{
		    if(AntiCheat[10] == 1)
		    {
		 		if(!IsPlayerInAnyVehicle(i))
		 		{
					GetPlayerWeaponData(i, j, weapons[j][1], weapons[j][2]);
					if(weapons[j][1] == 27 || weapons[j][1] == 17 || weapons[j][1] == 19
					|| weapons[j][1] == 20 || weapons[j][1] == 21 || weapons[j][1] == 35 || weapons[j][1] == 36 || weapons[j][1] == 39 || weapons[j][1] == 40 || weapons[j][1] == 44 || weapons[j][1] == 45
					|| weapons[j][1] == 38 || weapons[j][1] == 32 || weapons[j][1] == 28 || weapons[j][1] == 18 || weapons[j][1] == 37 || weapons[j][1] == 16 || weapons[j][1] == 9)
					{
					    ResetPlayerWeapons(i);
						SendClientMessage(i, COLOR_LIGHTRED, SendKick), Kick(i);
					}
				}
			}
		}
		if(AntiCheat[11] == 1)
		{
			if(GetPlayerState(i) == 2)
			{
				if(SpeedVehicle(i) / 2 > MAX_SPEED)
				{
					switch(Slap[5])
		   			{
		      			case 0: return true;
				        case 1: SendClientMessage(i, COLOR_LIGHTRED, SendKick), Kick(i);
			        	case 2: SendClientMessage(i, COLOR_LIGHTRED, SendBan), Ban(i);
			        	case 3: { format(string, 70, SendAdm ,sendername(i), i); return SendAdminMessage(COLOR_LIGHTRED, string); }
					}
			    }
			}
		}
	    if(AntiCheat[9] == 1)
	    {
			if(GetPlayerSpecialAction(i) == SPECIAL_ACTION_USEJETPACK)
			{
				switch(Slap[4])
	   			{
	      			case 0: return true;
		            case 1: SendClientMessage(i, COLOR_LIGHTRED, SendKick), Kick(i);
	        	    case 2: SendClientMessage(i, COLOR_LIGHTRED, SendBan), Ban(i);
	        	    case 3: { format(string, 70, SendAdm ,sendername(i), i); return SendAdminMessage(COLOR_LIGHTRED, string); }
				}
			}
		}
	}
	return true;
}

public OnPlayerGiveDamage(playerid, damagedid, Float:amount, weaponid)
{
    if(AntiCheat[12] == 0) return true;
	new Float:Dmg[3];
 	GetPlayerArmour(damagedid, Dmg[1]);
  	GetPlayerHealth(damagedid, Dmg[0]);
   	if(Dmg[1] > 0)
    {
    	if(amount > Dmg[1])
     	{
      		Dmg[2] = amount - Dmg[1];
        	Dmg[0] = Dmg[0] - Dmg[2];
         	SetPlayerArmour(damagedid, 0.0);
          	return SetPlayerHealth(damagedid, Dmg[0]);
        }
       	Dmg[1] = Dmg[1] - amount;
        SetPlayerArmour(damagedid, Dmg[1]);
    }
    if(Dmg[1] < 1)
    {
    	Dmg[0] = Dmg[0] - amount;
    	SetPlayerHealth(damagedid, Dmg[0]);
    }
    return true;
}

stock SpeedVehicle(playerid)
{
    new Float:ST[4];
	if(IsPlayerInAnyVehicle(playerid)) GetVehicleVelocity(GetPlayerVehicleID(playerid),ST[0],ST[1],ST[2]);
	else GetPlayerVelocity(playerid,ST[0],ST[1],ST[2]);
    ST[3] = floatsqroot(floatpower(floatabs(ST[0]), 2.0) + floatpower(floatabs(ST[1]), 2.0) + floatpower(floatabs(ST[2]), 2.0)) * 213.3;
    return floatround(ST[3]);
}

stock sendername(playerid) { new name[MAX_PLAYER_NAME]; GetPlayerName(playerid, name, sizeof(name)); return name; }

stock SendAdminMessage(color, str[])
{
    for(new i = GetMaxPlayers() - 1; i != -1; i--)
	{
	    if(!IsPlayerConnected(i)) continue;
		if(IsPlayerAdmin(i)) SendClientMessage(i, color, str);
	}
	return true;
}
