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

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

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

Сегодня на операционном столе будет приложение в телеграм, которое в будущем должно стать полноценной децентрализованной биржей, но в настоящее время позволяет новым пользователям лишь зарабатывать внутренние очки. Хочу сразу сказать, что даже руководитель проекта честно заявляет, что обмен этих очков на что-то более материальное в будущем вовсе на обязателен, имейте это ввиду. Я его тоже не рекламирую, и уж тем более не даю никаких финансовых рекомендаций, он нам нужен лишь в качестве примера.

Механика мини игры внутри этого приложения такая: в течение небольшого времени сверху падают цветочки, которые нужно ловить простым нажатием. За них и начисляют очки. Однако, недавно в игре появились еще и бомбочки, при нажатии на которые счет обнуляется.

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

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

import pyautogui
import keyboard
import time

Pyautogui будет управлять мышью и определять цвет пикселя, на который наведен курсор. Keyboard нужен для назначения горячих клавиш, а time для временной задержки.

Назначим три переменные.

work = False
points = [(0, 0) for _ in range(20)]
index = 0

Work будет отвечать за работу кода в бесконечном цикле. Если True- выполняется следующая функция, если False - всё останавливается. Points содержит координаты двадцати точек, изначально равные нулю, так как мы их будем назначать после запуска программы. А index нужен, чтобы демонстрировать пользователю, какую по счету точку он назначает. И сразу напишем функцию присваивания координат точкам для кликов.

def mouse_posotion():
    global index
    x, y = pyautogui.position()
    points[index] = x, y
    print(f'Координаты точки {index + 1}: X: {x}, Y: {y}', end='\r')
    index += 1
    if index > 19:
        index = 0

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

Следующая функция будем изменять значение переменной work и срабатывать так же при нажатии горячей клавиши. Она будет ставить на паузу работу автокликера.

def change_clicker():
    global work
    work = not work

Теперь функция самого кликера.

def clicker(points: list):
    for point in points:
        screenshot = pyautogui.screenshot()
        color = screenshot.getpixel((point[0], point[1]))
        if color[0] in range(134, 218) and color[1] != color[2]:
            pyautogui.click(point[0], point[1])

    time.sleep(0.0001)

В цикле for программа пробегает по всем координатам для клика мышью, но на каждой итерации делается снимок экрана, и перед нажатием определяется цвет пикселя, на который указывает курсор. Важно, что метод getpixel возвращает кортеж с тремя числами, которые характеризую цвет по системе RGB. Методом тыка я пришел к выводу, что для определения цветка нам достаточно, чтобы первое число в картеже было в диапазоне от 134 до 218, а вот если второе и третье число равны, это уже свидетельствует о сером оттенке, в которые выкрашены бомбы, и на такое кликать не стоит. Соответствующие условия я и передал в конструкцию if.

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

def main():
    keyboard.add_hotkey('`', change_clicker)
    keyboard.add_hotkey('=', mouse_posotion)

    try:
        while True:
            if work:
                clicker(points)

    except KeyboardInterrupt:
        print('\nВыход из программы')


if __name__ == '__main__':
    main()

Вот такая простенькая, но многофункциональная программа получилась. Код целиком:

"""
После запуска скрипта необходимо назначить координаты двадцати кликов:
1. Переместить курсор в нужное место.
2. Нажать клавишу '=' (равно). В коносли будут прописаны номер точки и координаты.
Повторить для каждой из 20 позиций кликов.
3. Для запуска кликера нажать тильду (Ё).
4. Остановить кликер - нажать тильду (Ё).
"""

import pyautogui
import keyboard
import time

work = False
points = [(0, 0) for _ in range(20)]
index = 0

def mouse_posotion():
    global index
    x, y = pyautogui.position()
    points[index] = x, y
    print(f'Координаты точки {index + 1}: X: {x}, Y: {y}', end='\r')
    index += 1
    if index > 19:
        index = 0

def change_clicker():
    global work
    work = not work

def clicker(points: list):
    for point in points:
        screenshot = pyautogui.screenshot()
        color = screenshot.getpixel((point[0], point[1]))
        if color[0] in range(134, 218) and color[1] != color[2]:
            pyautogui.click(point[0], point[1])

    time.sleep(0.0001)


def main():
    keyboard.add_hotkey('`', change_clicker)
    keyboard.add_hotkey('=', mouse_posotion)

    try:
        while True:
            if work:
                clicker(points)

    except KeyboardInterrupt:
        print('\nВыход из программы')


if __name__ == '__main__':
    main()

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

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

И последнее, эффективность описанного кода сейчас зависит только от стратегии, по которой вы разместили точки для кликов. У меня результат был так себе, но я нашел самый эффективный способ для фарма в таких простых играх - это дети. Хотя это уже читерство, согласен.

Комментарии (11)


  1. cryptoscam
    05.06.2024 18:00
    +7

    истерия по хомячку набирает обороты.

    Даже ГосДумеры в срочном порядке наконец-таки утвердили все свои "хотелки-непонималки", чтобы побыстрей оформить всех промышленных майнеров, а то как говорится "налоги не ждут", того и гляди, наряду с термином "майнер" введут дополнительное "нищий тапер", дабы не обойти вниманием школьников (а то вдруг они что-то там заработали?), ведь до учебного года еще далеко, а усердно долбить пальцем, считая что "ну наконец-то ты полноценный трудяга", повадились почти все, не отдавая себе отчет в абсурдности происходящего. Возможно потом внесут свои трудовые заслуги в резюме, так и напишут "отчаянно тапал все каникулы, стер в кровь три фаланги"...

    Да и кому какая разница, раз платят монетками? Хорошо хоть не заставляют биться пустой башкой об телефон с включенной селфи-камерой, чтобы все по-честному, без подлога. Возможно, оставили это важное нововведение для обновленной версии этого шлака.

    Про сам шиток и написать нечего, он традиционно пуст, как и всё, выходящее из под Дурова. Но, разумеется, с громким пуком, иначе никак. На одном пуке и держится вся эта "хлипкая империя". Этот же анонсировал какое-то там "большое обновление", опять наверное селфи пупка будет показывать, ну, с кирпичиками пресса ага...

    А какой маркетинг, просто слов нет. Все лаконично и просто, в лучших традициях Татьяныча - коротко и (простите за самоповтор) с громким пуком. Раз уж ТОН-2 не решился назвать, тогда "либо кверху ногами(лого), либо задом наперед(тикер)". Гениальность решения равна лаконичности, помноженной на время генерации идеи (несколько секунд, не слезая с толчка). Зачем заморачиваться, если нлп-обезьяны все итак схавают и бесплатно превознесут до небес, достаточно им показать кубики пресса, мол смотрите, будущее монеты в надежных руках.

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


    1. Devastor87
      05.06.2024 18:00

      Хорошо хоть не заставляют биться пустой башкой об телефон с включенной селфи-камерой

      Не подавайте им идей :)


    1. qwerty2299
      05.06.2024 18:00

      ахахах пока ты ходишь на работу я тапаю хомяка и зарабатываю доллары, можешь плиз не так сильно завидовать мне ок?


  1. reasoned_critique
    05.06.2024 18:00

    Для начинающего полезно, спасибо. Игры - хороший старт и с интересом


  1. DmSting
    05.06.2024 18:00

    Давно и успешно делаю тоже самое что и автор в UOPilot (не реклама) :)

    Мало того, что можно реагировать на цвет определённого пикселя, можно оочень много всего - нажимать на кнопки на клавиатуре, ресайзить окна, писать логи в файл, вызывать WinAPI события, и тэдэ и тэпэ.

    Главное не забывать добавлять условие остановки по горячей клавише - а то основной цикл бесконечный, она так и будет отбирать у пользователя клавиатуру и мышь пока шнур питания не выдернешь.


    1. temabed Автор
      05.06.2024 18:00

      Эффективно, но не спортивно)


    1. xsevenbeta
      05.06.2024 18:00
      +1

      UOPilot который создавался для автоматизации Ultima Online был хорош ровно до тех пор, пока не появился Inject и EasyUO, где можно было напрямую получать игровые объекты, их тип и расстояние до них.

      Что касается игровой автоматизации, то у AutoHotKey и AutoIt гораздо более функциональны, распространены и для них написаны потрясающие библиотеки; гораздо больше документации и хороших примеров. Но в 2D игры почти закончились, а в 3D без OpenCV и ML особо не сунешься, поэтому пайтон лучший выбор.


      1. temabed Автор
        05.06.2024 18:00

        На радость сишникам игру на Python не написать, зато можно неплохо в них поиграть)


  1. datacompboy
    05.06.2024 18:00

    А как получить экран -- через adb ? Или запуск в эмуляторе?

    p.s.: если кому надо инвайт на блюм -- пингатине в личку, есть еще лишние


  1. polRk
    05.06.2024 18:00

    Камон, по апи нужно отправить 1 запрос…


  1. losander
    05.06.2024 18:00

    Блин только недавно пытался сделать подобное только с cv2, что бы он находил пиксели с нужным RGB, но не получилось и забросил. А тут оказывается можно ещё проще сделать.