Посылаем нажатия и клики в свёрнутое окно на AutoHotkey: бот Clicker Heroes

Часто хочется автоматизировать что-то так, чтобы посылать нажатия и клики прямо в свёрнутое окно. Пришло время сделать это, на AutoHotkey.

Это пример кода, который помогает играть в «кликер» Clicker Heroes, автоматически использует способности (кнопки 1-9), собирает золото и наносит урон.

 

Что тут происходит?

#IfWinactive, ahk_exe Clicker Heroes.exe делает эти хоткеи доступными только когда игра в данный момент в фокусе. Когда в фокусе любое другое приложение, эти хоткеи никак не будут реагировать.
Описание доступных селекторов типа ahk_exe https://www.autohotkey.com/docs/misc/WinTitle.htm

#MaxThreadsPerHotkey 2 позволяет вызывать один и тот же хоткей не 1 раз, как по-умолчанию, а 2 раза, таким образом срабатывает логика toggle переключения режима вкл/выкл.
Здесь про саму директиву https://www.autohotkey.com/docs/commands/_MaxThreadsPerHotkey.htm
Здесь теория, как «потоки» работают в AutoHotkey https://www.autohotkey.com/docs/misc/Threads.htm
By default, a given hotkey or hotstring subroutine cannot be run a second time if it is already running. Use #MaxThreadsPerHotkey to change this behavior.

 

Основная логика на F4, то есть в clicker_heroes_background_spam().

В AHK «потоки» не работают одновременно, AHK замораживает исполнение в первом «потоке», пока новый не завершит свою работу. Поэтому второй «поток» изменяет глобальное состояние toggle, завершается, возвращает управление первому потоку. Первый поток видит, что toggle теперь выключен, и тоже gracefully завершается.

WinExist("A") возвращает hwnd (id) текущего активного окна. Это используется, чтобы временно прекращать работу автоматического кликера, когда управление игрой взял на себя человек, чтобы не конфликтовать. https://www.autohotkey.com/docs/commands/WinExist.htm

ControlSend — то же самое, что Send, но может посылать нажатия в неактивные окна. Не может посылать клики. https://www.autohotkey.com/docs/commands/ControlSend.htm

ControlClick — а вот так можно посылать клики в неактивные окна. В моём случае верная координата в AHK Window Spy это Window. https://www.autohotkey.com/docs/commands/ControlClick.htm

autohotkey window spy для ControlClick

 

Чтобы это всё работало хорошо и никак не пересекалось с остальным взаимодействием с компьютером, используются некоторые техники.

Для ControlClick стоит флаг NA, честно говоря я разницы не увидел, но в описании его рекомендуют, и его описание выглядит будто я хочу, чтобы он был. Ну, вроде хуже не стало. https://www.autohotkey.com/docs/commands/ControlClick.htm

Для ControlClick так же поставил SetControlDelay, -1, опять же проблем не видел и до этой настройки, но по аналогии со следующим пунктом, возможно, это полезно. https://www.autohotkey.com/docs/commands/SetControlDelay.htm

Для ControlSend важная настройка SetKeyDelay, -1. Эту статью я пишу, пока background скрипт работает, и пока эту настройку не сделал, периодически были какие-то фантомные штуки вроде «альт-таб не сработал», «ctrl+z не сработал». С этой же настройкой мне не удалось заметить ни одной помехи в основной работе за компьютером, пока работает background скрипт. https://www.autohotkey.com/docs/commands/SetKeyDelay.htm

Ещё важная техника — использовать режим {blind} для ControlSend. Если не использовать его, отправка будет полагать, что нужно отправить строку именно так, как она написана (что, собственно, в большинстве случаев верно). И будет нажимать или отжимать Shift, будет пытаться отжать мой Alt, чтобы отправить свою строку, и потом обратно вернуть мой Alt. Я уже обширно тестировал это, играя в World of Warcraft, и рано или поздно система даст сбой, чуть-чуть промахнётся, и оставит какой-нибудь модификатор (шифт, …) зажатым. Это плохо. Режим же {blind} говорит «не обращай внимания на всякие там модификаторы, просто отправляй чё написано». Таким образом минусы — в background программу могут быть отправлено не то, что написано, а то что написано + текущее состояние модификаторов (alt, ctrl, …). Но когда дело касается игр, как правило это или не страшно, или наоборот желаемое поведение. Зато стабильность и безглючность на максимальном уровне: если AutoHotkey не пытается управлять модификаторами, нет шансов что-либо сломать. https://www.autohotkey.com/docs/commands/Send.htm#Blind

 

Для примера, вот так я пользовался {blind} в World of Warcraft, чтобы просто держать кнопку скила (1, файрбол на маге) и чтобы он сам кастовался. Когда в нужный момент мне было необходимо моментально скастовать моментальный файрбласт (хоткей Alt+1), я просто не отпуская 1 до-зажимал Alt, режим {blind} не обращает внимания на модификаторы, поэтому теперь в игру начинал прилетать зажатый хардверно Alt и тот же самый спам 1, спел кастовался. Очень удобно. Топ дпс все дела, просто зажав и не отпуская одну кнопку ) Там ещё макросы внутри игры помогали, чтобы, если надо, в эту одну кнопку более-менее умную ротацию заклинаний встроить.

Жалко только, что в новых клиентах классического WoW’а используется новый движок, в котором уже есть спаллбатчинг, если бы, как 15 лет назад в ванилле, его не было, подобный спам давал бы ещё больше преимущества над обычными людьми.

 

Вот, собственно, и всё. Система работает. Пока я пишу этот пост, нажатия и клики незаметно отправляются в игру, и это нисколько мне не мешает, совсем никак не нагружает процессор.

Кстати заметил, что игру выгоднее именно сворачивать, а не просто убирать фокус. Потому что у игры без фокуса графика продолжает отрисовываться, а свёрнутая игра, по крайней мере именно Clicker Heroes, позволяет получать нажатия и клики, но уже ничего не отрисовывает, и с ~10% загрузки, то есть с почти целого ядра, опускается до ~3%, то есть до 1/4 целого ядра.

 

Осталось разве что показать несколько хелпер-функций, которые используются.

Это меняет значок в систем трее, чтобы было видно, что скрипт активен.

иконка бабочки когда включен скрипт ahk

Иконка в данном случае берётся из стандартного shell32.dll, я список доступных там иконок смотрю прямо в total commander:

смотрю доступные в shell32.dll иконки и порядковый номер в total commander

 

Ну а это просто generic функция, спамит лефт-клики в текущее активное окно, прекращает спамить или когда теряется фокус, или по тому же хоткею, по тому же самому общему механизму toggle:

 

Мучаюсь с синтаксисом AutoHotkey каждый раз, до сих пор приходится каждый раз проверять, где там expressions, что там в переменных, где нужны кавычки а где не нужны, это самый корявый язык из всех мне известных. Разве что наверно lua может с ним посоревноваться.

Но тем не менее, AutoHotkey обладает огромным набором возможностей для автоматизации множества задач на Windows, для работы с интерфейсом. Так что, по сути, выбора нет. Вообще, конечно, страшно представить, что этот скрипт я в сумме писал 12 часов. На нормальном языке вроде PHP справился бы за 2 часа.

До встречи.

 

clicker heroes 1 clicker heroes 2 clicker heroes 3 clicker heroes 4

Обсуждение

avatar

Максим
2021.07.16 15:27

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

wpDiscuz