Посылаем нажатия и клики в свёрнутое окно на 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

wpDiscuz