Пишем бота-кликера на Python для Lineage 2


Предисловие


Как можно развлечься в новогодние праздники? Поиграть в компьютерные игры? Нет! Лучше написать бота, который это будет делать за тебя, а самому пойти лепить снеговика и пить глинтвейн.


Когда-то в школьные годы был увлечен одной из популярных MMORPG — Lineage 2. В игре можно объединяться в кланы, группы, заводить друзей и сражаться с соперниками, но в общем игра наполнена однообразными действиями: выполнением квестов и фармом (сбор ресурсов, получение опыта).


В итоге решил, что бот должен решать одну задачу: фарм. Для управления будут использоваться эмулированные клики мыши и нажатия клавиш клавиатуры, а для ориентирования в пространстве — компьютерное зрение, язык программирования — Python.


Вообще, создание бота для L2 дело не новое и их готовых есть довольно много. Делятся они на 2 основные группы: те, которые внедряются в работу клиента и кликеры.


Первые — это жёсткий чит, в плане игры пользоваться ими слишком уж неспортивно. Второй вариант интереснее, учитывая, что его можно будет с некоторыми доработками применить к любой другой игре, да и реализация будет интереснее. Те кликеры, которых я находил, по разным причинам не работали, либо работали нестабильно.


Внимание: вся информация здесь изложена только в познавательных целях. Особенно для разработчиков игр, чтобы помочь им лучше бороться с ботами.


Итак, к делу.


Работа с окном


Тут все просто. Будем работать со скриншотами из окна с игрой.
Для этого определим координаты окна. С окном работаем с помощью модуля win32gui. Нужное окно определим по заголовку — “Lineage 2”.


Код методов получения положения окна
def get_window_info():
    # set window info
    window_info = {}
    win32gui.EnumWindows(set_window_coordinates, window_info)
    return window_info

# EnumWindows handler
# sets L2 window coordinates
def set_window_coordinates(hwnd, window_info):
    if win32gui.IsWindowVisible(hwnd):
        if WINDOW_SUBSTRING in win32gui.GetWindowText(hwnd):
            rect = win32gui.GetWindowRect(hwnd)
            x = rect[0]
            y = rect[1]
            w = rect[2] - x
            h = rect[3] - y
            window_info['x'] = x
            window_info['y'] = y
            window_info['width'] = w
            window_info['height'] = h
            window_info['name'] = win32gui.GetWindowText(hwnd)
            win32gui.SetForegroundWindow(hwnd)

Получаем картинку нужного окна с помощью ImageGrab:


def get_screen(x1, y1, x2, y2):
    box = (x1 + 8, y1 + 30, x2 - 8, y2)
    screen = ImageGrab.grab(box)
    img = array(screen.getdata(), dtype=uint8).reshape((screen.size[1], screen.size[0], 3))
    return img

Теперь будем работать с содержимым.


Поиск монстра


Самое интересное. Те реализации, которые я находил, мне не подошли. Например, в одном из популярных и даже платном это сделано через игровой макрос. И “игрок” должен для каждого типа монстра прописывать в макросе типа “/target Monster Name Bla Bla”.


В нашем случае мы последуем такой логике: в первую очередь найдём все тексты белого цвета на экране. Белый текст может быть не только названием монстра, но и именем самого персонажа, именем NPC или других игроков. Поэтому надо навести курсор на объект и если появится подсветка с нужным нам паттерном, то можно атаковать цель.


Вот исходная картинка, с который будем работать:



Закрасим черным своё имя, чтобы не мешало и переведем картинку в ч/б. Исходная картинка в RGB — каждый пиксель это массив из трёх значений от 0 до 255, когда ч/б — это одно значение. Так мы значительно уменьшим объем данных:


img[210:230, 350:440] = (0, 0, 0)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)


Найдем все объекты белого цвета (это белый текст с названиями монстров)


ret, threshold1 = cv2.threshold(gray, 252, 255, cv2.THRESH_BINARY)


Морфологические преобразования:


  1. Фильтровать будем по прямоугольнику размером 50x5. Такой прямоугольник подошел лучше всех.
  2. Убираем шум внутри прямоугольников с текстом (по сути закрашиваем всё между букв белым)
  3. Еще раз убираем шум, размывая и растягивая с применением фильтра

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 5))
closed = cv2.morphologyEx(threshold1, cv2.MORPH_CLOSE, kernel)
closed = cv2.erode(closed, kernel, iterations=1)
closed = cv2.dilate(closed, kernel, iterations=1)


Находим середины получившихся пятен


(_, centers, hierarchy) = cv2.findContours(closed, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

Работает, но можно сделать прикольнее (например, для монстров, имена которых не видны, т.к. находятся далеко) — с помощью TensorFlow Object Detection, как тут, но когда-нибудь в следующей жизни.


Теперь наводим курсор на найденного монстра и смотрим, появилась ли подсветка с помощью метода cv2.matchTemplate. Осталось нажать ЛКМ и кнопку атаки.


Клик


С поиском монстра разобрались, бот уже может найти цели на экране и навести на них мышь. Чтобы атаковать цель, нужно кликнуть левой кнопкой мыши и нажать «атаковать» (на кнопку «1» можно забиндить атаку). Клик правой кнопкой мыши нужен для того, чтобы вращать камеру.


На сервере, где я тестировал бота, я вызвал клик через AutoIt, но он почему-то не сработал.


Как оказалось, игры защищаются от автокликеров разными способами:


  • поиск процессов, которые эмулируют клики
  • запись кликов и определение, какого цвета объект, на который кликает бот
  • определение паттернов кликов
  • определение бота по периодичности кликов

А некоторые приложения, как клиент этого сервера, могут определять источник клика на уровне ОС. (будет здорово, если кто-нибудь подскажет как именно).


Были перепробованы некоторые фреймворки, которые могут кликать (в т.ч. pyautogui, robot framework и что-то еще), но ни один из вариантов не сработал. Проскользнула мысль соорудить устройство, которое будет нажимать кнопку (кто-то даже так делал). Похоже, что нужен клик максимально хардварный. В итоге стал смотреть в сторону написания своего драйвера.


На просторах интернета был найден способ решения проблемы: usb-устройство, которое можно запрограммировать на подачу нужного сигнала — Digispark.


Ждать несколько недель с Алиэкспресса не хочется, поэтому поиски продолжились.


В итоге была найдена замечательная библиотека на C
Нашлась для неё и обёртка на Python


Библиотека у меня не завелась на питоне 3.6 — вываливалась ошибка Access violation что-то там. Поэтому пришлось соскочить на питон 2.7, там всё заработало like a charm.


Движение курсора


Библиотека может посылать любые команды, в том числе, куда переместить мышь. Но выглядит это как телепортация курсора. Нужно сделать движение курсора плавным, чтобы нас не забанили.


По сути задача сводится к тому, чтобы перемещать курсор из точки A в точку B с помощью обертки AutoHotPy. Неужели придется вспоминать математику?


Немного поразмыслив, всё-таки решил погуглить. Оказалось, что ничего придумывать не надо — задачу решает алгоритм Брезенхэма, один из старейших алгоритмов в компьютерной графике:


Прямо с Википедии можно взять и реализацию


Логика работы


Все инструменты есть, осталось самое простое — написать сценарий.


  1. Если монстр жив, продолжаем атаковать
  2. Если нет цели, найти цель и начать атаковать
  3. Если не удалось найти цель, немного повернемся
  4. Если 5 раз никого не удалось найти — идём в сторону и начинаем заново

Из более-менее интересного опишу, как я получал статус здоровья жертвы. В общих чертах: находим по паттерну с помощью OpenCV элемент управления, показывающий статус здоровья цели, берём полоску высотой в один пиксель и считаем в процентах, сколько закрашено красным.


Код метода получения уровня здоровья жертвы
def get_targeted_hp(self):
        """
        return victim's hp
        or -1 if there is no target
        """

        hp_color = [214, 24, 65]
        target_widget_coordinates = {}
        filled_red_pixels = 1

        img = get_screen(
            self.window_info["x"],
            self.window_info["y"],
            self.window_info["x"] + self.window_info["width"],
            self.window_info["y"] + self.window_info["height"] - 190
        )

        img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        template = cv2.imread('img/target_bar.png', 0)
        # w, h = template.shape[::-1]

        res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
        threshold = 0.8
        loc = np.where(res >= threshold)
        if count_nonzero(loc) == 2:
            for pt in zip(*loc[::-1]):
                target_widget_coordinates = {"x": pt[0], "y": pt[1]}
                # cv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), (255, 255, 255), 2)

        if not target_widget_coordinates:
            return -1

        pil_image_hp = get_screen(
            self.window_info["x"] + target_widget_coordinates['x'] + 15,
            self.window_info["y"] + target_widget_coordinates['y'] + 31,
            self.window_info["x"] + target_widget_coordinates['x'] + 164,
            self.window_info["y"] + target_widget_coordinates['y'] + 62
        )

        pixels = pil_image_hp[0].tolist()
        for pixel in pixels:
            if pixel == hp_color:
                filled_red_pixels += 1

        percent = 100 * filled_red_pixels / 150
        return percent

Теперь бот понимает, сколько HP у жертвы и жива ли она еще.


Основная логика готова, вот как теперь он выглядит в действии:
Для занятых я ускорил на 1.30



Остановка работы


Вся работа с курсором и клавиатурой ведется через объект autohotpy, работу которого в любой момент можно остановить нажатием кнопки ESC.


Проблема в том, что всё время бот занят выполнением цикла, отвечающим за логику действий персонажа и обработчики событий объекта и autohotpy не начинают слушать события, пока цикл не закончится. Работу программы не остановить и с помощью мыши, т.к. бот управляет ей и уводит курсор куда ему нужно.


Нам это не подходит, поэтому пришлось разделить бота на 2 потока: слушание событий и выполнение логики действий персонажа.


Создадим 2 потока


        # init bot stop event
        self.bot_thread_stop_event = threading.Event()

        # init threads
        self.auto_py_thread = threading.Thread(target=self.start_auto_py, args=(auto_py,))
        self.bot_thread = threading.Thread(target=self.start_bot, args=(auto_py, self.bot_thread_stop_event, character_class))

        # start threads
        self.auto_py_thread.start()
        self.bot_thread.start()

и теперь вешаем обработчик на ESC:


auto_py.registerExit(auto_py.ESC, self.stop_bot_event_handler)

при нажатии ESC устанавливаем событие


self.bot_thread_stop_event.set()

и в цикле логики персонажа проверяем, установлено ли событие:


while not stop_event.is_set():

Теперь спокойно останавливаем бота по кнопке ESC.


Заключение


Казалось бы, зачем тратить время на продукт, который не приносит никакой практической пользы?


На самом деле компьютерная игра с точки зрения компьютерного зрения — почти то же самое, что и снятая на камеру реальность, а там возможности для применения огромны. Отличный пример описан в статье про подводных роботов, которые лазером стреляют по лососям. Также статья может помочь разработчикам игр в борьбе с ботоводами.


Ну а я ознакомился с Python, прикоснулся к компьютерному зрению, написал свой первый слабоумный искусственный интеллект и получил массу удовольствия.
Надеюсь, было интересно и вам.


P.S. Ссылка на репозиторий

Поделиться публикацией
Похожие публикации
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 73
  • +1
    А сколько времени было потрачено на создание бота?
    • +1
      В часах немного, начал две недели назад.
    • +1
      Прикольно. Но, труднее ли это было бы реализовать на AutoHotkey?
      • +2

        Она палится системой защиты =)

        • 0
          тестил?)
          • +1
            По какому признаку?
            • 0
              Это самый интересный вопрос :)
              • 0
                Человек не двигает курсором по алгоритму Брезенхема.
          • 0

            Спасибо. Вспомнил молодость и кучу маленьких программ для обмана защиты =)

            • +2
              прикольно получилось, играл когда-то :)

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

              в общем, интересная задумка.

              Казалось бы, зачем тратить время на продукт, который не приносит никакой практической пользы?


              я бы здесь не согласился
              — ради «попробовать» — интересно и полезно, с чем Вы согласны,
              — помню, на некоторых серверах L2, пользователи покупали шмотки, аден, аккаунты за реальные деньги :)

              если довести бот до максимальной автономности, чтобы персонаж качался круглосуточно — оставив несколько клиентов L2 запущенных под управлением подобного бота в VM Ware, за месяцок можно набить нормальное количество аккаунтов с прокачанными и «одетыми» персонажами… останеться лишь продать :)
              • +1
                Круглосуточно — очень быстро будет замечено.
                • +1
                  Вы, видимо, просто не знакомы с Lineage 2)
                  • 0
                    А в чем собственно проблема запрограммировать бота на «разлогиниться в 2 часа ночи и залогиниться в 8 утра»… А если добавить случайности (+- час тут, траекторию «мыши» сделать не ровно прямой, направление выбирать случайно, монстров «иногда» не замечать...) — то можно очень долго не палиться…
                    • 0
                      А в чем собственно проблема запрограммировать бота на «разлогиниться в 2 часа ночи и залогиниться в 8 утра»…

                      А зачем? Нахождение в онлайне 24/7 ещё не означает, что персонаж бот. Может, он просто торгует?

                    • 0
                      Прекрасно знаком.
                      Есть существенная разница между (на вскидку):
                      — Персонаж 24 часа бегает в одном данже, бъет одних и тех же мобов 4 абилками, в чат не пишет, не делает релог.
                      — Персонаж переписывается в чате, бегает в город, сидит мулом в Гиране или Одене, торгуя A-сетом.

                      Как ниже написал mickvav, эмулирование действий человека, в том числе, ошибки, запланированные и случайные по длительности паузы — существенно увеличивают шанс не попасть под банхаммер. А вот 24/7 гринд — верный путь в бан.
                      • 0
                        — Персонаж 24 часа бегает в одном данже, бъет одних и тех же мобов 4 абилками, в чат не пишет, не делает релог.

                        И как вы сможете это проверить? Насколько я помню, сервер L2 не пишет насколько детальную информацию в логи. Ну и даже если бы и писал, то автоматическое выявление ботов было бы серьёзной BigData задачей.


                        Поэтому стандартный способ выявления ботов — вручную по репортам, либо через невалидные данные (невидимые мобы, например).

                        • 0
                          стандартный способ выявления ботов —

                          Группа опытных ботхантеров 24/7 ингейм, патрулирующих все локации. Невалидные мобы/итемы — мера против школьников и то, на 1-2 раза. А вот гейм-мастер, снимающий баф с чара — гораздо эффективный метод.
                          • 0

                            На еврооффе, где я играл, ГМы так не заморачивались. Потому ботоводство там цвело и пахло. Но вообще, если владелец сервера действительно хочет избавиться от ботов, то он может это сделать. А вот с чем владелец сервера ничего не может сделать — это снифферы, совсем простая автоматизация и багоюз.


                            Группа опытных ботхантеров 24/7 ингейм, патрулирующих все локации

                            А ещё был GMChecker. ГМ в онлайне — боты прячутся.
                            Ещё была технология определения местоположения любого игрока в игре.
                            И да, с инстансами что делать?

                            • +1
                              А вот с чем владелец сервера ничего не может сделать — это снифферы, совсем простая автоматизация и багоюз.

                              Мы говорим про официальные сервера или все?
                              И да, с инстансами что делать?

                              Инстансы не создаются динамически и преград для доступа ГМов в инстансы нет.
                              А ещё был GMChecker.

                              /gmlist или /gmonline, точно не помню. Стандартная команда и, есессно, у ГМов есть опция «не отображать в списке онлайн» (с каких хроник — не скажу, но есть).
                              ГМы так не заморачивались


                              В Корее прекрасно понимают, что фармить в таких масштабах нереально и, если ты не продаешь награбленное, всем до лампочки.
                              • 0
                                /gmlist или /gmonline, точно не помню. Стандартная команда и, есессно, у ГМов есть опция «не отображать в списке онлайн» (с каких хроник — не скажу, но есть).

                                Понятное дело, что эта команда не работала. Были косвенные признаки определения, находится ли ГМ в онлайне или нет. Например, зная ник игрока, можно легко понять, находится ли он в онлайне или нет, так, чтобы этот игрок об этом не узнал. Главное — просто вести актуальный список ГМов и перебирать их в бесконечном цикле со специального аккаунта.


                                Инстансы не создаются динамически и преград для доступа ГМов в инстансы нет.

                                Тем не менее, инстансы защищают от случайных прохожих, могущих зарепортить ботов.

                                • 0
                                  Корея сильно отличается по менталитету гейминга от наших.
                                  Они воют чутли не по договоренности, члены (боты в том числе) воющих кланов могут стоять на соседних полянах и еще мирно в чатике переписываться, наши с поляны выпрут любого исходя из принципа потому что могут), трейн не опытного ботовода разденут до гола и репортить не будут, если мозгов боту не добавят еще раз придет и оберет как липку.
                                  P.S. NCSoft (как и сами видимо корейские игроки) ботов проблемой у себя не считают, соответственно плевали они и на защиту, что у себя, что на евро, что руоффе (локализатор ковырялся сам вроде всегда), отсюда и DLL-injection как вершина ботовского софта для линейки упомянутая товарищем DistortNeo ниже
                                  • 0
                                    > отсюда и DLL-injection как вершина ботовского софта

                                    Скорее, имел место компромисс между уровнем зондирования и недовольством пользователей. Например, местный Frost банил игроков просто за сам факт наличия на жёстком диске бота. Для США/Европы такое немыслимо, поэтому GameGuard работал довольно мягко, просто не давая играть при определённых условиях

                                    А ещё в GameGuard есть белый список приложений, которым можно отправлять нажатия клавиш в окно игры. В этом список входят, например, драйверы клавиатур, Fraps и т.д. Не знаю, как сейчас, но раньше проверка была простая — по имени. То есть достаточно было переименовать AutoHotKey.exe в какой-то-там-panel.exe (от Logitech), и опа — всё работает.

                                    И, кстати, в случае невозможности использования инъекции DLL решение все равно бы было — сетевой шлюз внутри виртуальной машины, который у системы защиты вообще не было бы никаких шансов обнаружить, кроме самого факта запущенной виртуальной машины.
                                    • 0
                                      А ещё в GameGuard есть белый список приложений, которым можно отправлять нажатия клавиш в окно игры. В этом список входят, например, драйверы клавиатур, Fraps и т.д. Не знаю, как сейчас, но раньше проверка была простая — по имени.

                                      И первые ребята с не вошедшим в список софтом, для бинда кнопок/макросов для мышки улетали по первости в бан и штурмовали саппорт) было дело)
                      • +1
                        когда впервые познакомился с Л2, я был на 1курсе КПИ, тогда были лишь первые хроники, и рейты на все х1, и когда старый сервер Duron 900Mhz падал, пол-дня игры коту под хвост, что очень многих раздражало, и многие играли чуть ли не сутками :)

                        самый заядлых игроков — отчислили в первом семестре, я был не из заядлых, но в придачу еще и бухал, потому и меня отчислили )
                      • 0
                        помню, на некоторых серверах L2, пользователи покупали шмотки, аден, аккаунты за реальные деньги :)

                        На всех. Цена зависит от даты старта сервера.
                      • 0
                        Интересная штука!
                        Было бы круто, если бы нашлось время на разбор бота с внедрением в процесс игры.
                        Обходы защит и прочие плюшки :)
                        • +1
                          Могу вкратце написать, как я обходил GameGuard на еврооффе. Особенности GameGuard:

                          Сразу после старта клиента, но до старта GameGuard (около секунды) клиент является абсолютно незащищённым — можно делать что угодно. После старта GameGuard последний ограничивает внешний доступ к процессу, мониторит сетевые соединения и проверяет консистентность системных библиотек.

                          Для перехвата соединений внутри клиента я использовал обычный DLL-injection и JMP-хуки (при этом меняется код системной библиотеки в памяти процесса). Всё это успешно делалось в первую секунду после старта процесса. При этом был обнаружен интересный факт: GameGuard препятствет установке хуков на recv(), send() — даже если они были установлены ранее, то GG восстанавлияет исходный код библиотеки, но позволяет устанавливать JMP-hook на функцию connect().

                          Но не всё так просто: мы не можем просто взять и перенаправить вызов connect() на адрес, отличный от сервера L2 — это спалит система защиты. Но оказалось, что GameGuard нормально пропускает сокеты, переданные из другого процесса с помощью DuplicateAndClose. Поэтому внутри процесса настраивался pipe, а затем оба сокета передаётся в процесс-бот, ну а дальше дело техники.

                          Ну и ещё мелочь: перехват кликов мышки для того, чтобы клики, сделанные поверх окна бота, не доходили до клиента. Здесь всё аналогично, но хуки навешивались уже на одну из библиотек DirectX.
                          • 0
                            Интересно, спасибо!
                            Будет круто увидеть это в виде сочного, жирного поста. Если будет желание и время.
                        • 0
                          Как это сочетается, например, с Фростом и 4геем?
                          • +1
                            бот явно писался не для L2 Classic, там явно требуется учесть и предугадать больше вариантов развития событий, весьма агрессивного «ареала обитания».
                            P.S. для полностью автономного существования

                            а Фрост кликеры и не палил, процесс clicker.exe переименовал в neygadal.exe на этом хак закончен
                            • 0
                              Ну, в классике и нет кат, для которых этот бот и подходит :)
                              • 0
                                есть места где появление мобов ограничено пятачком, + некоторые локации аля Forgotten Temple под Глудином, разбитое на комнаты.
                                для ботовода 2 правила:
                                1. правильное место)
                                2. тихое место)
                                • 0
                                  На самом деле правил гораздо больше, если хочешь максимально снизить вероятность бана, какое бы тихое место ни было, рано или поздно может пробежать случайный игрок, спалить тебя, написать петицию, приходит модератор, всё твоего аккаунта больше нет)
                                  • 0
                                    Для ботовода могу выделить несколько правил:
                                    1) Не играть.
                                    2) Ваших чаров забанят. Когда — вопрос времени, к этому нужно быть готовым.
                                    3) Не пастись в одной локации.
                                  • 0

                                    Как это в классике нет кат? Прекрасные 60+ каты под ХВ :)

                                • 0
                                  Я писал бота для Interlude, т.к. мне доводилось играть только на этих хрониках. Хроники на актуальных серверах давно ушли вперед.
                                • 0
                                  Классная статья по старой доброй игре :) Интересно было прочитать, когда ни будь надеюсь повторить.
                                  • 0
                                    Знавал пару ботоводов, не знаю на сколько правда но в зависимости от сервера, обмундирования и противодействия зарабатывали от 500 до 1500$. Поэтому не такая уж и забава) подруга с Украины многие годы только так и зарабвтывала (с ее слов), нигде больше не работая. А по теме, ваш бот легко спалит админ поставив вдалеке мобов 80ур., впрочем это самый распространенный способ обнаружения, но т.к. мобы эти бордово-крассные, то конечно с этим не сложно бороться. Еще обычно смотрят по поведению, если оно прямо как у робота, то конечно будет бан, возможно даже перманентный. Вообще как задрот ла2 могу с уверенностью сказать, если делать избыточно-рандомные действия (ходить не по прямой, а свариациями, изменять угол смотрения камеры, не замирать на месте, а делать все как бы потоково, но не быстрее человека) — спалить очень сложно, потому что тогда отличить будет ну очень сложно, игроки там бегают почти всегда одинаково и делают это часами. Встречал такого бота когда еще играл на РуОфе, мне 15 минут понадобилось что бы понять, что это бот) кто-то подошел реально творчески к процессу, а конда я его пытался под мобами станить, что бы они его убивали, у него срабастывал авторелог, а если совсем все плохо было, то просто бсое :)
                                    • 0
                                      Зарабатывать надо на продаже бота :)
                                      • 0
                                        Сложно конкурировать с Адреналином :). Даже пока наращиваешь возможности, очень сложно демпинговать будет.
                                        • 0
                                          Адреналин не просто софтина, а уже целый сервис с поддержкой, там грамотно все сделали, качество не проверял, но сам подход :)
                                          Крупные кланы обычно пользуются приватным софтом, настраиваемый под задачи, там такой человек на окладе сидит), к тому же все конвертируемое в вечно зеленые в их руках, сам бог велел как говорится, доход одинокого ботовода не сравнится с Топами, но в зависимости от периода развития игры на икру хватит
                                    • +1
                                      На просторах интернета был найден способ решения проблемы: usb-устройство, которое можно запрограммировать на подачу нужного сигнала — Digispark.

                                      Есть ещё USBIP. И пример эмулятора HID-устройства к нему.
                                      Ещё можно реализовывать через отправку комманд Bluetooth HID и двух адаптеров версии от 2.0 :)
                                      • 0
                                        В своё время не вылезал из l2. Ночи в катах, мамон… Ностальгия напала. :'0
                                        • +1
                                          В новой «линейке» Revolution разработчики полностью решили проблему ботов. Теперь там есть кнопка «автофарм» :).
                                          • +1
                                            ну есть Lineage ll classik, ну и куча фришек, где еще очень долго не будет этого обновления, на многих определенно никогда) а вообще фарм это конвертация твоего времени в ценности, поэтому теперь все решает только толщина кошелька, ла2 закатилась туда где решают только деньги, поэтому хочешь старую ламповую, либо на фриху, либо забивать, даже на руофе, на классике ввели магаз, хотя били пяткой в гпудь что не бывать этому никогда, короче и там видимо темная сторона все заруинит :( а раньше, это был несомненный шедевр, ни одна игра не приносила такое море эмоций…
                                            • 0
                                              lineage 2 revolution это не обновление а отдельная мобильная гриндилка не имеющая отношения к традиционной ла2, классику и фришкам(ну может кроме лора).
                                              • 0
                                                хорошо, что это «дедушки» не видели, которые до сих пор в Ultima Online играют :)
                                                и скрипты пишут под неё
                                            • 0
                                              А я не так давно для FIFA 18 делал бота, который сам по ночам просто матчи запускал (результат там не важен) для фарминга монет.

                                              Тоже на Python (+ PyQT для удобства). Использовал OpenCV для анализа того, что ImageGrab «скринил». Пришлось сделать много скриншотов, из которых я удалял лишнее (делал прозрачным) и оставлял только то, что точно идентифицирует наше «состояние».

                                              Пытался сделать так, чтобы работало со свернутым окном — никак. :) Не придумал вообще как можно получить снимок неактивного DirectX приложения (и можно ли вообще). Да и клавиши все равно слать надо… Проще уже в виртуалке, если тянет.

                                              Ну а так работало все. Запустил, Alt+Enter, нажал «Start» боту, и погнало до утра играть. :)
                                            • +1
                                              Делал хардварный кликер. Нужна серва и ардуинка.
                                              Серву к клавиатуре крепил двумя саморезами.
                                              github.com/Areso/Arduino-clicker
                                              • 0
                                                Припаять провод к контакту кнопки? Нет. Саморезы!
                                                • 0
                                                  Безотносительно к ботам для ла2: ничто так не эмулирует аппаратный дребезг ключа, как аппаратный дребезг ключа (на правах шутки). Зато обеспечивает небольшой, но настоящий хардварный рандом при нажатии.
                                              • +1
                                                Если в локации будут другие белые имена помимо мобов? NPC/Игроки.

                                                И мне показалось, что работает (обрабатывает события) медленно. Очень много времени занимает нахождение цели, выделение, повороты.
                                                • 0

                                                  Как я понял, при наведении мыши мобы иначе подсвечиваются (например красным)


                                                  Теперь наводим курсор на найденного монстра и смотрим, появилась ли подсветка с помощью метода
                                                  • 0
                                                    при наведении мыши мобы иначе подсвечиваются

                                                    Нет. А вот как я понял — проверки на «моб — чар» просто нет. Потому первый же чар (по правилам игры, чаров с белым ником атаковать без зажатого Ctrl нельзя) уведет бота куда угодно (атака в «белого», на игровом сленге «не флагнутого» — не перешедшего в пвп режим (тогда ник чара розовеет), работает как атака в NPC: начать диалог).
                                                  • 0
                                                    Было написано про НПС, проверяется отклик при наведении, если он «правильный», то кликается левая кнопка мыши и идет атака, если же он «неправильный» то выбирается следующая цель.… Интересный актокликер, мне понравилась как логика реализации так и сама реализация, классненько, я когда-то делал кликер для пв, там было тоже не очень просто реализовать все эти логические комбинации, решил проблему почти также :)
                                                  • 0
                                                    Аж передёрнуло от темы. В своё время (~10 лет назад) играл на еврооффе, и тоже писал своего бота. Причём писал тоже по-серьёзному: с кусей пользователей, сервером обновления бота. Собственно, для меня это был первый серьёзный проект, которых неплохо подтянул скилл программирования.

                                                    Важный момент: система защиты на офсерверах (GameGuard) обходилась с полпинка, за ботами особо не следили, поэтому я работал непосредственно на уровне сетевого протокола.

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

                                                    Немного жалею, что в те времена ещё не было средств разработки, которые доступны сейчас — сделал бы гораздо больше всего интересного. Дико не хватало асинхронного программирования. Ну и сейчас я бы попробовал использовать не захардкоженные алгоритмы, а ИИ для более правдоподобных действий ботов.
                                                    • 0

                                                      Ждем следующую статью про самообучающегося бота на нейросетях

                                                      • 0
                                                        А некоторые приложения, как клиент этого сервера, могут определять источник клика на уровне ОС. (будет здорово, если кто-нибудь подскажет как именно).

                                                        Мое предположение, что автокликеры используют WinApi для кликов/хоткеев, а игра использует DirectInput

                                                        • +1
                                                          > Мое предположение, что автокликеры используют WinApi для кликов/хоткеев, а игра использует DirectInput

                                                          Именно так. Фильтр кликов внутри игры я делал, перехватывая соответствующие функции.
                                                        • 0
                                                          Спасибо большое автору за эту чудесную статью) После просмотра видео подхватил ностальгию) Жаль только звуков нет в видосике ;( Теперь вот сегодня — завтра сам пойду катать, правда в HF. Заведу себе гномку — рабыню, которая круглосуточно будет фармить каты xD
                                                          • 0

                                                            В юности какой-то кусок времени игрался в Silkroad где-то до 2008го года со всеми вытекающими систем free2p(l)ay — донаты, боты… Был отличный хак"testosterone" от товарища Rumata с небольшим изменением в клиенте, так же был слегка кАличный, но работающий TBot, который как-то навешивал хуки и пропускал через себя трафик игры, как через прокси, анализируя входные и добавляя команды на движения в выходные данные…
                                                            Может кто помнит?

                                                            • 0
                                                              В классе 9м наткнулся на одну статью, где с помощью С и малых манипуляций с оджидебагером и ассемблером, было предложено сделать что то типа «робота для 3й GTA»
                                                              все делалось только работая с памятью.
                                                              Игра запускалась на виртуальной машине, и простор для фантазии был практически безграничен, правда обратной связи от игры получить я так и не смог.
                                                              Вот сейчас задумался попробовать сделать что ни будь подобное и с современными играми
                                                              • 0

                                                                Этот алгоритм поиска моба думаю стоит применять после того, как перестанут выделяться мобы по /targetnext

                                                                • 0
                                                                  Первый же флагнутый чар — ваш. Мобы за стенкой — тоже ваши.
                                                                • 0

                                                                  Давненько в Линейку не играл, но если мне не изменяет память, по умолчанию на TAB’е висит перебор целей, видимых на экране. Название и ХП текущей цели отображаются в прямоугольнике в верхней части экрана. Не проще ли работать с этим таргетным прямоугольником, а не со всем экраном?

                                                                  • 0
                                                                    по умолчанию на TAB’е висит...

                                                                    инвентарь.
                                                                  • 0
                                                                    Не играл в линейку, но… почитал алгоритм бота:
                                                                    Если монстр жив, продолжаем атаковать
                                                                    Если нет цели, найти цель и начать атаковать
                                                                    Если не удалось найти цель, немного повернемся
                                                                    Если 5 раз никого не удалось найти — идём в сторону и начинаем заново

                                                                    Пока он ищет цель и вертится его не убьют?
                                                                    • 0
                                                                      у каждого монстра есть так называемое время респа(с момента убийства до возрождения) и координаты респа (в данном случае в пределах комнаты)
                                                                      Самое сложное зачистить комнату, когда все монстры уже появились(на игрока налетает вся толпа), делается как правило в ручную
                                                                      цели убиваются поочередно,
                                                                      из этого следует что и появляются они по очереди, а не толпой после зачистки комнаты
                                                                      главное рассчитать время убийства моба с временем респа и вуаля)
                                                                    • 0
                                                                      Было бы прекрасно увидеть нечто подобное, но не для автономного бота, а для текстового клиента. Т.е., например, на одной машине: определение мобов и окружающих объектов с помощью оптического распознавания, совершение действий. На другой — управление действиями первой машины (и чатом в ней) с помощью коротких команд, пример (утрированный):
                                                                      find target
                                                                      «targets found 6, names: monster Nephilim (2), monster OtherName(2), monster YetAnotherName(1), player VasyaBigOrc»
                                                                      attack -player VasyaBigOrc &
                                                                      useskillbutton -row 3 -number 7

                                                                      Естественно, скорость реакции и действий в случае пвп оставляли бы желать лучшего, но соль-то не в них.
                                                                    • 0
                                                                      у меня так, в свое время, пару десятков pvp за ночь бот нарубил
                                                                      • 0
                                                                        Вот, кстати, забавно — в линейке на ботов, в целом, до сих пор всем пофигу.
                                                                        А мне однажды приснилось, что СБ одной большой компании с неоднозначной репутацией и с проектом, очень похожим на линейку по геймплею, довольно активно боролась с проявлениями ботизма с эффектами присутствия.

                                                                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.