Как в lineage 2 сделать бота в
Как можно развлечься в новогодние праздники? Поиграть в компьютерные игры? Нет! Лучше написать бота, который это будет делать за тебя, а самому пойти лепить снеговика и пить глинтвейн.
Когда-то в школьные годы был увлечен одной из популярных MMORPG — Lineage 2. В игре можно объединяться в кланы, группы, заводить друзей и сражаться с соперниками, но в общем игра наполнена однообразными действиями: выполнением квестов и фармом (сбор ресурсов, получение опыта).
В итоге решил, что бот должен решать одну задачу: фарм. Для управления будут использоваться эмулированные клики мыши и нажатия клавиш клавиатуры, а для ориентирования в пространстве — компьютерное зрение, язык программирования — Python.
Вообще, создание бота для L2 дело не новое и их готовых есть довольно много. Делятся они на 2 основные группы: те, которые внедряются в работу клиента и кликеры.
Первые — это жёсткий чит, в плане игры пользоваться ими слишком уж неспортивно. Второй вариант интереснее, учитывая, что его можно будет с некоторыми доработками применить к любой другой игре, да и реализация будет интереснее. Те кликеры, которых я находил, по разным причинам не работали, либо работали нестабильно.
Внимание: вся информация здесь изложена только в познавательных целях. Особенно для разработчиков игр, чтобы помочь им лучше бороться с ботами.
Работа с окном
Тут все просто. Будем работать со скриншотами из окна с игрой.
Для этого определим координаты окна. С окном работаем с помощью модуля win32gui. Нужное окно определим по заголовку — “Lineage 2”.
Получаем картинку нужного окна с помощью ImageGrab:
Теперь будем работать с содержимым.
Поиск монстра
Самое интересное. Те реализации, которые я находил, мне не подошли. Например, в одном из популярных и даже платном это сделано через игровой макрос. И “игрок” должен для каждого типа монстра прописывать в макросе типа “/target Monster Name Bla Bla”.
В нашем случае мы последуем такой логике: в первую очередь найдём все тексты белого цвета на экране. Белый текст может быть не только названием монстра, но и именем самого персонажа, именем NPC или других игроков. Поэтому надо навести курсор на объект и если появится подсветка с нужным нам паттерном, то можно атаковать цель.
Вот исходная картинка, с который будем работать:
Закрасим черным своё имя, чтобы не мешало и переведем картинку в ч/б. Исходная картинка в RGB — каждый пиксель это массив из трёх значений от 0 до 255, когда ч/б — это одно значение. Так мы значительно уменьшим объем данных:
Найдем все объекты белого цвета (это белый текст с названиями монстров)
- Фильтровать будем по прямоугольнику размером 50x5. Такой прямоугольник подошел лучше всех.
- Убираем шум внутри прямоугольников с текстом (по сути закрашиваем всё между букв белым)
- Еще раз убираем шум, размывая и растягивая с применением фильтра
Находим середины получившихся пятен
Работает, но можно сделать прикольнее (например, для монстров, имена которых не видны, т.к. находятся далеко) — с помощью TensorFlow Object Detection, как тут, но когда-нибудь в следующей жизни.
Теперь наводим курсор на найденного монстра и смотрим, появилась ли подсветка с помощью метода cv2.matchTemplate. Осталось нажать ЛКМ и кнопку атаки.
С поиском монстра разобрались, бот уже может найти цели на экране и навести на них мышь. Чтобы атаковать цель, нужно кликнуть левой кнопкой мыши и нажать «атаковать» (на кнопку «1» можно забиндить атаку). Клик правой кнопкой мыши нужен для того, чтобы вращать камеру.
На сервере, где я тестировал бота, я вызвал клик через AutoIt, но он почему-то не сработал.
Как оказалось, игры защищаются от автокликеров разными способами:
- поиск процессов, которые эмулируют клики
- запись кликов и определение, какого цвета объект, на который кликает бот
- определение паттернов кликов
- определение бота по периодичности кликов
А некоторые приложения, как клиент этого сервера, могут определять источник клика на уровне ОС. (будет здорово, если кто-нибудь подскажет как именно).
Были перепробованы некоторые фреймворки, которые могут кликать (в т.ч. pyautogui, robot framework и что-то еще), но ни один из вариантов не сработал. Проскользнула мысль соорудить устройство, которое будет нажимать кнопку (кто-то даже так делал). Похоже, что нужен клик максимально хардварный. В итоге стал смотреть в сторону написания своего драйвера.
На просторах интернета был найден способ решения проблемы: usb-устройство, которое можно запрограммировать на подачу нужного сигнала — Digispark.
Ждать несколько недель с Алиэкспресса не хочется, поэтому поиски продолжились.
Библиотека у меня не завелась на питоне 3.6 — вываливалась ошибка Access violation что-то там. Поэтому пришлось соскочить на питон 2.7, там всё заработало like a charm.
Движение курсора
Библиотека может посылать любые команды, в том числе, куда переместить мышь. Но выглядит это как телепортация курсора. Нужно сделать движение курсора плавным, чтобы нас не забанили.
По сути задача сводится к тому, чтобы перемещать курсор из точки A в точку B с помощью обертки AutoHotPy. Неужели придется вспоминать математику?
Немного поразмыслив, всё-таки решил погуглить. Оказалось, что ничего придумывать не надо — задачу решает алгоритм Брезенхэма, один из старейших алгоритмов в компьютерной графике:
Прямо с Википедии можно взять и реализацию
Логика работы
Все инструменты есть, осталось самое простое — написать сценарий.
- Если монстр жив, продолжаем атаковать
- Если нет цели, найти цель и начать атаковать
- Если не удалось найти цель, немного повернемся
- Если 5 раз никого не удалось найти — идём в сторону и начинаем заново
Из более-менее интересного опишу, как я получал статус здоровья жертвы. В общих чертах: находим по паттерну с помощью OpenCV элемент управления, показывающий статус здоровья цели, берём полоску высотой в один пиксель и считаем в процентах, сколько закрашено красным.
Теперь бот понимает, сколько HP у жертвы и жива ли она еще.
Основная логика готова, вот как теперь он выглядит в действии:
Для занятых я ускорил на 1.30
Остановка работы
Вся работа с курсором и клавиатурой ведется через объект autohotpy, работу которого в любой момент можно остановить нажатием кнопки ESC.
Проблема в том, что всё время бот занят выполнением цикла, отвечающим за логику действий персонажа и обработчики событий объекта и autohotpy не начинают слушать события, пока цикл не закончится. Работу программы не остановить и с помощью мыши, т.к. бот управляет ей и уводит курсор куда ему нужно.
Нам это не подходит, поэтому пришлось разделить бота на 2 потока: слушание событий и выполнение логики действий персонажа.
Создадим 2 потока
и теперь вешаем обработчик на ESC:
при нажатии ESC устанавливаем событие
и в цикле логики персонажа проверяем, установлено ли событие:
Теперь спокойно останавливаем бота по кнопке ESC.
Заключение
Казалось бы, зачем тратить время на продукт, который не приносит никакой практической пользы?
На самом деле компьютерная игра с точки зрения компьютерного зрения — почти то же самое, что и снятая на камеру реальность, а там возможности для применения огромны. Отличный пример описан в статье про подводных роботов, которые лазером стреляют по лососям. Также статья может помочь разработчикам игр в борьбе с ботоводами.
Ну а я ознакомился с Python, прикоснулся к компьютерному зрению, написал свой первый слабоумный искусственный интеллект и получил массу удовольствия.
Надеюсь, было интересно и вам.
Обход защиты от автокликеров и ботов в онлайн играх.
Видео работы приватного АнтиАнтикликера под GameGuard
Каким бы ни был функциональным автокликер или бот все его достоинства разбиваются о многочисленную защиту онлайн игр, направленную на нейтрализацию программ автоматизации. На некоторых игровых серверах удается временно заставить работать ту или иную программу путем блокировки и отключения тех или иных функций защиты. Как правило это срабатывает ненадолго и чревато быть обнаруженным со всеми вытекающими последствиями.
Программы предоставленные на этом сайте предпологают совсем другой подход к проблемме защит.
Рассмотрим пример с автокликерами.
На сегодняшний день все автокликеры так или иначе используют API функции эмуляции клавиатуры и мыши. Вы можете перепробовать множество кликеров, но если в данной игре не работает первые пару штук можете быть уверенны что найти кликер для вашей игры не удастся.
AvtoK первый автокликер поддерживающий эмуляцию действий с мышью и клавиатурой на уровне железа и не использует API функций.
За счет этого его работа невидима для защит. В итоге этот автокликер работает на любых игровых серверах. Протестировано в на серверах 4game в Lineage 2, RF Online и allods mail ru в Аллоды онлайн. Кроме того в автокликере AvtoK присутствуют функции рандома, позволяющие скрыть свою деятельность как автокликер, поскольку будучи зацикленным он не повторяет один в один движения мыши и координаты кликов как обыкновенный кликер. Так же возможно включить рандом для скорости перемещения мыши и паузы между циклами. Шанс уличить такой автокликер возможен только путем прямого общения ГМ с игроком.
С управлением мы разобрались. Но как быть если нам нужен не просто кликер а бот?
Кибор программируемый кликер. Главный упор этой программы идет на анализ экрана и управление клавиатурой и мышью.
Так же как и с блокированием API функций эмуляции защита блокирует функции чтения записи в другой процесс. Поэтому не работают боты,так как они активно используют эти функции. Так что нам остается еще (методы взлома и блокировки защит не расматриваются)? А остается нам то что никогда не закроется от пользователя - экран. Поэтому Кибор имеет в наличие мощные функции для работы и анализа изображения, позволяющие создавать ботов не только для простых 2Д игр, но и для 3Д, работая при этом не только к пикселями или в лучшем случае с 2Д картинками, но и с 3Д объектами.
Урок. Как создать бота в Кибор.
Как обойти защиту от автокликеров и ботов. Обход Frost и других защит.
В основе этого урока лежит создание бота для Lineage 2 в программе Кибор.
Надеюсь что перед чтением этой статьи Вы пролистали хоть поверхностно справку по программе?
Часть первая. Подготовка графического материала и расчет координат.
Перед созданием любого бота мы должны составить четкий план инструкций, которые должен выполнять бот для достижения той или иной цели. В нашем случае это будет фарм-кач бот. В его обязаности будет входить поиск мобов, их убийство и сбор лута. Так же мы должны четко знать какие действия для этого предприняли бы мы и по чему ориентировались, будь мы этим ботом. Ориентируемся мы визуально. Поэтому нам надо определиться на что мы обращаем внимание во время фарма.
Мы видим на экране окно с игрой, видим в окне мобов, их положение на экране. Если мы не видим мобов, то у нас есть радар по которому мы можем найти направление и узнать куда надо идти что бы прийти к новой стае. Если есть мобы в непосредственной близости от нас мы можем просто брать их таргет с помощью специальной функции любезно предоставленной нам разработчиками линейки. Во время боя мы атакуем имеющимися скилами и видим табличку с XP моба и можем по ней определить ход боя. После слива моба мы собираем лут.
Теперь наша задача заставить это все видеть и выполнять бота.
Для начала дадим боту возможность видеть и укажем куда надо смотреть для контроля того либо иного действия. Для этого определимся что бот должен видеть.
Первое - само окно с игрой, его позицию на экране и само игровое поле в окне. Для этого найдем в окне игры какой либо участок интерфейса, который был бы постоянным в любой ситуации, заставим бота при запуске скрипта найти этот участок и расчитаем координаты игрового поля.
Для определения не меняющихся частей интерфейса воспользуемся встроенным графическим редактором Кибор. Открываем панель Графика (прочитать про графический редактор Кибор), активируем окно с игрой и жмем CTRL+SHIFT+S. В Кибор появляется рисунок окна с игрой. Затем жмем CTRL+SHIFT+A (запустим фильтр динамики) и немного побегаем и покрутим камерой. Останавливаем фильтр динамики нажав опять на CTRL+SHIFT+A. Смотрим на рисунок в редакторе и видим примерно такую картину:
Все что подсветилось красным нам не подходит, так как меняется во время игры. Для выбора рисунка для привязки к окну надо найти объект на экране который не будет сдвинут во время игры. В нашем случае подходит кнопка настройки чата. Выделяем ее и нажав правую кнопку мыши сохраняем выделенное в виде .bmp файла. Его потом при запуске бот найдет на экране и расчитает координаты игрового поля в котором ему предстоит играть. Так же нам надо указать позицию таблички с XP моба для того что бы бот мог проверять ее наличие на экране и узнавать XP моба, и радара для последующего поиска на нем мобов и расчет их положений относительно центра радара (перса).
Во время поиска мобов на экране бот будет перебирать с помощью finddynamic все потенциальные участки на экране где может быть моб и будет ориентироваться на появление кружочков над мобом если на него навели мышь (ознакомиться с finddynamic ) (как работает finddynamic ). Наводим мышь на моба, жмем CTRL+SHIFT+S и сохраняем центр кружочка в .bmp.
Собственно это тот минимум который необходимо контролировать для успешного фарма. Определение собственного XP я думаю вы сможете сделать сами. На этом рисунке выделены все объекты которые использовались в прилагаемом скрипте бота. Табличка с XP моба сохранялась по трем позициям выделенных толстыми красными рамками. Сами рисунки смотрите в папке со скриптом:
Красными толстыми прямоугольниками показаны все сохраненные рисунки.
Табличка с XP моба сохранена по трем участкам.
Белыми линиями показаны расчитываемые координаты которые найдены с помощью соответствующего рисунка.
Большая рамка в окне игры ограничивает область поиска мобов функцией finddynamic и расчитывается исходя из найденной позиции рисунка кнопки настройки чата (1).
Координаты рамки поиска на радаре и его центр (положение перса) расчитываются исходя из найденого рисунка кнопки показа карты (3).
Координаты первого красного пикселя полосы XP моба расчитываются исходя из позиции таблички моба в таргете (2).
Область поиска кружочка над мобом (6) когда на него навели мышь расчитывается исходя их положения мыши над мобом.
Все наши подготовленные рисунки ищутся функцией findimage (пример применения findimage ) и (еще пример), которая позволяет найти на экране изображение подобное загруженному с .bmp файла с помощью функции loadimage (ознакомиться с loadimage ) и возвращает координаты левого верхнего угла найденного изображения.
Пример программирования загрузки рисунка кнопки настройки чата и расчет координат рамки ограничевающей поиск мобов:
int PrivyazkaXY[14][14]; //Переменная в котрую будет загружен рисунок кнопки настройки чата
int P_X[1], P_Y[1]; //Переменные в который будут записаны найденные координаты левого верхнего угла этого изображения
Поясняю откуда взялись xe, ye и w:
xe и ye - разрешение экрана. Узнается с помощью функции getdisplay (подробнее о getdisplay )
w - указатель на окно. В нашем случае мы работаем со всем экраном, поэтому получаем указатель на рабочий стол с помощью window (подробнее о window )
Теперь можно расчитать координаты рамки (5). Наводим мышь на окно игры в позицию (7). Жмем CTRL+SHIFT+S. Переходим на вкладку Код (подробнее о шпионе) в Кибор. В окне Координаты мыши экранные видим координаты этой точки. Записываем их. Наводим мышь на левый верхний угол рисунка кнопки настройки чата. Жмем CTRL+SHIFT+S. Так же само записываем. Теперь расчитываем:
int S_X,S_Y,F_X,F_Y; //Переменные левого верхнего и правого нижнего угла рамки
S_X=P_X[0]; S_Y=P_Y[0]-625; //Левый верхний угол
F_X=P_X[0]+1010; F_Y=P_Y[0]-160; //Правый нижний угол
625, 1010, 160 мы получили узнав разницу между полученными координатами с помощью CTRL+SHIFT+S.
Таким же образом узнаем и записываем в переменные все остальные координаты которые будет использовать бот.
Читайте также: