📜 ⬆️ ⬇️

Game bots. Start

What could be more interesting than the process of playing games? Right! The process of observing how the game is written by you bot.

For a while, I thought about what to write my first article. I wanted to write about microcontroller programming, but it turned out to be difficult to separate parts of working projects from those that can be published without looking at my colleagues. Stopped on the idea of ​​bots.

Introduction

I would roughly divide bots for online games into 3 types according to the methods of implementation:
1. Bots that do not use the game application. Simulating the exchange protocol with the server.
2. Bots working with the game application process. In the case of the Web, working with a browser window.
3. Bots working with a screenshot and simulating input devices mouse and keyboard.

The first type is rather hypothetical, since protocols are usually closed and not trivial.
The first type is more suitable for bots with simple and textual protocols. If binary data is transmitted to the server, then it is necessary to understand its structure, which complicates the task.
')
The second type is more real and can be realized. The bot of the second type receives useful information from the memory of the game process. The disadvantage is that versions of clients can be updated regularly and then you may need to re-search for interesting memory addresses.

We will consider the third kind of bots, because IMHO they are more attractive, though not without drawbacks.
And also, this approach is more sporty :-)

In this article I will look at a set of tools for the simplest bot for Windows.

For the simplest bot, it is enough to emit mouse and keyboard events. In most cases, this turns out to be sufficient for solving (not the most effective, but not requiring human participation) routine tasks in various games. To work more efficiently, the bot requires feedback from the game, i.e. receiving and processing screenshots of the game.

Code

For application development, I will use Qt Creator + Qt 5 either (I’m used to it), and once the bot for Windows is + windows.h (WinAPI).

Includes:
#include <windows.h> // WinAPI #include <iostream> // std::cout #include <unistd.h> // sleep(), usleep() #include <math.h> 


Header bot:

 //   enum { menu=0, elm_1, points_cnt }; class MyBot { public: MyBot(); void run(); void move_to(int inx); void lclick_to(int inx); void rclick_to(int inx); void drag(int from_inx,int to_inx); POINT point[points_cnt]; }; 


Constructor:
 MyBot::MyBot() : //     (     ) point({ {100,100}, // 0 - menu {130,130}, // 1 - elm_1 }) { } 


Register hotkeys to control the bot:

  RegisterHotKey((HWND)Widget::winId(), 101, MOD_ALT, VK_F1); //   RegisterHotKey((HWND)Widget::winId(), 102, MOD_ALT, VK_F2); // inx++ RegisterHotKey((HWND)Widget::winId(), 103, MOD_ALT, VK_F3); //   inx RegisterHotKey((HWND)Widget::winId(), 104, MOD_ALT, VK_F4); //   inx RegisterHotKey((HWND)Widget::winId(), 105, MOD_ALT, VK_F5); //      


Handling bot control buttons event handling:

 int inx=0; MyBot bot; bool Widget::nativeEvent(const QByteArray & eventType, void * message, long * result){ Q_UNUSED(result); Q_UNUSED(eventType); MSG* msg = reinterpret_cast<MSG*>(message); if(msg->message!=WM_HOTKEY)return false; switch(msg->wParam){ case 101: // Alt-F1 -   bot.run(); return true; case 102: // Alt-F2 - inx++ if(inx<points_cnt-1)inx++; return true; case 103: // Alt-F3 -   inx bot.move_to(inx); return true; case 104: // Alt-F4 -   inx GetCursorPos(&bot.point[inx]); return true; case 105: // Alt-F5 -      for(i=0;i<points_cnt;i++){ std::cout << "{" << bot.point[i].x << "," << bot.point[i].y << "}, //" << i << std::endl; } return true; } return false; } 


Move the mouse to the desired point:
(not very carefully done, I promise to fix it :-))
 #define width 1920 #define height 1080 void MyBot::move_to(int inx){ int x=point[id].x; int y=point[id].y; POINT pt; GetCursorPos(&pt); int from_x=pt.x; int from_y=pt.y; int to_x=x; int to_y=y; int dx=to_x-from_x; int dy=to_y-from_y; float fdx; float fdy; int loop_cnt; if(abs(dx)>abs(dy) && dx!=0){ fdx=dx<0? -1.0 :1.0; fdy=(float)dy/abs(dx); loop_cnt=abs(dx); } else if(dy!=0){ fdy=dy<0? -1.0 :1.0; fdx=(float)dx/abs(dy); loop_cnt=abs(dy); } else return; //   1  int time=1000000/loop_cnt; float fx=from_x; float fy=from_y; for(int i=0;i<loop_cnt;i++){ fy+=fdy; fx+=fdx; int nx=(fx)*(65536 / width); int ny=(fy)*(65536 / height); mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,nx,ny,0,0); usleep(time); } usleep(50000); } 


Clicks:

 void MyBot::lclick_to(int inx){ move_to(inx); mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0); usleep(50000); mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0); usleep(100000); } void MyBot::rclick_to(int inx){ move_to(inx); mouse_event(MOUSEEVENTF_RIGHTDOWN,0,0,0,0); usleep(50000); mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0); usleep(100000); } 


Drag and Drop:

 void MyBot::drag(int from_inx, to_inx){ move_to(from_inx); usleep(50000); mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0); usleep(70000); move_to(to_inx); mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0); usleep(30000); } 


Bot's job:

 void MyBot::run(){ rclick_to(menu); //        lclick_to(elm_1); //       } 


User manual

Before launching the bot with the Alt-F1 hot button, the bot must first be configured, determining the correct coordinates of the controls on which the bot will click.
To memorize the coordinates of the point, we point the pointer to the place and press Alt-F4.
To check the correctness of the point, move the pointer to the side and press Alt-F3.
To set the next point, press Alt-F2.
To save the correct coordinates, press Alt-F5.

Underwater rocks

Experience shows that you should not rush to click on the controls and move the pointer. Often the games slow down, when you hover the mouse over the button, the backlight rendering and other unknown processes work and haste leads to a failure of the click or capture when dragging, etc. and as a result, the bot's inoperability. With manual control, people usually do not even notice such annoying trifles, since feedback through organs of vision works. The solution is to pause after all the elementary actions.

The game window can be arbitrarily minimized due to the appearance of a message from the Windows or for some other reason. The program of the sequence of clicks and pauses is to provide a click on the icon of the minimized game.

Qt Creator: qt-project.org/downloads
Project source code on github: github.com/rumaster/my_bot_v1

PS Do not think that I am an ardent opponent of online games, once I publish the source codes of bots. I am opposed to discrimination of AI (bots) and for the development of it. And yet, the game - the engine of progress.

PPS Speaking of AI, I mean a program capable of receiving and processing (analyzing) information, planning and performing actions in accordance with the goals and results of a situation analysis.

Source: https://habr.com/ru/post/212779/


All Articles