Как создать бота с игрой в телеграмм c помощью Python.
Hello World!
Недавно я писал бота для телеграмм и один мой знакомый рассказал, что в телеграмме есть еще и игры. Мне стало интересно и я решил прогуглить. Идея игр в телеграмм мне понравилась и я подумал, что было бы хорошо интегрировать данную опцию в моего телеграмм бота, так как это добавит интерактивности. Телеграмм ботов я разрабатываю на Python, используя при этом библиотеку pyTelegramBotAPI. Вообщем, я начал искать и , к сожалению, не нашел нужной для меня информации, собранной в одном месте и на русском языке. Но как-то у меня получилось собрать все в кучу и немного разобраться с играми в телеграмм и теперь я хочу поделиться этим с вами. Сразу скажу, что в данной статье не будет каких-то детальных технических особенностей и тому подобных вещей. Начинаем.
Так, в статье я предполагаю, что у вас уже установлена библиотека pyTelegramBotAPI, а также вы более или менее понимаете, как создавать телеграмм ботов. В противном случае со всем этим вы можете ознакомиться в Интернете — информации достаточно.
Итак, импортируем библиотеку pyTelegramBotAPI, создаем бота с помощью BotFather и создаем объект бота используя токен, который выдал нам BotFather.
Хорошо, давайте теперь создадим игру. Делается это также с помощью BotFather. Пишем /newgame и следуем дальнейшим инструкциям.
Окей, дальше, когда вы согласитесь(или не согласитесь ) с условиями пользователя, BotFather напишет, что ваш бот работает не в inline_mode, а бот с игрой должен работать именно в этом режиме. Но это не проблема. Просто пропишите команду /setinline и BotFather выдаст вам список ваших ботов и предложит выбрать какого из ботов вы хотите перевести в inline режим. Смело выбирайте какого-то из своих ботов.
Пишем бота-кликера на Python для Lineage 2
Как можно развлечься в новогодние праздники? Поиграть в компьютерные игры? Нет! Лучше написать бота, который это будет делать за тебя, а самому пойти лепить снеговика и пить глинтвейн.
Когда-то в школьные годы был увлечен одной из популярных MMORPG — Lineage 2. В игре можно объединяться в кланы, группы, заводить друзей и сражаться с соперниками, но в общем игра наполнена однообразными действиями: выполнением квестов и фармом (сбор ресурсов, получение опыта).
В итоге решил, что бот должен решать одну задачу: фарм. Для управления будут использоваться эмулированные клики мыши и нажатия клавиш клавиатуры, а для ориентирования в пространстве — компьютерное зрение, язык программирования — Python.
Вообще, создание бота для L2 дело не новое и их готовых есть довольно много. Делятся они на 2 основные группы: те, которые внедряются в работу клиента и кликеры.
Первые — это жёсткий чит, в плане игры пользоваться ими слишком уж неспортивно. Второй вариант интереснее, учитывая, что его можно будет с некоторыми доработками применить к любой другой игре, да и реализация будет интереснее. Те кликеры, которых я находил, по разным причинам не работали, либо работали нестабильно.
Внимание: вся информация здесь изложена только в познавательных целях. Особенно для разработчиков игр, чтобы помочь им лучше бороться с ботами.
Работа с окном
Тут все просто. Будем работать со скриншотами из окна с игрой.
Для этого определим координаты окна. С окном работаем с помощью модуля win32gui. Нужное окно определим по заголовку — “Lineage 2”.
Получаем картинку нужного окна с помощью ImageGrab:
Теперь будем работать с содержимым.
Поиск монстра
Самое интересное. Те реализации, которые я находил, мне не подошли. Например, в одном из популярных и даже платном это сделано через игровой макрос. И “игрок” должен для каждого типа монстра прописывать в макросе типа “/target Monster Name Bla Bla”.
В нашем случае мы последуем такой логике: в первую очередь найдём все тексты белого цвета на экране. Белый текст может быть не только названием монстра, но и именем самого персонажа, именем NPC или других игроков. Поэтому надо навести курсор на объект и если появится подсветка с нужным нам паттерном, то можно атаковать цель.
Вот исходная картинка, с который будем работать:

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

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

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

Находим середины получившихся пятен
Работает, но можно сделать прикольнее (например, для монстров, имена которых не видны, т.к. находятся далеко) — с помощью TensorFlow Object Detection, как тут, но когда-нибудь в следующей жизни.
Теперь наводим курсор на найденного монстра и смотрим, появилась ли подсветка с помощью метода cv2.matchTemplate. Осталось нажать ЛКМ и кнопку атаки.
С поиском монстра разобрались, бот уже может найти цели на экране и навести на них мышь. Чтобы атаковать цель, нужно кликнуть левой кнопкой мыши и нажать «атаковать» (на кнопку «1» можно забиндить атаку). Клик правой кнопкой мыши нужен для того, чтобы вращать камеру.
На сервере, где я тестировал бота, я вызвал клик через AutoIt, но он почему-то не сработал.
Как оказалось, игры защищаются от автокликеров разными способами:
- поиск процессов, которые эмулируют клики
- запись кликов и определение, какого цвета объект, на который кликает бот
- определение паттернов кликов
- определение бота по периодичности кликов
А некоторые приложения, как клиент этого сервера, могут определять источник клика на уровне ОС. (будет здорово, если кто-нибудь подскажет как именно).
Были перепробованы некоторые фреймворки, которые могут кликать (в т.ч. pyautogui, robot framework и что-то еще), но ни один из вариантов не сработал. Проскользнула мысль соорудить устройство, которое будет нажимать кнопку (кто-то даже так делал). Похоже, что нужен клик максимально хардварный. В итоге стал смотреть в сторону написания своего драйвера.
На просторах интернета был найден способ решения проблемы: usb-устройство, которое можно запрограммировать на подачу нужного сигнала — Digispark. 
Ждать несколько недель с Алиэкспресса не хочется, поэтому поиски продолжились.
Библиотека у меня не завелась на питоне 3.6 — вываливалась ошибка Access violation что-то там. Поэтому пришлось соскочить на питон 2.7, там всё заработало like a charm.
Движение курсора
Библиотека может посылать любые команды, в том числе, куда переместить мышь. Но выглядит это как телепортация курсора. Нужно сделать движение курсора плавным, чтобы нас не забанили.
По сути задача сводится к тому, чтобы перемещать курсор из точки A в точку B с помощью обертки AutoHotPy. Неужели придется вспоминать математику?
Немного поразмыслив, всё-таки решил погуглить. Оказалось, что ничего придумывать не надо — задачу решает алгоритм Брезенхэма, один из старейших алгоритмов в компьютерной графике:
Прямо с Википедии можно взять и реализацию
Логика работы
Все инструменты есть, осталось самое простое — написать сценарий.
- Если монстр жив, продолжаем атаковать
- Если нет цели, найти цель и начать атаковать
- Если не удалось найти цель, немного повернемся
- Если 5 раз никого не удалось найти — идём в сторону и начинаем заново
Из более-менее интересного опишу, как я получал статус здоровья жертвы. В общих чертах: находим по паттерну с помощью OpenCV элемент управления, показывающий статус здоровья цели, берём полоску высотой в один пиксель и считаем в процентах, сколько закрашено красным.
Теперь бот понимает, сколько HP у жертвы и жива ли она еще.
Основная логика готова, вот как теперь он выглядит в действии:
Для занятых я ускорил на 1.30
Остановка работы
Вся работа с курсором и клавиатурой ведется через объект autohotpy, работу которого в любой момент можно остановить нажатием кнопки ESC.
Проблема в том, что всё время бот занят выполнением цикла, отвечающим за логику действий персонажа и обработчики событий объекта и autohotpy не начинают слушать события, пока цикл не закончится. Работу программы не остановить и с помощью мыши, т.к. бот управляет ей и уводит курсор куда ему нужно.
Нам это не подходит, поэтому пришлось разделить бота на 2 потока: слушание событий и выполнение логики действий персонажа.
Создадим 2 потока
и теперь вешаем обработчик на ESC:
при нажатии ESC устанавливаем событие
и в цикле логики персонажа проверяем, установлено ли событие:
Теперь спокойно останавливаем бота по кнопке ESC.
Заключение
Казалось бы, зачем тратить время на продукт, который не приносит никакой практической пользы?
На самом деле компьютерная игра с точки зрения компьютерного зрения — почти то же самое, что и снятая на камеру реальность, а там возможности для применения огромны. Отличный пример описан в статье про подводных роботов, которые лазером стреляют по лососям. Также статья может помочь разработчикам игр в борьбе с ботоводами.
Ну а я ознакомился с Python, прикоснулся к компьютерному зрению, написал свой первый слабоумный искусственный интеллект и получил массу удовольствия.
Надеюсь, было интересно и вам.
How to Build Android Gaming Bot With Python
Building an android gaming bot is an exciting venture because it demands skills in diverse areas such as windows API, machine vision, multi threading and in some cases you need very intimate knowledge of computer systems to optimize certain parts of your code. So, this project is definitely not for the faint of heart. But if you like to grapple with complex problems than welcome to this exciting journey.
Set up Your Development Environment
This is a very CPU intensive project due to the involvement of an android emulator. At minimum you must have a computer with 8 GB ram and ideally an SSD and 2 GB Graphics Card. You can get away with 4 GB ram and a regular HDD but you can’t run multiple instances of android emulator in this case, in fact your whole development/testing process will be terribly slow.
Other than hardware you must have
- Windows 10 Pro
- MemuPlay Android Emulator
Pro Tip: If you want your bot to open multiple android instances in paralell, make sure you have SSD. Its excruciatingly high IO operation and Memuplay will generate weired errors if its starving on disk bandwidth.
Python Environment
Why You Should Get MemuPlay Premium
In recent months MemuPlay has started to show tons of ads, Its now increasingly difficult to use any bot with memu. So if you are serious about developing bots its important to get premium subscription of memu play.
There are workarounds to handle these ads but thats not worth the trouble.
Lets Start Coding
Before you begin you should be comfortable with memuc which is a command line interface. We will use this utility to control MemuPlay (Documentation of memuc is available here). By default memuc is not available on Windows path. You will need to manually put it there to call it from python or you can simply call the memuc using its full path just like I did it in following code. Here is a minimum list of functions which our bot will need to perform.
- Open / Close MemuPlay instance
Our bot should be able to send commands to Memu to control the instances. Create a file vm.py and enter the following code.
Create a new file main.py and enter following code
Now open Multi-MEmu (Multiple Instance Manager) and create a android emulator instance. In memu each android instance is recognized and controlled using its index no. For example, in my case the index no is 2.

Finally run the main.py file and you will quickly see that android instance start to load.
How the above code works
start_vm function is basically very straightforward. I am sending start -i 2 command to memuc via python subprocess. Which basically means I am telling memuc to start android vm which has index 2. If subprocess doesn’t generate any error it will generate output like this
If you take a closer look at start_vm function you can see I am sending output of my memuc command to stdout. You easily access it by calling vm.stdout.
Error Handling
Just like any other software there is an inherent assumption that your bot can break at some point due to any error. In our case the situation is quite complicated because its not just your own code which can fail but MemuPlay itself can crash your bot If you have not handled errors properly.
For example consider the start_vm function again. In some cases output (stdout) of our memuc command will be “ERROR: start vm failed” but in reality memu start the android instance without any issue. So this is a case where we have to check manually whether instance is actually started or not. For that purpose we will write another function find_window in vm.py file.
The above function is your starting point in WindowsApi. We are calling FindWindow to check whether a window with specified title is available or not. When memu open an android instance it sets its window title to (InstanceName). For example my instance name is MEmu2 its window title will be (MEmu2). If there is no window found with our provided title FindWindow return 0.
2. Closing the Android Instance
Our next task is to close the android instance. Add the following code in vm.py file.
Now first start any android instance using multi memu. Than add following code in main.py and run it. Don’t forget to change vm index and title in following code.
How stop_vm works
Its very similar to start_vm. Basically we are sending command to close android instance with a specified index. After taking a pause of 1 second we check whether our command actually close the instance. This can be achieved easily by using the find_window function which we wrote previously. It checks whether there is any window running with a specific title. If not the command has executed successfully otherwise command failed and we will forcefully close the instance window by using Windows API.
For this purpose we will use force_close_window function. Its simply instructs to Windows OS to close the window. Basically we are using PostMessage API to send “CLOSE” command to a window. In almost all cases this function works flawlessly.
In some cases memu doesn’t close an android instance even though we have given it stop command. In order to deal with this situation I have written the force_close_window function.
3. Start Game
Its time to actually start the game. First of all start an android instance and login to google play store and install mafia city game. In my case I have already installed the game on MEmu2. If you are new to MafiaCity it will take a while to setup your account, just like any other game in this genre the game forces you to complete lot of steps like constructing buildings, training troops etc… Unfortunately its a lengthy process and you must have to complete this step before we use it with bot.
Ok, now the game stuff is out of our way, lets focus on coding. add the following code in vm.py
Lets test the above code, add following code in main.py
Before running the above code make sure you run the andoird instance where you have installed the mafiacity game. Once you run the code Mafiacity game will run and mafiacity process id will be printed in terminal.
How start_game Works
start_game is again a simple command to memu. We are asking it to start app “ com.yottagames.mafiawar ” in android instance with index is 1. If there is no error, the output of our command will be SUCCESS: start app finished . But for our case this output is not enough to confirm whether game is actually running or not. So we will write a function verify_game_process which runs an adb command to check whether there is com.yottagames.mafiawar process is running?
Error Handling in start_game
There are three categories of errors related to start_game. First one belongs to our bot, in most cases its usually the wrong vm_index or possibly wrong address of memuc execution file. They are very easy to fix. Second category related to MemuPlay itself. In some cases, where you are opening/closing multiple android instances back to back in automated fashion plus your PC doesn’t have SSD, the sart game command doesn’t work due to error . Its rare but it happens
Third category related to Mafia City itself. When you will run game it can generate all sorts of error such as network connection, corrupted database of game, problem with mafiacity servers. In some cases game just stuck on loading screen, if its not network problem, it usually means that android instance is corrupted.
I ll go into detail later on how to handle these errors. Because we can’t catch these errors with python’s try. except clause.
Its important that we handle all possible errors in start_game function because if we don’t our bot will be highly unstable.
How To Take Screenshot Of a Window With Python
Taking screenshot of entire screen is straightforward in python, but if you want to take screen shot of an individual window that’s bit tricky, it requires directly calling windows api. There is no seperate library exists for this task. Memu opens each VM in its seperate window, in order to work properly, our bot should know what’s going on in each VM’s window. At any given moment, our bot will open 3 to 4 windows in parallel, that’s why full screen screenshot is useless in our case.
save the following code in “screenshot.py” file.
How The Screenshot Code Works
Before we move further, you need to learn how to take screenshot of an individual window using python. It will give awareness to your bot, what’s going on the screen.
take_screenshot function takes window_title as argument. Memu assigns name of the VM as window title. For example in our case the window title will be something like this ‘(Memu2)’. First of all we need to get handle to a window called HWND.
The above line is a Win32 Api call where we are getting a handle to a window through its title. Next step is to call “GetClientRect”.
The above line retrieves the coordinates of the window client area. Here you need to remember an important thing. Just like GetClientRect, there is another function called GetWindowRect which returns the rect in screen coordinates. The window rect includes the non-client area for example window borders, caption bar etc. The client rect does not.
The remaining code of take_screenshot requires some rigorous knowledge of Win32 api in order to understand why this code works. For the moment, you should ignore the complexity of this function.
Test Our ScreenShot Code
For a quick test add following line at the end of screenshot.py. I am taking screen shot of power shell window. Make sure the window title you are giving to this function is accurate otherwise you will see a black image. Now run the screenshot.py file. It will generate an image test.png in the same directory where screenshot.py file is saved.
In my case the output looks something like this.

If your test is successful you will see an image of your window, otherwise you need to recheck the title of the window.
How to Recognize An Object Within An Image
Our next critical task is to implement some critical object recognition functionality. Although image recognition is quite a deep subject, I wont delve into details here how recognition works. For the purpose of this bot I am reusing some code from pyAutoGui library. This library is awesome but unfortunately, it doesn’t provide all the functionality we need for our bot.
So we need to build a custom function verify_screen to meet our following requirements.
- It will take screenshot of a given window title after every x seconds, upto a certain number of retries with a given confidence value.
- It will check whether the image object we passed in arguments actually spotted in screenshot.
- If Image detected/or not detected return results appropriately, either in True/False or return screen coordinates where the image object is located in screen shot. This will help us later on If we want to click on it.
First of all create a new file locateImage.py and paste the following code in it and save it alongside other files.
The above code was extracted from PyAutoGUI and its dependent on OpenCV. If you are not familiar with opencv you can skip the above code and later on check how the above code works. For the moment just use as it is.
Next create another file called android.py and paste the following code in it. This file will be responsible for handling our all interaction with android.
Frankly the above code I have written is very ugly and requires some serious refactoring. But for now we ll use as it is. Your task for the moment is to run the above function, try to get the screen coordinates of an image object within a screenshot and share your results with me.
Как написать игру для ICQ на Python
Приветствую. Сегодня хотелось бы написать простого ICQ бота для игры в «Угадай число», где у пользователя будет неограниченное количество попыток, а диапазон чисел составит от 1 до 99 для отгадывания. Сразу хотелось бы сказать, что данный бот работает не совсем так, как хотелось бы, это можно увидеть по фото ниже, т. к. я в этом начинающий.
Устанавливаем библиотеку для ICQ ботов
Для начала нам понадобится сам Python, и специальная библиотека для работы с ботами, качаем её через pip:
Теперь, переходим в ICQ и ищем в поиске @metabot. Создаём бота, скопировав и сохранив токен. В дальнейшем он нам понадобится.
Код игры
Оставьте программу активной и перейдите в ICQ. Найдите своего бота в списке и отправьте команду /start.