Sign in to follow this  
Followers 0

Принцип написания античитов. Написание античита на деньги для наглядности

3 posts in this topic

Cawfee
Великий Гуру

В предыдущем уроке я рассказал о том, как пользоваться перехватом функций. Также сказал, что перехваты функций применяются для того, чтобы можно было изменить поведение конкретной функции. Сегодня постараюсь объяснить принцип создания античита и для примера написать для вас античит на деньги.

 

Как работает античит? Рассмотрим такую ситуацию. При помощи запрещенных программных обеспечений Вы изменяете количество денег у своего игрока. Но спустя несколько секунд (а обычно даже секунду) это количество денег возвращается в прежнее состояние. Можно предположить, что существует какой-то таймер с интервалом, например, в секунду, внутри которого идет проверка: соответствует ли количество денег игрока сейчас тем цифрам, что были во время прежней проверки.

 

Итак, мы можем получить деньги игрока в данный момент при помощи функции GetPlayerMoney. А с чем нам сверять полученное количество средств? Следует создать новую переменную, в которую уже стоит заносить количество средств, которое должно быть у игрока. Следовательно, нам нужно перехватить функции, связанные с изменением денег, в которых уже производить изменения в значении переменной.

 

Далее, как я ранее упомянул, следует создать таймер, где уже производить проверку на то, пользуется ли игрок запрещенным программным обеспечением. На этом, в принципе, принцип написания античита завершен. Ровным счетом так же пишутся античиты на здоровье, броню, очки (уровень), телепортацию и многие други. То есть логика везде одинакова.

 

Начинаем писать античит.

Мое мнение таково, что античиты следует выносить в отдельные файлы (инклуды). Для этого предлагаю создать в папке "include" новую папку - "anticheats". Внутри новой папки создаем файл "ac_money.inc". Открываем файл.

 

Прежде всего нам следует задать некое начало нашему файлу, в котором стоит написать проверку на переподключение файла (об этом еще будет урок позже, в данный момент от вас требуется просто скопировать данный мною ниже код):

#if defined INC_AC_MONEY
	#endinput
#endif
#define INC_AC_MONEY

Далее мы объявим переменные, в которых будем хранить количество денег игрока (сколько у него должно быть) и ID таймера для игрока, чтобы могли удалять его после того, как игрок отключился.

static
	gPlayerMoney[MAX_PLAYERS], // количество денег, которое должно быть у игрока
	gPlayerTimer[MAX_PLAYERS]; // ID таймера для игрока, в котором будет идти проверка его баланса

Теперь приступим к перехватам. Запуск таймера мы начнем в функции OnPlayerConnect (вызывается, когда игрок подключается), а удалять таймер будем в OnPlayerDisconnect.

public OnPlayerConnect(playerid)
{
	// создаем таймер, где будем проверять игрока на пользование читами
	gPlayerTimer[playerid] = SetTimerEx("ac_money_OnPlayerSecondTimer", 1000*1, true, "i", playerid);
	
	#if defined ac_money_OnPlayerConnect
		return ac_money_OnPlayerConnect(playerid);
	#else
		return 1;
	#endif
}
#if defined _ALS_OnPlayerConnect
	#undef OnPlayerConnect
#else
	#define _ALS_OnPlayerConnect
#endif
#define OnPlayerConnect ac_money_OnPlayerConnect
#if defined ac_money_OnPlayerConnect
	forward ac_money_OnPlayerConnect(playerid);
#endif

public OnPlayerDisconnect(playerid, reason)
{
	KillTimer(ac_timerid[playerid]); // удалим таймер для этого игрока
	
	#if defined ac_money_OnPlayerDisconnect
		return ac_money_OnPlayerDisconnect(playerid, reason);
	#else
		return 1;
	#endif
}
#if defined _ALS_OnPlayerDisconnect
	#undef OnPlayerDisconnect
#else
	#define _ALS_OnPlayerDisconnect
#endif
#define OnPlayerDisconnect ac_money_OnPlayerDisconnect
#if defined ac_money_OnPlayerDisconnect
	forward ac_money_OnPlayerDisconnect(playerid);
#endif

Мы перехватили две функции - OnPlayerConnect и OnPlayerDisconnect, в которых будем создавать и удалять таймер для проверки игрока на пользование читами. Далее мы должны перехватить функции изменения денег (ResetPlayerMoney, GivePlayerMoney), чтобы в них происходило изменение значения переменной, где записано количество денежных средств данного игрока:

stock ac_money_GivePlayerMoney(playerid, money) // перехватываем функцию GivePlayerMoney
{
	gPlayerMoney[playerid] += money;
	return GivePlayerMoney(playerid, money);
}
#if defined _ALS_GivePlayerMoney
	#undef GivePlayerMoney
#else
	#define _ALS_GivePlayerMoney
#endif
#define GivePlayerMoney ac_money_GivePlayerMoney

stock ac_money_ResetPlayerMoney(playerid) // перехватим функцию ResetPlayerMoney
{
	gPlayerMoney[playerid] = 0;
	return ResetPlayerMoney(playerid);
}
#if defined _ALS_ResetPlayerMoney
	#undef ResetPlayerMoney
#else
	#define _ALS_ResetPlayerMoney
#endif
#define ResetPlayerMoney ac_money_ResetPlayerMoney

Последнее, что мы не сделали - функцию, в которой будем производить проверку: пользуется ли игрок запрещенными программными обеспечениями? Создаем ее (обратите внимание - я создаю функцию с модификатором public потому, что это будет таймер, а все таймеры следует объявлять с модификаторами public).

forward ac_money_OnPlayerSecond(playerid);
public ac_money_OnPlayerSecond(playerid)
{
	if(GetPlayerMoney(playerid) == gPlayerMoney[playerid])
		return 1; // все хорошо, деньги "тогда" и сейчас совпадают
		
	SendClientMessage(playerid, -1, "Система расценила Ваши действия как действия читера. Количество средств не совпадает.");
	Kick(playerid); // выкинем игрока с сервера за пользование сторонними ПО
	return 0;
}

На этом, вроде бы, все. файл с античитом, который должен был получиться у вас, если Вы следовали согласно данному уроку, я приложу ниже. Спасибо за внимание.

 

Автор данного урока: @Jawn

AntiCheat money.inc

Share this post


Link to post
Share on other sites
DEST
Maintainer

@mat300 принцип во всех играх один - хранить данные, которые могут быть подделаны, на сервере. А код, естественно, будет отличаться. Данный подойдет к SAMP/CRMP. 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • watson
      By watson
      Продаётся проект Criminal RolePlay с 8-летней историей.

      Проект заморожен и не используется длительное время.
      Потратил на него около 250.000 рублей, продаю за приемлимую цену.

      В комплекте:
      Полноценный игровой мод Мобильный лаунчер с Figma-дизайном Кэш клиентской части Все версии оформления проекта Все группы проекта Criminal RolePlay Шаблоны всех версий сайта, включая ранее не выпущенный шаблон Модуль автодоната YooMoney Помощь с установкой игрового мода на хостинг Цена:
      49 900₽ — за весь комплект.
      Возможен торг при адекватных предложениях.

      Важное:
      Проект продаётся в одни руки. Если в течение месяца не найдётся покупатель, будет рассмотрена продажа по частям.
      Связаться: https://vk.com/rosetta
    • watson
      By watson
      Продаётся проект Criminal RolePlay с 8-летней историей.

      Проект заморожен и не используется длительное время.
      Потратил на него около 250.000 рублей, продаю за приемлимую цену.

      В комплекте:
      Полноценный игровой мод Мобильный лаунчер с Figma-дизайном Кэш клиентской части Все версии оформления проекта Все группы проекта Criminal RolePlay Шаблоны всех версий сайта, включая ранее не выпущенный шаблон Модуль автодоната YooMoney Помощь с установкой игрового мода на хостинг Цена:
      49 900₽ — за весь комплект.
      Возможен торг при адекватных предложениях.

      Важное:
      Проект продаётся в одни руки. Если в течение месяца не найдётся покупатель, будет рассмотрена продажа по частям.
      Связаться: https://vk.com/rosetta
    • Elvis
      By Elvis
      Настоящим информируем о начале набора сотрудников в нашу студию "AlinSA Studios". В рамках текущего проекта "VanguardRP", основанного на мотивах CRMP, мы ищем профессионалов и энтузиастов для выполнения следующих должностей:
       
      1. Технические специалисты
       
      Требования:
       
      | Базовые знания в области информационных технологий
      | Понимание структур кода и принципов работы компиляторов
      | Готовность к обучению и развитию профессиональных навыков
      | Иметь базовое представлении ЯП "Pawn" или "Kotlin" и "Java".
       
      Обязанности:
       
      | Поддержка технической инфраструктуры проекта
      | Участие в разработке и оптимизации программных решений
      | Взаимодействие с командой разработки для внедрения новых функций
       
      2. Пиар-ассистенты
       
      Требования:
       
      | Опыт работы в сфере SMM, маркетинга или PR
      | Навыки взаимодействия с аудиторией и ведения социальных сетей
       
      Обязанности:
       
      | Продвижение проекта в социальных сетях
       
      3. Дизайнеры
       
      Требования:
       
      | Наличие портфолио с примерами выполненных работ (не обязательно, желательно)
      | Владение графическими редакторами ! (Photoshop и Figma)
      | Креативность, внимательность к деталям и способность работать в сжатые сроки
       
      Обязанности:
       
      | создание графического контента для соцсетей, сайта и внутриигровых материалов
      | Разработка дизайна интерфейсов, баннеров, логотипов и иллюстраций
      | Участие в визуальном оформлении проекта
       
      4. Геймдизайнеры
       
      Обязанности:
       
      | Разработка игровых механик, правил взаимодействия и систем баланса
      | Проработка сюжета, персонажей и сценариев для создания эмоциональной связи с игроками
      | Проектирование уровней, задач и сценариев для обеспечения разнообразия игрового процесса
      | Взаимодействие с командой разработчиков, художников и звукорежиссёров для достижения согласованности элементов игры
      | Участие в тестировании прототипов, выявление проблем и балансировка игрового процесса
       
      5. Рупоры
       
      Цель роли: Обеспечить эффективное взаимодействие с целевой аудиторией, формировать положительный имидж проекта, своевременно информировать участников о новостях, обновлениях и
      мероприятиях, а также модерировать сообщества для поддержания комфортной и безопасной среды.
       
      -————————-
      Условия работы:
       
      Обучение и постоянная поддержка со стороны команды
      Гибкий график работы / удалённый формат (обсуждается индивидуально)
       
       
      Если вы заинтересованы в присоединении к нашей команде или хотите получить дополнительную информацию, обращайтесь по следующему контакту:
      Telegram: @AntonLegost
       
       
      Благодарим за внимание! Надеемся на плодотворное сотрудничество.
       
      p.s Новички приветствуются. Для пополнение портфолио и наработки опыта.
       
      С уважением,
      Команда "AlinSA Studios"
    • Kutuzov
      By Kutuzov
      Автор данного канала снимает уроки по программированию на Pawn, также скоро будет на 20 подписчиков снимать мод с нуля в samp. 
      Приглашаем всех на канал, а также особенно новичков. Даже если вы уже знаете pawn, подпишитесь пожалуйста на его канал и поддержите его.
      Автор канала не требует денег!!! Он обучает всех бесплатно!!!
      Ссылка на канал: https://www.youtube.com/@prog_samp_easy
       
      Также у него есть свой тг канал, но начнет вести его, как только будет не менее 10 подписчиков.
       Ссылка на тг канал: https://t.me/pawndevelop
       
      Всем удачи
    • Sleash
      By Sleash
      Всем доброго времени суток. Сегодня мне бы хотелось вам рассказать от таких функциях в PAWN-языке, как SetTimer и SetTimerEx.
      Сразу сделаю такое примечание: Для SetTimer и SetTimerEx можно использовать ТОЛЬКО public!!!
      SetTimer
      Итак, для начала приступим к лёгкому и пойдём по нарастающей:
      Первое, это SetTimer. Функция включает в себя 3 параметра:
      native SetTimer(funcname[], interval, repeating); funcname[] - Это название функции, по сути - название вашего pablic в кавычках.
      interval - Интервалы от вызова таймера до срабатывания pablic
                     Так же если стоит повторение таймера, то будет работать как интервал между таймерами.
                     Измеряется в миллисекундах. 1000 миллисекунд равно 1 секунде
      repating - Тут всё просто: будет ли повторяться ваша функция. Может иметь значения: true - будет выполняться повторение ИЛИ false - вызывается 1 раз.
      Давайте разберём пример для наглядности:
      forward Info(); public Info() {     SendClientMessageToAll(0xFFFFFFFF, "Наш сайт: pawno-rus.ru"); } // И теперь давайте вызовем данный таймер при запуске мода public OngameModeInit() {     SetTimer("Info", 1000*60*20, true);     return true } Давайте разберёмся по интервалу: 1000*60*20. Так как я писал ранее, что 1000 млСек = 1 сек, то: 1 сек * 60 = 1 минута; 1 минута * 20 = 20 минут.
      Таким образом данный таймер будет выводить каждые 20 минут для всех игроков на сервере в чат: "pawno-rus.ru".
       
      SetTimerEx
       
      По сути с SetTimer - всё, теперь перейдём к следующей функции: SetTimerEx:
      native SetTimerEx(funcname[], interval, repeating, const format[], {Float,_}:...); Тут добавляются ещё 2 параметра:
      const format[] - формат данных для ввода в функцию. (Такие как: s, d, f);
      {Float,_}:... - переменные или значение для данных из const fromat[]
      Из данных объяснения мало что можно понять незнающему или начинающему скриптеру, поэтому давайте разберём на примере кода, который при входу даёт на авторизацию две минуты игроку:
      forward autorez(playerid); public autorez(playerid) {     if(/*проверка на то залогинился ли игрок*/)     {         SendClientMessage(playerid, 0xFFFFFFFF, "Вы были кикнуты по причине: Время на авторизацию истекло.");         Kick(playerid);         return true;     }     return true; } //Дальше уже добавлям сам таймер public OnPlayerConnect(playerid) {     SetTimerEx("autorez", 1000*60*2, false, "d", playerid);     return true; } Если первые три пункта мы уже разбирали. то начнём сразу с 4-го:
      4. Тут в кавычках надо вставлять тип данных. Наподобие функции format(output[], len, "%s %d %f", string, int, float), только без знака процента (%)
      5. Тут уже указывают сами данные, так же разберём как и предыдущий: format(output[], len, "%s %d %f ", string, int, float)
       
      Я надеюсь что кому-то помог, а если что непонятно, то спрашивайте, всегда помогу.