Содержание статьи
Рассказывать подробно о самой игре не буду, о ней слышали, наверное, даже те, у кого нет мобильного телефона. Начнем сразу с интересного.
warning
Редакция не рекомендует рассматривать Hamster Kombat как потенциальный источник заработка: почему — есть подробная статья на «Хабрахабре». Мы будем подразумевать, что имеем дело с обычной игрой, и используем ее как популярный пример, на котором можно продемонстрировать техники автоматизации.
Задача
Игра запускается через бота в Telegram, смысл заключается в наращивании пассивного дохода с биржи. Увеличивать доход можно с помощью покупки карточек, каждая карточка дает определенную прибавку к доходу. Деньги для покупки карточек добываются двумя путями: из того самого пассивного дохода и нажиманием большой кнопки в центре экрана.
В процессе игры у меня быстро появилось желание автоматизировать две вещи: нажатие на кнопку и выбор оптимальных карточек для покупки. У каждой карточки две основные характеристики: размер прибавки к доходу и цена. Одни карточки дают небольшую прибавку и дорого стоят, другие, наоборот, очень выгодны. Для простоты анализа я ввел понятие удельного дохода, ну или его еще можно назвать «цена прибавки». Допустим, если карточка стоит миллион монет и дает прибавку к доходу 4000 монет, значит, цена прибавки будет 1 000 000 / 4000 = 250 монет. Чем меньше цена прибавки, тем целесообразнее покупка монеты.
Характеристики карточки меняются после каждой покупки, поэтому на глаз все проанализировать и выбрать наиболее выгодную карточку по цене прибавки практически нереально. Для начала я составил табличку, добавил в нее все карточки и отсортировал их по удельной доходности (цена/добавка). Все бы хорошо, но это не отменяет необходимости после каждой покупки вручную обновлять изменившиеся характеристики карточки. Что ж, попробуем автоматизировать.
С ходу в голову пришел очевидный способ взаимодействия с игрой — анализ изображения на экране и эмуляция нажатий на экран с использованием Android Debug Bridge (ADB). Конечно, в идеале бы все сделать на запросах, вообще без телефона, но для этого надо анализировать трафик, а с учетом того, что игра запускается только на телефоне, внутри Telegram, анализ трафика мне показался весьма трудоемкой задачей, поэтому я решил начать с более очевидной реализации.
Автоматизация через ADB
Тапаем на экран
Надеюсь, что устанавливать ADB и взаимодействовать через него с телефоном все умеют, поэтому не буду лить воду про это, перейдем сразу к делу. Попытки запустить игру в Windows закончились неудачей, поскольку игра каким‑то образом определяет, что запущена не на телефоне, и выводит сообщение об этом. Что ж, телефон — значит, телефон. Вооружаемся телефоном с Android, расчехляем ADB. Вопрос с тапаньем по кнопке легко решается одной командой:
e:\Android\sdk\platform-tools\adb.exe shell input tap 540 1800
540 и 1800 — это координаты точки на экране, в которую мы хотим «ткнуть пальцем». Чтобы не возвращаться к этому второй раз, сразу хочу сказать про так называемую морзянку. В игре каждый день есть возможность получить дополнительный миллион монет, введя с помощью азбуки Морзе определенный код. Точка кодируется коротким нажатием, тире — длинным. Делать короткое нажатие мы уже умеем, длинное же делается вот такой командой:
e:\Android\sdk\platform-tools\adb.exe shell input swipe 500 1500 500 1500 555
Первые четыре числа — координаты начала и конца движения, а 555 — время движения. В нашем случае начало и конец совпадают.
Чтобы минимизировать ручную работу, можно написать на Python скрипт, который будет принимать на вход слово, перекодировать его в последовательность точек и тире и через нажатия вводить в игру. Приведу основные функции, которые понадобятся.
Функция, которая эмулирует ввод точки:
def tochka(): cmd = "adb.exe shell input tap 500 1500" process = subprocess.Popen(cmd, stdout=subprocess.PIPE, creationflags=0x08000000) process.wait()
Функция, эмулирующая ввод тире:
def tire(): cmd = "adb.exe shell input swipe 500 1500 500 1500 500" process = subprocess.Popen(cmd, stdout=subprocess.PIPE, creationflags=0x08000000) process.wait()
Функция, которая разбирает последовательность точек и тире и отправляет ее в телефон (пробел означает паузу в три секунды, необходимую для отделения букв друг от друга):
def mz2tap(morze): for simvol in morze: match simvol: case ".": tochka() case "-": tire() case " ": time.sleep(3)
Перевода текста в азбуку Морзе касаться не буду, не ради этого мы тут собрались. Пример использования:
mz2tap(".--")mz2tap(".")mz2tap("-...")mz2tap("...--")
С первой задачей по автоматизации тапов разобрались, теперь самое время заняться анализом карточек, чтобы выбирать лучшую.
Распознаём карточки
С карточками пришлось повозиться. К задаче я решил подойти в лоб — пролистывать карточки и делать скриншоты, затем обрезать лишнее и распознавать то, что осталось.
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»