Активный
- Тема Автор
- #1
Защита от читов - важная часть любого сервера. Разберем базовые методы защиты.
Проверка скорости
Проверка телепортации
Проверка оружия
Проверка здоровья
Проверка денег
Система предупреждений
Важные моменты:
- Не делайте проверки слишком строгими
- Учитывайте легитимные способы перемещения
- Логируйте все подозрительные действия
- Используйте систему предупреждений
- Регулярно обновляйте защиту
Античит требует постоянного совершенствования!
Проверка скорости
Код:
new Float:PlayerLastPos[MAX_PLAYERS][3];
new PlayerLastUpdate[MAX_PLAYERS];
public OnPlayerUpdate(playerid)
{
new Float:x, Float:y, Float:z;
GetPlayerPos(playerid, x, y, z);
new time = GetTickCount();
if(PlayerLastUpdate[playerid] > 0)
{
new Float:distance = floatsqroot(
floatpower(x - PlayerLastPos[playerid][0], 2) +
floatpower(y - PlayerLastPos[playerid][1], 2) +
floatpower(z - PlayerLastPos[playerid][2], 2)
);
new interval = time - PlayerLastUpdate[playerid];
new Float:speed = (distance / float(interval)) * 1000.0;
if(speed > 200.0) // максимальная скорость
{
new string[128];
format(string, sizeof(string), "[Античит] Игрок %s подозревается в использовании читов (скорость: %.2f)",
GetPlayerName(playerid), speed);
SendMessageToAdmins(-1, string);
// Наказание
SetPlayerHealth(playerid, 0.0);
}
}
PlayerLastPos[playerid][0] = x;
PlayerLastPos[playerid][1] = y;
PlayerLastPos[playerid][2] = z;
PlayerLastUpdate[playerid] = time;
return 1;
}
Проверка телепортации
Код:
new Float:PlayerLastPos[MAX_PLAYERS][3];
public OnPlayerSpawn(playerid)
{
GetPlayerPos(playerid, PlayerLastPos[playerid][0], PlayerLastPos[playerid][1], PlayerLastPos[playerid][2]);
return 1;
}
public OnPlayerUpdate(playerid)
{
new Float:x, Float:y, Float:z;
GetPlayerPos(playerid, x, y, z);
new Float:distance = floatsqroot(
floatpower(x - PlayerLastPos[playerid][0], 2) +
floatpower(y - PlayerLastPos[playerid][1], 2) +
floatpower(z - PlayerLastPos[playerid][2], 2)
);
if(distance > 50.0 && !IsPlayerInAnyVehicle(playerid))
{
// Возможная телепортация
new string[128];
format(string, sizeof(string), "[Античит] Игрок %s подозревается в телепортации",
GetPlayerName(playerid));
SendMessageToAdmins(-1, string);
}
PlayerLastPos[playerid][0] = x;
PlayerLastPos[playerid][1] = y;
PlayerLastPos[playerid][2] = z;
return 1;
}
Проверка оружия
Код:
new PlayerWeapon[MAX_PLAYERS];
new PlayerAmmo[MAX_PLAYERS];
public OnPlayerUpdate(playerid)
{
new weapon = GetPlayerWeapon(playerid);
new ammo = GetPlayerAmmo(playerid);
if(weapon != PlayerWeapon[playerid] || ammo != PlayerAmmo[playerid])
{
// Проверка на разрешенное оружие
if(!IsWeaponAllowed(weapon))
{
RemovePlayerWeapon(playerid, weapon);
SendClientMessage(playerid, -1, "Это оружие запрещено");
}
// Проверка на бесконечные патроны
if(ammo > PlayerAmmo[playerid] && PlayerAmmo[playerid] > 0)
{
new string[128];
format(string, sizeof(string), "[Античит] Игрок %s подозревается в читах на патроны",
GetPlayerName(playerid));
SendMessageToAdmins(-1, string);
}
}
PlayerWeapon[playerid] = weapon;
PlayerAmmo[playerid] = ammo;
return 1;
}
stock IsWeaponAllowed(weaponid)
{
new allowed_weapons[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for(new i = 0; i < sizeof(allowed_weapons); i++)
{
if(weaponid == allowed_weapons[i])
{
return 1;
}
}
return 0;
}
Проверка здоровья
Код:
new Float:PlayerLastHealth[MAX_PLAYERS];
public OnPlayerUpdate(playerid)
{
new Float:health;
GetPlayerHealth(playerid, health);
if(health > PlayerLastHealth[playerid] && PlayerLastHealth[playerid] < 100.0)
{
// Проверка на автолечение
if(!IsPlayerAtHospital(playerid))
{
new string[128];
format(string, sizeof(string), "[Античит] Игрок %s подозревается в автолечении",
GetPlayerName(playerid));
SendMessageToAdmins(-1, string);
}
}
PlayerLastHealth[playerid] = health;
return 1;
}
Проверка денег
Код:
new PlayerLastMoney[MAX_PLAYERS];
public OnPlayerUpdate(playerid)
{
new money = GetPlayerMoney(playerid);
if(money > PlayerLastMoney[playerid])
{
new difference = money - PlayerLastMoney[playerid];
// Проверка на подозрительное увеличение денег
if(difference > 100000 && !IsPlayerEarningMoney(playerid))
{
new string[128];
format(string, sizeof(string), "[Античит] Игрок %s подозревается в читах на деньги (+$%d)",
GetPlayerName(playerid), difference);
SendMessageToAdmins(-1, string);
// Откат денег
GivePlayerMoney(playerid, -difference);
}
}
PlayerLastMoney[playerid] = money;
return 1;
}
Система предупреждений
Код:
new PlayerWarnings[MAX_PLAYERS];
AddWarning(playerid, reason[])
{
PlayerWarnings[playerid]++;
new string[128];
format(string, sizeof(string), "[Античит] Игрок %s получил предупреждение (%d/3): %s",
GetPlayerName(playerid), PlayerWarnings[playerid], reason);
SendMessageToAdmins(-1, string);
if(PlayerWarnings[playerid] >= 3)
{
Ban(playerid);
format(string, sizeof(string), "Игрок %s забанен за читы", GetPlayerName(playerid));
SendClientMessageToAll(-1, string);
}
}
public OnPlayerConnect(playerid)
{
PlayerWarnings[playerid] = 0;
return 1;
}
Важные моменты:
- Не делайте проверки слишком строгими
- Учитывайте легитимные способы перемещения
- Логируйте все подозрительные действия
- Используйте систему предупреждений
- Регулярно обновляйте защиту
Античит требует постоянного совершенствования!