Доступ к готовым решениям

Переход в группу "Пользователь"

300.00
Одноразовый платёж
Быстрый переход в группу "Пользователи", без надобности написания постов и ожидания.

Покупка дает возможность:
Быть полноправным участником форума
Нормальное копирование кода
Создавать темы
Скачивать файлы
Доступ к архиву Pawno-Info

Настройка анти-чита Nex Anticheat (Nex-AC)

whale

/proger/
Регистрация
20 Сен 2013
Сообщения
1,076
Лучшие ответы
4
Репутация
421
Чтобы видеть скрытое содержание Зарегистрируйтесь на форуме!

Данная тема является уроком по настройке Nex Anticheat (Nex-AC)




Сегодня мы рассмотрим два варианта настройки данного анти-чита:
  • Обычная настройка.
    [*] Динамическая настройка с сохранением (MySQL).

Итоговый результат (скриншоты):
Чтобы видеть скрытое содержание Зарегистрируйтесь на форуме!
Чтобы видеть скрытое содержание Зарегистрируйтесь на форуме!
Чтобы видеть скрытое содержание Зарегистрируйтесь на форуме!
Чтобы видеть скрытое содержание Зарегистрируйтесь на форуме!
Чтобы видеть скрытое содержание Зарегистрируйтесь на форуме!

Обычная настройка
1. Перед тем, как приступить к написанию основного кода системы, нам необходимо объявить некоторые макросы,
которые будут способствовать удобству в нашей дальнейшей работе.
PHP:
/*
Общие настройки, касающиеся анти-чита
*/
#define AC_MAX_CODES 53 // Количество кодов анти-чита (на данный момент их 53)
#define AC_MAX_CODE_LENGTH (3 + 1) // Максимальное количество символов в "коде" анти-чита (001/002/003, etc.)
#define AC_MAX_CODE_NAME_LENGTH (33 + 1) // Максимальное количество символов в полном названии чита, за который отвечает какой-либо код

#define AC_MAX_TRIGGER_TYPES 3 // Количество типов срабатываний (наказаний) анти-чита. По мере добавления типов срабатываний (наказаний), увеличивайте данное значение.
#define AC_MAX_TRIGGER_TYPE_NAME_LENGTH (8 + 1) // Максимальное количество символов в названии типа срабатывания (наказания) анти-чита

#define AC_GLOBAL_TRIGGER_TYPE_PLAYER 0
#define AC_GLOBAL_TRIGGER_TYPE_IP 1

// Типы срабатываний объявлены макросами, чтобы было проще ориентироваться в OnCheatDetected.
#define AC_CODE_TRIGGER_TYPE_DISABLED 0 // AC_CODE_TRIGGER_TYPE_DISABLED - Тип наказания: Отключён
#define AC_CODE_TRIGGER_TYPE_WARNING 1 // AC_CODE_TRIGGER_TYPE_WARNING - Тип наказания: Warning
#define AC_CODE_TRIGGER_TYPE_KICK 2 // AC_CODE_TRIGGER_TYPE_KICK - Тип наказания: Kick

#define AC_TRIGGER_ANTIFLOOD_TIME 20 // Время для анти-флуда срабатываниями (в секундах)

/*
Настройки визуальной части системы (диалогов)
*/
#define AC_MAX_CODES_ON_PAGE 15 // Максимальное количество элементов на странице настроек анти-чита
#define AC_DIALOG_NEXT_PAGE_TEXT ">>> Следующая страница" // Текст кнопки, которая будет отображать следующую страницу списка
#define AC_DIALOG_PREVIOUS_PAGE_TEXT "<<< Предыдущая страница" // Текст кнопки, которая будет отображать предыдущую страницу списка

#define DIALOG_ANTICHEAT_SETTINGS /*ID свободного диалога для главного меню анти-чита*/
#define DIALOG_ANTICHEAT_EDIT_CODE /*ID свободного диалога для меню настройки срабатывания определённого кода анти-чита*/
Чтобы видеть скрытое содержание Зарегистрируйтесь на форуме!
2. После того, как мы объявили нужные нам макросы, - переходим к объявлению некоторых констант и переменных нашей системы.
PHP:
// Массив AC_CODE хранит в себе текстовые форматы номеров кода анти-чита
static const AC_CODE[AC_MAX_CODES][AC_MAX_CODE_LENGTH] =
{
"000",
"001",
"002",
"003",
"004",
"005",
"006",
"007",
"008",
"009",
"010",
"011",
"012",
"013",
"014",
"015",
"016",
"017",
"018",
"019",
"020",
"021",
"022",
"023",
"024",
"025",
"026",
"027",
"028",
"029",
"030",
"031",
"032",
"033",
"034",
"035",
"036",
"037",
"038",
"039",
"040",
"041",
"042",
"043",
"044",
"045",
"046",
"047",
"048",
"049",
"050",
"051",
"052"
};

// Массив AC_CODE_NAME хранит в себе названия читов, которые соответствуют кодам анти-чита
static const AC_CODE_NAME[AC_MAX_CODES][AC_MAX_CODE_NAME_LENGTH] =
{
{"AirBreak (onfoot)"},
{"AirBreak (in vehicle)"},
{"Teleport (onfoot)"},
{"Teleport (in vehicle)"},
{"Teleport (into/between vehicles)"},
{"Teleport (vehicle to player)"},
{"Teleport (pickups)"},
{"FlyHack (onfoot)"},
{"FlyHack (in vehicle)"},
{"SpeedHack (onfoot)"},
{"SpeedHack (in vehicle)"},
{"Health hack (in vehicle)"},
{"Health hack (onfoot)"},
{"Armour hack"},
{"Money hack"},
{"Weapon hack"},
{"Ammo hack (add)"},
{"Ammo hack (infinite)"},
{"Special actions hack"},
{"GodMode from bullets (onfoot)"},
{"GodMode from bullets (in vehicle)"},
{"Invisible hack"},
{"Lagcomp-spoof"},
{"Tuning hack"},
{"Parkour mod"},
{"Quick turn"},
{"Rapid fire"},
{"FakeSpawn"},
{"FakeKill"},
{"Pro Aim"},
{"CJ run"},
{"CarShot"},
{"CarJack"},
{"UnFreeze"},
{"AFK Ghost"},
{"Full Aiming"},
{"Fake NPC"},
{"Reconnect"},
{"High ping"},
{"Dialog hack"},
{"Sandbox"},
{"Invalid version"},
{"Rcon hack"},
{"Tuning crasher"},
{"Invalid seat crasher"},
{"Dialog crasher"},
{"Attached object crasher"},
{"Weapon Crasher"},
{"Connects to one slot"},
{"Flood callback functions"},
{"Flood change seat"},
{"DDos"},
{"NOP's"}
};

// Массив AC_TRIGGER_TYPE_NAME хранит в себе названия типов срабатываний (наказаний) анти-чита.
static const AC_TRIGGER_TYPE_NAME[AC_MAX_TRIGGER_TYPES][AC_MAX_TRIGGER_TYPE_NAME_LENGTH] =
{
{"Отключён"},
{"Warning"},
{"Kick"}
};

// Массив AC_CODE_TRIGGER_TYPE хранит в себе наказания каждого кода анти-чита по умолчанию, которые будут заданы при запуске сервера.
new AC_CODE_TRIGGER_TYPE[AC_MAX_CODES] =
{
AC_CODE_TRIGGER_TYPE_WARNING, // Airbreak (onfoot)
AC_CODE_TRIGGER_TYPE_WARNING, // Airbreak (in vehicle)
AC_CODE_TRIGGER_TYPE_WARNING, // Teleport (onfoot)
AC_CODE_TRIGGER_TYPE_WARNING, // Teleport (in vehicle)
AC_CODE_TRIGGER_TYPE_WARNING, // Teleport (into/between vehicles)
AC_CODE_TRIGGER_TYPE_WARNING, // Teleport (vehicle to player)
AC_CODE_TRIGGER_TYPE_WARNING, // Teleport (pickups)
AC_CODE_TRIGGER_TYPE_WARNING, // FlyHack (onfoot)
AC_CODE_TRIGGER_TYPE_WARNING, // FlyHack (in vehicle)
AC_CODE_TRIGGER_TYPE_WARNING, // SpeedHack (onfoot)
AC_CODE_TRIGGER_TYPE_WARNING, // SpeedHack (in vehicle)
AC_CODE_TRIGGER_TYPE_KICK, // Health hack (in vehicle)
AC_CODE_TRIGGER_TYPE_KICK, // Health hack (onfoot)
AC_CODE_TRIGGER_TYPE_KICK, // Armour hack
AC_CODE_TRIGGER_TYPE_KICK, // Money hack
AC_CODE_TRIGGER_TYPE_KICK, // Weapon hack
AC_CODE_TRIGGER_TYPE_KICK, // Ammo hack (add)
AC_CODE_TRIGGER_TYPE_KICK, // Ammo hack (infinite)
AC_CODE_TRIGGER_TYPE_KICK, // Special actions hack
AC_CODE_TRIGGER_TYPE_WARNING, // GodMode from bullets (onfoot)
AC_CODE_TRIGGER_TYPE_WARNING, // GodMode from bullets (in vehicle)
AC_CODE_TRIGGER_TYPE_KICK, // Invisible hack
AC_CODE_TRIGGER_TYPE_KICK, // Lagcomp-spoof
AC_CODE_TRIGGER_TYPE_KICK, // Tuning hack
AC_CODE_TRIGGER_TYPE_WARNING, // Parkour mod
AC_CODE_TRIGGER_TYPE_KICK, // Quick turn
AC_CODE_TRIGGER_TYPE_KICK, // Rapid fire
AC_CODE_TRIGGER_TYPE_KICK, // FakeSpawn
AC_CODE_TRIGGER_TYPE_KICK, // FakeKill
AC_CODE_TRIGGER_TYPE_WARNING, // Pro Aim
AC_CODE_TRIGGER_TYPE_WARNING, // CJ run
AC_CODE_TRIGGER_TYPE_WARNING, // CarShot
AC_CODE_TRIGGER_TYPE_WARNING, // CarJack
AC_CODE_TRIGGER_TYPE_KICK, // UnFreeze
AC_CODE_TRIGGER_TYPE_WARNING, // AFK Ghost
AC_CODE_TRIGGER_TYPE_WARNING, // Full Aiming
AC_CODE_TRIGGER_TYPE_KICK, // Fake NPC
AC_CODE_TRIGGER_TYPE_KICK, // Reconnect
AC_CODE_TRIGGER_TYPE_WARNING, // High Ping
AC_CODE_TRIGGER_TYPE_KICK, // Dialog Hack
AC_CODE_TRIGGER_TYPE_KICK, // Sandbox
AC_CODE_TRIGGER_TYPE_KICK, // Invalid Version
AC_CODE_TRIGGER_TYPE_KICK, // Rcon hack
AC_CODE_TRIGGER_TYPE_KICK, // Tuning crasher
AC_CODE_TRIGGER_TYPE_KICK, // Invalid seat crasher
AC_CODE_TRIGGER_TYPE_KICK, // Dialog crasher
AC_CODE_TRIGGER_TYPE_KICK, // Attached object crasher
AC_CODE_TRIGGER_TYPE_KICK, // Weapon crasher
AC_CODE_TRIGGER_TYPE_KICK, // Connects to one slot
AC_CODE_TRIGGER_TYPE_KICK, // Flood callback functions
AC_CODE_TRIGGER_TYPE_KICK, // Flood change seat
AC_CODE_TRIGGER_TYPE_KICK, // DDos
AC_CODE_TRIGGER_TYPE_KICK // NOP`s
};
new
AC_CODE_TRIGGERED_COUNT[AC_MAX_CODES] = {0, ...}; // Массив, хранящий количество срабатываний того или иного кода анти-чита на протяжении текущей сессии

new
pAntiCheatLastCodeTriggerTime[MAX_PLAYERS][AC_MAX_CODES], // Массив, хранящий последнее время срабатывания каждого кода анти-чита на игрока
pAntiCheatSettingsPage[MAX_PLAYERS char], // Массив, хранящий номер страницы настроек, на которой сейчас находится игрок
pAntiCheatSettingsMenuListData[MAX_PLAYERS][AC_MAX_CODES_ON_PAGE], // Массив, хранящий в себе идентификаторы (ID) отображённых анти-читов на текущей странице, при их настройке в диалоге
pAntiCheatSettingsEditCodeId[MAX_PLAYERS]; // Массив, хранящий номер кода анти-чита, который редактируется игроком
3. Объявив все макросы, константы и переменные, мы переходим к самому функционалу данной системы.
Первым делом, при подключении игрока к серверу, нужно обнулить и задать некоторые значения нашим переменным:
PHP:
public OnPlayerConnect(playerid)
{
/*
В цикле присвамваем значение -1 каждой ячейке массива, которая отвечает за
время последнего срабатывания каждого кода анти-чита на игрока
*/
for(new i = 0; i < AC_MAX_CODES; i++)
pAntiCheatLastCodeTriggerTime[playerid][i] = -1;

pAntiCheatSettingsPage{playerid} = 0; // Присваиваем значение 0 переменной, хранящей номер страницы настроек анти-чита, на которой находится игрок
pAntiCheatSettingsEditCodeId[playerid] = -1; // Присваиваем переменной, хранящей идентификатор (ID) кода анти-чита, который редактирует игрок, занчение -1
return 1;
}
4. Нам необходимо добавить функцию OnCheatDetected, которая срабатывает при использовании игроком читов (софта)
PHP:
forward OnCheatDetected(playerid, const ip_address[], type, code);
public OnCheatDetected(playerid, const ip_address[], type, code)
{
if(type == AC_GLOBAL_TRIGGER_TYPE_PLAYER)
{
switch(code)
{
case 5, 6, 11, 22:
{
return 1;
}
case 32: // CarJack
{
new
Float:x,
Float:y,
Float:z;

AntiCheatGetPos(playerid, x, y, z);
return SetPlayerPos(playerid, x, y, z);
}
case 40: // Sandbox
{
SendClientMessage(playerid, -1, MAX_CONNECTS_MSG);
return AntiCheatKickWithDesync(playerid, code);
}
case 41: // Invalid Version
{
SendClientMessage(playerid, -1, UNKNOWN_CLIENT_MSG);
return AntiCheatKickWithDesync(playerid, code);
}
default:
{
if(gettime() - pAntiCheatLastCodeTriggerTime[playerid][code] < AC_TRIGGER_ANTIFLOOD_TIME)
return 1;

pAntiCheatLastCodeTriggerTime[playerid][code] = gettime();
AC_CODE_TRIGGERED_COUNT[code]++;

new
string[88 - 10 + MAX_PLAYER_NAME + 5 + AC_MAX_CODE_NAME_LENGTH + AC_MAX_CODE_LENGTH],
trigger_type = AC_CODE_TRIGGER_TYPE[code];

if(trigger_type == AC_CODE_TRIGGER_TYPE_WARNING)
{
format(string, sizeof(string), "<AC> %s[%d] подозревается в использовании чит-программ: %s [code: %03d].", /*NickName*/, playerid, AC_CODE_NAME[code], code);
/*Отправка сообщения администрации. Пример: SendAdminMessage(-1, string);*/
}
else // AC_CODE_TRIGGER_TYPE_KICK
{
format(string, sizeof(string), "<AC-KICK> %s[%d] был кикнут по подозрению в использовании чит-программ: %s [code: %03d].", /*NickName*/, playerid, AC_CODE_NAME[code], code);
/*Отправка сообщения администрации. Пример: SendAdminMessage(-1, string);*/

format(string, sizeof(string), "Вы были кикнуты по подозрению в использовании чит-программ: %s [code: %03d].", AC_CODE_NAME[code], code);
SendClientMessage(playerid, -1, string);

AntiCheatKickWithDesync(playerid, code);
}
}
}
}
else // AC_GLOBAL_TRIGGER_TYPE_IP
{
AC_CODE_TRIGGERED_COUNT[code]++;

new
string[58 - 8 + 16 + AC_MAX_CODE_NAME_LENGTH + AC_MAX_CODE_LENGTH];

format(string, sizeof(string), "<AC-BAN-IP> IP-адрес %s был заблокирован: %s [code: %03d].", ip_address, AC_CODE_NAME[code], code);
/*Отправка сообщения администрации. Пример: SendAdminMessage(-1, string);*/

BlockIpAddress(ip_address, 0);
}
return 1;
}
5. Добавляем команду, функцию показа главного диалога настроек и функцию показа настройки определённого кода анти-чита:
* Функции комментироваться не будут, так как там только форматирование и показ диалога, с которым, ни у кого проблем возникнуть не должно.
PHP:
CMD:anticheat_settings(playerid, params[])
{
pAntiCheatSettingsPage{playerid} = 1; // Присваиваем переменной, хранящей номер страницы, на который находится игрок, значение 1 (т.е, теперь игрок на 1-ой странице)
return ShowPlayer_AntiCheatSettings(playerid); // Показываем игрок главный диалог настроек анти-чита
}

// Функция показа главного меню настроек анти-чита
stock ShowPlayer_AntiCheatSettings(playerid)
{
static
dialog_string[42 + 19 - 8 + (AC_MAX_CODE_LENGTH + AC_MAX_CODE_NAME_LENGTH + AC_MAX_TRIGGER_TYPE_NAME_LENGTH + 10)*AC_MAX_CODES_ON_PAGE] = EOS;

new
triggeredCount = 0,
page = pAntiCheatSettingsPage{playerid},
next = 0,
index = 0;

dialog_string = "Название\tНаказание\tКол-во срабатываний\n";

for(new i = 0; i < AC_MAX_CODES; i++)
{
if(i >= (page * AC_MAX_CODES_ON_PAGE) && i < (page * AC_MAX_CODES_ON_PAGE) + AC_MAX_CODES_ON_PAGE)
next++;

if(i >= (page - 1) * AC_MAX_CODES_ON_PAGE && i < ((page - 1) * AC_MAX_CODES_ON_PAGE) + AC_MAX_CODES_ON_PAGE)
{
triggeredCount = AC_CODE_TRIGGERED_COUNT[i];

format(dialog_string, sizeof(dialog_string), "%s[%s] %s\t%s\t%d\n",
dialog_string,
AC_CODE[i],
AC_CODE_NAME[i],
AC_TRIGGER_TYPE_NAME[AC_CODE_TRIGGER_TYPE[i]],
triggeredCount);

pAntiCheatSettingsMenuListData[playerid][index++] = i;
}
}

if(next)
strcat(dialog_string, ""AC_DIALOG_NEXT_PAGE_TEXT"\n");

if(page > 1)
strcat(dialog_string, AC_DIALOG_PREVIOUS_PAGE_TEXT);

return ShowPlayerDialog(playerid, DIALOG_ANTICHEAT_SETTINGS, DIALOG_STYLE_TABLIST_HEADERS, !"Настройки анти-чита", dialog_string, !"Выбрать", !"Отмена");
}

// Функция показа меню редактирования типа срабатывания определённого кода в анти-чите
stock ShowPlayer_AntiCheatEditCode(playerid, code)
{
new
dialog_header[22 - 4 + AC_MAX_CODE_LENGTH + AC_MAX_CODE_NAME_LENGTH],
dialog_string[AC_MAX_TRIGGER_TYPE_NAME_LENGTH*AC_MAX_TRIGGER_TYPES];

format(dialog_header, sizeof(dialog_header), "Код: %s | Название: %s", AC_CODE[code], AC_CODE_NAME[code]);

for(new i = 0; i < AC_MAX_TRIGGER_TYPES; i++)
{
strcat(dialog_string, AC_TRIGGER_TYPE_NAME[i]);

if(i + 1 != AC_MAX_TRIGGER_TYPES)
strcat(dialog_string, "\n");
}

return ShowPlayerDialog(playerid, DIALOG_ANTICHEAT_EDIT_CODE, DIALOG_STYLE_LIST, dialog_header, dialog_string, !"Выбрать", !"Назад");
}
6. Последний штрих - OnDialogResponse (обработка диалогов).
PHP:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
switch(dialogid)
{
case DIALOG_ANTICHEAT_SETTINGS: // Главное меню настроект анти-чита
{
if(!response) // Если игрок закрыл диалог
{
pAntiCheatSettingsPage{playerid} = 0; // Присваиваем значение 0 переменной, хранящей номер страницы настроек анти-чита, на которой находится игрок
return 1; // Закрываем диалог
}

if(!strcmp(inputtext, AC_DIALOG_NEXT_PAGE_TEXT)) // Если игрок нажал на кнопку перелистывания на следующую страницу
{
pAntiCheatSettingsPage{playerid}++; // Инкрементируем (прибавляем 1) значение переменной, хранящей номер страницы настроек анти-чита, на которой находится игрок
}
else if(!strcmp(inputtext, AC_DIALOG_PREVIOUS_PAGE_TEXT)) // Если игрок нажал на кнопку перелистывания на предыдущую страницу
{
pAntiCheatSettingsPage{playerid}--; // Декрементируем (убавляем 1) значение переменной, хранящей номер страницы настроек анти-чита, на которой находится игрок
}
else // Если игрко выбрал какой-либо из кодов анти-чита
{
pAntiCheatSettingsEditCodeId[playerid] = pAntiCheatSettingsMenuListData[playerid][listitem]; // Присваиваем переменной, хранящей номер кода анти-чита, который редактирует игрок, номер кода, который он выбрал
return ShowPlayer_AntiCheatEditCode(playerid, pAntiCheatSettingsEditCodeId[playerid]); // Показываем игроку диалог настройки кода анти-чита
}
return ShowPlayer_AntiCheatSettings(playerid); // Относится к выбору следующей и предыдущей страницы. Заново показываем игроку главное меню настройки анти-чита.
}
case DIALOG_ANTICHEAT_EDIT_CODE: // Меню настройки определённого кода анти-чита
{
if(!response) // Если игрок закрыл диалог
{
pAntiCheatSettingsEditCodeId[playerid] = -1; // Присваиваем переменной, хранящей идентификатор (ID) кода анти-чита, который редактирует игрок, занчение -1
return ShowPlayer_AntiCheatSettings(playerid); // Показываем игроку главное меню настроек анти-чита
}

new
item = pAntiCheatSettingsEditCodeId[playerid]; // Создаём локальную переменную item, которая примет значение кода анти-чита, который редактирует игрок

if(AC_CODE_TRIGGER_TYPE[item] == listitem) // Если игрок пытается присвоить коду уже присвоенный ему тип срабатывания
return ShowPlayer_AntiCheatSettings(playerid); // Показываем главное меню настроек анти-чита

AC_CODE_TRIGGER_TYPE[item] = listitem; // Если же игрок выбрал другой тип срабатывания - присваиваем его переменной
return ShowPlayer_AntiCheatSettings(playerid); // Показываем главное меню настроек анти-чита
}
}
return 1;
}

Динамическая настройка с сохранением (MySQL)
1. Создаём таблицу в базе данных.
Так как название таблицы и её поля задаются внутри кода (см. пункт 2) - Вам необходимо создать в базе данных таблицу с тем названием,
которое Вы укажете в макросе AC_TABLE_SETTINGS, а так же названия двух столбцов соответственно AC_TABLE_FIELD_CODE, AC_TABLE_FIELD_TRIGGER.

Пример создания таблицы (под спойлером):
1. Создаём таблицу:
* Обратите внимание, что столбцов всего 2:
Чтобы видеть скрытое содержание Зарегистрируйтесь на форуме!

2. Настраиваем столбцы:
* Обратите внимание, что столбец, отвечающий за идентификатор кода анти-чита, должен иметь уникальный индекс (UNIQUE).
Чтобы видеть скрытое содержание Зарегистрируйтесь на форуме!

3. Финальная структура таблицы:
* Обратите внимание: подобным образом должна выглядеть финальная структура таблицы.
Чтобы видеть скрытое содержание Зарегистрируйтесь на форуме!
2. Перед тем, как приступить к написанию основного кода системы, нам необходимо объявить некоторые макросы,
которые будут способствовать удобству в нашей дальнейшей работе.
PHP:
/*
Настройки, связанные с базой данных (MySQL)
*/
#define AC_TABLE_SETTINGS "anticheat_settings" // Название таблицы в базе данных с настройками анти-чита
#define AC_TABLE_FIELD_CODE "ac_code" // Название поля с кодом анти-чита в таблице
#define AC_TABLE_FIELD_TRIGGER "ac_code_trigger_type" // Название поля со значением срабатывания кода анти-чита в таблице

/*
Общие настройки, касающиеся анти-чита
*/
#define AC_MAX_CODES 53 // Количество кодов анти-чита (на данный момент их 53)
#define AC_MAX_CODE_LENGTH (3 + 1) // Максимальное количество символов в "коде" анти-чита (001/002/003, etc.)
#define AC_MAX_CODE_NAME_LENGTH (33 + 1) // Максимальное количество символов в полном названии чита, за который отвечает какой-либо код

#define AC_MAX_TRIGGER_TYPES 3 // Количество типов срабатываний (наказаний) анти-чита. По мере добавления типов срабатываний (наказаний), увеличивайте данное значение.
#define AC_MAX_TRIGGER_TYPE_NAME_LENGTH (8 + 1) // Максимальное количество символов в названии типа срабатывания (наказания) анти-чита

#define AC_GLOBAL_TRIGGER_TYPE_PLAYER 0
#define AC_GLOBAL_TRIGGER_TYPE_IP 1

// Типы срабатываний объявлены макросами, чтобы было проще ориентироваться в OnCheatDetected.
#define AC_CODE_TRIGGER_TYPE_DISABLED 0 // AC_CODE_TRIGGER_TYPE_DISABLED - Тип наказания: Отключён
#define AC_CODE_TRIGGER_TYPE_WARNING 1 // AC_CODE_TRIGGER_TYPE_WARNING - Тип наказания: Warning
#define AC_CODE_TRIGGER_TYPE_KICK 2 // AC_CODE_TRIGGER_TYPE_KICK - Тип наказания: Kick

#define AC_TRIGGER_ANTIFLOOD_TIME 20 // Время для анти-флуда срабатываниями (в секундах)

/*
Настройки визуальной части системы (диалогов)
*/
#define AC_MAX_CODES_ON_PAGE 15 // Максимальное количество элементов на странице настроек анти-чита
#define AC_DIALOG_NEXT_PAGE_TEXT ">>> Следующая страница" // Текст кнопки, которая будет отображать следующую страницу списка
#define AC_DIALOG_PREVIOUS_PAGE_TEXT "<<< Предыдущая страница" // Текст кнопки, которая будет отображать предыдущую страницу списка

#define DIALOG_ANTICHEAT_SETTINGS /*ID свободного диалога для главного меню анти-чита*/
#define DIALOG_ANTICHEAT_EDIT_CODE /*ID свободного диалога для меню настройки срабатывания определённого кода анти-чита*/
Чтобы видеть скрытое содержание Зарегистрируйтесь на форуме!
3. После того, как мы объявили нужные нам макросы, - переходим к объявлению некоторых констант и переменных нашей системы.
PHP:
// Массив AC_CODE хранит в себе текстовые форматы номеров кода анти-чита
static const AC_CODE[AC_MAX_CODES][AC_MAX_CODE_LENGTH] =
{
"000",
"001",
"002",
"003",
"004",
"005",
"006",
"007",
"008",
"009",
"010",
"011",
"012",
"013",
"014",
"015",
"016",
"017",
"018",
"019",
"020",
"021",
"022",
"023",
"024",
"025",
"026",
"027",
"028",
"029",
"030",
"031",
"032",
"033",
"034",
"035",
"036",
"037",
"038",
"039",
"040",
"041",
"042",
"043",
"044",
"045",
"046",
"047",
"048",
"049",
"050",
"051",
"052"
};

// Массив AC_CODE_NAME хранит в себе названия читов, которые соответствуют кодам анти-чита
static const AC_CODE_NAME[AC_MAX_CODES][AC_MAX_CODE_NAME_LENGTH] =
{
{"AirBreak (onfoot)"},
{"AirBreak (in vehicle)"},
{"Teleport (onfoot)"},
{"Teleport (in vehicle)"},
{"Teleport (into/between vehicles)"},
{"Teleport (vehicle to player)"},
{"Teleport (pickups)"},
{"FlyHack (onfoot)"},
{"FlyHack (in vehicle)"},
{"SpeedHack (onfoot)"},
{"SpeedHack (in vehicle)"},
{"Health hack (in vehicle)"},
{"Health hack (onfoot)"},
{"Armour hack"},
{"Money hack"},
{"Weapon hack"},
{"Ammo hack (add)"},
{"Ammo hack (infinite)"},
{"Special actions hack"},
{"GodMode from bullets (onfoot)"},
{"GodMode from bullets (in vehicle)"},
{"Invisible hack"},
{"Lagcomp-spoof"},
{"Tuning hack"},
{"Parkour mod"},
{"Quick turn"},
{"Rapid fire"},
{"FakeSpawn"},
{"FakeKill"},
{"Pro Aim"},
{"CJ run"},
{"CarShot"},
{"CarJack"},
{"UnFreeze"},
{"AFK Ghost"},
{"Full Aiming"},
{"Fake NPC"},
{"Reconnect"},
{"High ping"},
{"Dialog hack"},
{"Sandbox"},
{"Invalid version"},
{"Rcon hack"},
{"Tuning crasher"},
{"Invalid seat crasher"},
{"Dialog crasher"},
{"Attached object crasher"},
{"Weapon Crasher"},
{"Connects to one slot"},
{"Flood callback functions"},
{"Flood change seat"},
{"DDos"},
{"NOP's"}
};

// Массив AC_TRIGGER_TYPE_NAME хранит в себе названия типов срабатываний (наказаний) анти-чита.
static const AC_TRIGGER_TYPE_NAME[AC_MAX_TRIGGER_TYPES][AC_MAX_TRIGGER_TYPE_NAME_LENGTH] =
{
{"Отключён"},
{"Warning"},
{"Kick"}
};

new
AC_CODE_TRIGGER_TYPE[AC_MAX_CODES], // Массив AC_CODE_TRIGGER_TYPE хранит в себе наказания каждого кода анти-чита, которые мы загрузим из базы данных.
AC_CODE_TRIGGERED_COUNT[AC_MAX_CODES] = {0, ...}; // Массив, хранящий количество срабатываний того или иного кода анти-чита на протяжении текущей сессии

new
pAntiCheatLastCodeTriggerTime[MAX_PLAYERS][AC_MAX_CODES], // Массив, хранящий последнее время срабатывания каждого кода анти-чита на игрока
pAntiCheatSettingsPage[MAX_PLAYERS char], // Массив, хранящий номер страницы настроек, на которой сейчас находится игрок
pAntiCheatSettingsMenuListData[MAX_PLAYERS][AC_MAX_CODES_ON_PAGE], // Массив, хранящий в себе идентификаторы (ID) отображённых анти-читов на текущей странице, при их настройке в диалоге
pAntiCheatSettingsEditCodeId[MAX_PLAYERS]; // Массив, хранящий номер кода анти-чита, который редактируется игроком
4. Нам необходимо загрузить данные из базы данных, что мы, собственно, и сделаем.
Функцию ниже необходимо добавить в OnGameModeInit().
PHP:
// Функция загрузки данных о настройках кодов анти-чита из базы данных
stock UploadAntiCheatSettings()
{
new
Cache:cache = mysql_query(/*ID подключения к MySQL*/, "SELECT * FROM "AC_TABLE_SETTINGS" ORDER BY "AC_TABLE_FIELD_CODE"", true),
rows = 0,
tick = GetTickCount();

cache_get_row_count(rows);

if(rows > 0)
{
for(new i = 0; i < AC_MAX_CODES; i++)
{
cache_get_value_name_int(i, ""AC_TABLE_FIELD_TRIGGER"", AC_CODE_TRIGGER_TYPE[i]);

if(AC_CODE_TRIGGER_TYPE[i] == AC_CODE_TRIGGER_TYPE_DISABLED)
EnableAntiCheat(i, 0);
}

printf("[MySQL]: Настройки анти-чита успешно загружены (загружено: %d). Потрачено: %dмс.", rows, GetTickCount() - tick);
}
else
{
print("[MySQL]: Настройки анти-чита не найдены в базе данных. Загрузка мода остановлена - настройте анти-чит.");
return GameModeExit();
}

cache_delete(cache);
return 1;
}

// Пример
public OnGameModeInit()
{
// Используем функцию загрузку данных из нашей базы данных
UploadAntiCheatSettings();
return 1;
}
PHP:
// Функция загрузки данных о настройках кодов анти-чита из базы данных
stock UploadAntiCheatSettings()
{
new
Cache:cache = mysql_query(/*ID подключения к MySQL*/, "SELECT * FROM "AC_TABLE_SETTINGS" ORDER BY "AC_TABLE_FIELD_CODE""),
rows,
fields,
tick = GetTickCount();

cache_get_data(rows, fields);

if(rows > 0)
{
for(new i = 0; i < AC_MAX_CODES; i++)
{
AC_CODE_TRIGGER_TYPE[i] = cache_get_field_content_int(i, ""AC_TABLE_FIELD_TRIGGER"");

if(AC_CODE_TRIGGER_TYPE[i] == AC_CODE_TRIGGER_TYPE_DISABLED)
EnableAntiCheat(i, 0);
}

printf("[MySQL]: Настройки анти-чита успешно загружены (загружено: %d). Потрачено: %dмс.", rows, GetTickCount() - tick);
}
else
{
print("[MySQL]: Настройки анти-чита не найдены в базе данных. Загрузка мода остановлена - настройте анти-чит.");
return GameModeExit();
}

cache_delete(cache);
return 1;
}

// Пример
public OnGameModeInit()
{
// Используем функцию загрузку данных из нашей базы данных
UploadAntiCheatSettings();
return 1;
}
5. Объявив все макросы, константы и переменные, мы переходим к самому функционалу данной системы.
Первым делом, при подключении игрока к серверу, нужно обнулить и задать некоторые значения нашим переменным:
PHP:
public OnPlayerConnect(playerid)
{
/*
В цикле присвамваем значение -1 каждой ячейке массива, которая отвечает за
время последнего срабатывания каждого кода анти-чита на игрока
*/
for(new i = 0; i < AC_MAX_CODES; i++)
pAntiCheatLastCodeTriggerTime[playerid][i] = -1;

pAntiCheatSettingsPage{playerid} = 0; // Присваиваем значение 0 переменной, хранящей номер страницы настроек анти-чита, на которой находится игрок
pAntiCheatSettingsEditCodeId[playerid] = -1; // Присваиваем переменной, хранящей идентификатор (ID) кода анти-чита, который редактирует игрок, занчение -1
return 1;
}
6. Нам необходимо добавить функцию OnCheatDetected, которая срабатывает при использовании игроком читов (софта)
PHP:
forward OnCheatDetected(playerid, const ip_address[], type, code);
public OnCheatDetected(playerid, const ip_address[], type, code)
{
if(type == AC_GLOBAL_TRIGGER_TYPE_PLAYER)
{
switch(code)
{
case 5, 6, 11, 22:
{
return 1;
}
case 32: // CarJack
{
new
Float:x,
Float:y,
Float:z;

AntiCheatGetPos(playerid, x, y, z);
return SetPlayerPos(playerid, x, y, z);
}
case 40: // Sandbox
{
SendClientMessage(playerid, -1, MAX_CONNECTS_MSG);
return AntiCheatKickWithDesync(playerid, code);
}
case 41: // Invalid Version
{
SendClientMessage(playerid, -1, UNKNOWN_CLIENT_MSG);
return AntiCheatKickWithDesync(playerid, code);
}
default:
{
if(gettime() - pAntiCheatLastCodeTriggerTime[playerid][code] < AC_TRIGGER_ANTIFLOOD_TIME)
return 1;

pAntiCheatLastCodeTriggerTime[playerid][code] = gettime();
AC_CODE_TRIGGERED_COUNT[code]++;

new
string[88 - 10 + MAX_PLAYER_NAME + 5 + AC_MAX_CODE_NAME_LENGTH + AC_MAX_CODE_LENGTH],
trigger_type = AC_CODE_TRIGGER_TYPE[code];

if(trigger_type == AC_CODE_TRIGGER_TYPE_WARNING)
{
format(string, sizeof(string), "<AC> %s[%d] подозревается в использовании чит-программ: %s [code: %03d].", /*NickName*/, playerid, AC_CODE_NAME[code], code);
/*Отправка сообщения администрации. Пример: SendAdminMessage(-1, string);*/
}
else // AC_CODE_TRIGGER_TYPE_KICK
{
format(string, sizeof(string), "<AC-KICK> %s[%d] был кикнут по подозрению в использовании чит-программ: %s [code: %03d].", /*NickName*/, playerid, AC_CODE_NAME[code], code);
/*Отправка сообщения администрации. Пример: SendAdminMessage(-1, string);*/

format(string, sizeof(string), "Вы были кикнуты по подозрению в использовании чит-программ: %s [code: %03d].", AC_CODE_NAME[code], code);
SendClientMessage(playerid, -1, string);

AntiCheatKickWithDesync(playerid, code);
}
}
}
}
else // AC_GLOBAL_TRIGGER_TYPE_IP
{
AC_CODE_TRIGGERED_COUNT[code]++;

new
string[58 - 8 + 16 + AC_MAX_CODE_NAME_LENGTH + AC_MAX_CODE_LENGTH];

format(string, sizeof(string), "<AC-BAN-IP> IP-адрес %s был заблокирован: %s [code: %03d].", ip_address, AC_CODE_NAME[code], code);
/*Отправка сообщения администрации. Пример: SendAdminMessage(-1, string);*/

BlockIpAddress(ip_address, 0);
}
return 1;
}
7. Добавляем команду, функцию показа главного диалога настроек и функцию показа настройки определённого кода анти-чита:
* Функции комментироваться не будут, так как там только форматирование и показ диалога, с которым, ни у кого проблем возникнуть не должно.
PHP:
CMD:anticheat_settings(playerid, params[])
{
pAntiCheatSettingsPage{playerid} = 1; // Присваиваем переменной, хранящей номер страницы, на который находится игрок, значение 1 (т.е, теперь игрок на 1-ой странице)
return ShowPlayer_AntiCheatSettings(playerid); // Показываем игрок главный диалог настроек анти-чита
}

// Функция показа главного меню настроек анти-чита
stock ShowPlayer_AntiCheatSettings(playerid)
{
static
dialog_string[42 + 19 - 8 + (AC_MAX_CODE_LENGTH + AC_MAX_CODE_NAME_LENGTH + AC_MAX_TRIGGER_TYPE_NAME_LENGTH + 10)*AC_MAX_CODES_ON_PAGE] = EOS;

new
triggeredCount = 0,
page = pAntiCheatSettingsPage{playerid},
next = 0,
index = 0;

dialog_string = "Название\tНаказание\tКол-во срабатываний\n";

for(new i = 0; i < AC_MAX_CODES; i++)
{
if(i >= (page * AC_MAX_CODES_ON_PAGE) && i < (page * AC_MAX_CODES_ON_PAGE) + AC_MAX_CODES_ON_PAGE)
next++;

if(i >= (page - 1) * AC_MAX_CODES_ON_PAGE && i < ((page - 1) * AC_MAX_CODES_ON_PAGE) + AC_MAX_CODES_ON_PAGE)
{
triggeredCount = AC_CODE_TRIGGERED_COUNT[i];

format(dialog_string, sizeof(dialog_string), "%s[%s] %s\t%s\t%d\n",
dialog_string,
AC_CODE[i],
AC_CODE_NAME[i],
AC_TRIGGER_TYPE_NAME[AC_CODE_TRIGGER_TYPE[i]],
triggeredCount);

pAntiCheatSettingsMenuListData[playerid][index++] = i;
}
}

if(next)
strcat(dialog_string, ""AC_DIALOG_NEXT_PAGE_TEXT"\n");

if(page > 1)
strcat(dialog_string, AC_DIALOG_PREVIOUS_PAGE_TEXT);

return ShowPlayerDialog(playerid, DIALOG_ANTICHEAT_SETTINGS, DIALOG_STYLE_TABLIST_HEADERS, !"Настройки анти-чита", dialog_string, !"Выбрать", !"Отмена");
}

// Функция показа меню редактирования типа срабатывания определённого кода в анти-чите
stock ShowPlayer_AntiCheatEditCode(playerid, code)
{
new
dialog_header[22 - 4 + AC_MAX_CODE_LENGTH + AC_MAX_CODE_NAME_LENGTH],
dialog_string[AC_MAX_TRIGGER_TYPE_NAME_LENGTH*AC_MAX_TRIGGER_TYPES];

format(dialog_header, sizeof(dialog_header), "Код: %s | Название: %s", AC_CODE[code], AC_CODE_NAME[code]);

for(new i = 0; i < AC_MAX_TRIGGER_TYPES; i++)
{
strcat(dialog_string, AC_TRIGGER_TYPE_NAME[i]);

if(i + 1 != AC_MAX_TRIGGER_TYPES)
strcat(dialog_string, "\n");
}

return ShowPlayerDialog(playerid, DIALOG_ANTICHEAT_EDIT_CODE, DIALOG_STYLE_LIST, dialog_header, dialog_string, !"Выбрать", !"Назад");
}
8. Последний штрих - OnDialogResponse (обработка диалогов).
PHP:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
switch(dialogid)
{
case DIALOG_ANTICHEAT_SETTINGS: // Главное меню настроект анти-чита
{
if(!response) // Если игрок закрыл диалог
{
pAntiCheatSettingsPage{playerid} = 0; // Присваиваем значение 0 переменной, хранящей номер страницы настроек анти-чита, на которой находится игрок
return 1; // Закрываем диалог
}

if(!strcmp(inputtext, AC_DIALOG_NEXT_PAGE_TEXT)) // Если игрок нажал на кнопку перелистывания на следующую страницу
{
pAntiCheatSettingsPage{playerid}++; // Инкрементируем (прибавляем 1) значение переменной, хранящей номер страницы настроек анти-чита, на которой находится игрок
}
else if(!strcmp(inputtext, AC_DIALOG_PREVIOUS_PAGE_TEXT)) // Если игрок нажал на кнопку перелистывания на предыдущую страницу
{
pAntiCheatSettingsPage{playerid}--; // Декрементируем (убавляем 1) значение переменной, хранящей номер страницы настроек анти-чита, на которой находится игрок
}
else // Если игрко выбрал какой-либо из кодов анти-чита
{
pAntiCheatSettingsEditCodeId[playerid] = pAntiCheatSettingsMenuListData[playerid][listitem]; // Присваиваем переменной, хранящей номер кода анти-чита, который редактирует игрок, номер кода, который он выбрал
return ShowPlayer_AntiCheatEditCode(playerid, pAntiCheatSettingsEditCodeId[playerid]); // Показываем игроку диалог настройки кода анти-чита
}
return ShowPlayer_AntiCheatSettings(playerid); // Относится к выбору следующей и предыдущей страницы. Заново показываем игроку главное меню настройки анти-чита.
}
case DIALOG_ANTICHEAT_EDIT_CODE: // Меню настройки определённого кода анти-чита
{
if(!response) // Если игрок закрыл диалог
{
pAntiCheatSettingsEditCodeId[playerid] = -1; // Присваиваем переменной, хранящей идентификатор (ID) кода анти-чита, который редактирует игрок, занчение -1
return ShowPlayer_AntiCheatSettings(playerid); // Показываем игроку главное меню настроек анти-чита
}

new
item = pAntiCheatSettingsEditCodeId[playerid]; // Создаём локальную переменную item, которая примет значение кода анти-чита, который редактирует игрок

if(AC_CODE_TRIGGER_TYPE[item] == listitem) // Если игрок пытается присвоить коду уже присвоенный ему тип срабатывания
return ShowPlayer_AntiCheatSettings(playerid); // Показываем главное меню настроек анти-чита

if(AC_CODE_TRIGGER_TYPE[item] == AC_CODE_TRIGGER_TYPE_DISABLED && listitem != AC_CODE_TRIGGER_TYPE_DISABLED)
EnableAntiCheat(item, 1);

AC_CODE_TRIGGER_TYPE[item] = listitem; // Если же игрок выбрал другой тип срабатывания - присваиваем его переменной

new
sql_query[101 - 4 + 1 + 2];

// Форматируем запрос об обновлении данных указаного кода анти-чита в базу данных
format(sql_query, sizeof(sql_query), "UPDATE "AC_TABLE_SETTINGS" SET `"AC_TABLE_FIELD_TRIGGER"` = '%d' WHERE `"AC_TABLE_FIELD_CODE"` = '%d'",
listitem,
item);

mysql_tquery(/*ID подключения к MySQL*/, sql_query, "", ""); // Отправляем запрос в базу данных
return ShowPlayer_AntiCheatSettings(playerid); // Показываем главное меню настроек анти-чита
}
}
return 1;
}
PHP:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
switch(dialogid)
{
case DIALOG_ANTICHEAT_SETTINGS: // Главное меню настроект анти-чита
{
if(!response) // Если игрок закрыл диалог
{
pAntiCheatSettingsPage{playerid} = 0; // Присваиваем значение 0 переменной, хранящей номер страницы настроек анти-чита, на которой находится игрок
return 1; // Закрываем диалог
}

if(!strcmp(inputtext, AC_DIALOG_NEXT_PAGE_TEXT)) // Если игрок нажал на кнопку перелистывания на следующую страницу
{
pAntiCheatSettingsPage{playerid}++; // Инкрементируем (прибавляем 1) значение переменной, хранящей номер страницы настроек анти-чита, на которой находится игрок
}
else if(!strcmp(inputtext, AC_DIALOG_PREVIOUS_PAGE_TEXT)) // Если игрок нажал на кнопку перелистывания на предыдущую страницу
{
pAntiCheatSettingsPage{playerid}--; // Декрементируем (убавляем 1) значение переменной, хранящей номер страницы настроек анти-чита, на которой находится игрок
}
else // Если игрко выбрал какой-либо из кодов анти-чита
{
pAntiCheatSettingsEditCodeId[playerid] = pAntiCheatSettingsMenuListData[playerid][listitem]; // Присваиваем переменной, хранящей номер кода анти-чита, который редактирует игрок, номер кода, который он выбрал
return ShowPlayer_AntiCheatEditCode(playerid, pAntiCheatSettingsEditCodeId[playerid]); // Показываем игроку диалог настройки кода анти-чита
}
return ShowPlayer_AntiCheatSettings(playerid); // Относится к выбору следующей и предыдущей страницы. Заново показываем игроку главное меню настройки анти-чита.
}
case DIALOG_ANTICHEAT_EDIT_CODE: // Меню настройки определённого кода анти-чита
{
if(!response) // Если игрок закрыл диалог
{
pAntiCheatSettingsEditCodeId[playerid] = -1; // Присваиваем переменной, хранящей идентификатор (ID) кода анти-чита, который редактирует игрок, занчение -1
return ShowPlayer_AntiCheatSettings(playerid); // Показываем игроку главное меню настроек анти-чита
}

new
item = pAntiCheatSettingsEditCodeId[playerid]; // Создаём локальную переменную item, которая примет значение кода анти-чита, который редактирует игрок

if(AC_CODE_TRIGGER_TYPE[item] == listitem) // Если игрок пытается присвоить коду уже присвоенный ему тип срабатывания
return ShowPlayer_AntiCheatSettings(playerid); // Показываем главное меню настроек анти-чита

if(AC_CODE_TRIGGER_TYPE[item] == AC_CODE_TRIGGER_TYPE_DISABLED && listitem != AC_CODE_TRIGGER_TYPE_DISABLED)
EnableAntiCheat(item, 1);

AC_CODE_TRIGGER_TYPE[item] = listitem; // Если же игрок выбрал другой тип срабатывания - присваиваем его переменной

new
sql_query[101 - 4 + 1 + 2];

// Форматируем запрос об обновлении данных указаного кода анти-чита в базу данных
format(sql_query, sizeof(sql_query), "UPDATE "AC_TABLE_SETTINGS" SET `"AC_TABLE_FIELD_TRIGGER"` = '%d' WHERE `"AC_TABLE_FIELD_CODE"` = '%d'",
listitem,
item);

mysql_function_query(/*ID подключения к MySQL*/, sql_query, false, "", ""); // Отправляем запрос в базу данных
return ShowPlayer_AntiCheatSettings(playerid); // Показываем главное меню настроек анти-чита
}
}
return 1;
}


Настроенные коды анти-читов для базы данных в аттаче.


PHP:
AC_CODE_TRIGGER_TYPE_WARNING, // Airbreak (onfoot)
AC_CODE_TRIGGER_TYPE_WARNING, // Airbreak (in vehicle)
AC_CODE_TRIGGER_TYPE_WARNING, // Teleport (onfoot)
AC_CODE_TRIGGER_TYPE_WARNING, // Teleport (in vehicle)
AC_CODE_TRIGGER_TYPE_WARNING, // Teleport (into/between vehicles)
AC_CODE_TRIGGER_TYPE_WARNING, // Teleport (vehicle to player)
AC_CODE_TRIGGER_TYPE_WARNING, // Teleport (pickups)
AC_CODE_TRIGGER_TYPE_WARNING, // FlyHack (onfoot)
AC_CODE_TRIGGER_TYPE_WARNING, // FlyHack (in vehicle)
AC_CODE_TRIGGER_TYPE_WARNING, // SpeedHack (onfoot)
AC_CODE_TRIGGER_TYPE_WARNING, // SpeedHack (in vehicle)
AC_CODE_TRIGGER_TYPE_KICK, // Health hack (in vehicle)
AC_CODE_TRIGGER_TYPE_KICK, // Health hack (onfoot)
AC_CODE_TRIGGER_TYPE_KICK, // Armour hack
AC_CODE_TRIGGER_TYPE_KICK, // Money hack
AC_CODE_TRIGGER_TYPE_KICK, // Weapon hack
AC_CODE_TRIGGER_TYPE_KICK, // Ammo hack (add)
AC_CODE_TRIGGER_TYPE_KICK, // Ammo hack (infinite)
AC_CODE_TRIGGER_TYPE_KICK, // Special actions hack
AC_CODE_TRIGGER_TYPE_WARNING, // GodMode from bullets (onfoot)
AC_CODE_TRIGGER_TYPE_WARNING, // GodMode from bullets (in vehicle)
AC_CODE_TRIGGER_TYPE_KICK, // Invisible hack
AC_CODE_TRIGGER_TYPE_KICK, // Lagcomp-spoof
AC_CODE_TRIGGER_TYPE_KICK, // Tuning hack
AC_CODE_TRIGGER_TYPE_WARNING, // Parkour mod
AC_CODE_TRIGGER_TYPE_KICK, // Quick turn
AC_CODE_TRIGGER_TYPE_KICK, // Rapid fire
AC_CODE_TRIGGER_TYPE_KICK, // FakeSpawn
AC_CODE_TRIGGER_TYPE_KICK, // FakeKill
AC_CODE_TRIGGER_TYPE_WARNING, // Pro Aim
AC_CODE_TRIGGER_TYPE_WARNING, // CJ run
AC_CODE_TRIGGER_TYPE_WARNING, // CarShot
AC_CODE_TRIGGER_TYPE_WARNING, // CarJack
AC_CODE_TRIGGER_TYPE_KICK, // UnFreeze
AC_CODE_TRIGGER_TYPE_WARNING, // AFK Ghost
AC_CODE_TRIGGER_TYPE_WARNING, // Full Aiming
AC_CODE_TRIGGER_TYPE_KICK, // Fake NPC
AC_CODE_TRIGGER_TYPE_KICK, // Reconnect
AC_CODE_TRIGGER_TYPE_WARNING, // High Ping
AC_CODE_TRIGGER_TYPE_KICK, // Dialog Hack
AC_CODE_TRIGGER_TYPE_KICK, // Sandbox
AC_CODE_TRIGGER_TYPE_KICK, // Invalid Version
AC_CODE_TRIGGER_TYPE_KICK, // Rcon hack
AC_CODE_TRIGGER_TYPE_KICK, // Tuning crasher
AC_CODE_TRIGGER_TYPE_KICK, // Invalid seat crasher
AC_CODE_TRIGGER_TYPE_KICK, // Dialog crasher
AC_CODE_TRIGGER_TYPE_KICK, // Attached object crasher
AC_CODE_TRIGGER_TYPE_KICK, // Weapon crasher
AC_CODE_TRIGGER_TYPE_KICK, // Connects to one slot
AC_CODE_TRIGGER_TYPE_KICK, // Flood callback functions
AC_CODE_TRIGGER_TYPE_KICK, // Flood change seat
AC_CODE_TRIGGER_TYPE_KICK, // DDos
AC_CODE_TRIGGER_TYPE_KICK // NOP`s

* Примечание:
Да, большинство общих моментов можно было вынести за спойлер, но я решил не делать этого, дабы избежать множества лишних вопросов по типу: "а правильно ли я сделал?".
Каждый выберет себе свой вариант настройки, который ему нужен и будет следовать пунктам.

Если у Вас есть какие-либо вопросы - не стесняйтесь задавать их в комментариях.
 

Вложения

Последнее редактирование модератором:
Сверху Снизу