ゲームボット。 開始する

ゲームをプレイするプロセスよりも興味深いものは何ですか? そう! あなたが書いたボットがゲームをする様子を観察するプロセス。



しばらくの間、私は最初の記事を書くことを考えていました。 マイクロコントローラのプログラミングについて書きたいと思っていましたが、作業中のプロジェクトの部分を、同僚を見ずに公開できる部分から分離することは難しいことがわかりました。 彼はボットのアイデアを止めました。



はじめに


実装方法によって、オンラインゲームのボットを大まかに3種類に分けます。

1.ゲームアプリケーションを使用しないボット。 サーバーとの交換プロトコルを模倣します。

2.ゲームアプリケーションプロセスで作業するボット。 Webの場合、ブラウザウィンドウで作業します。

3.スクリーンショットを操作し、入力デバイスのマウスとキーボードをシミュレートするボット。



最初の種類はかなり仮説的なものです。なぜなら、 プロトコルは通常閉じられており、簡単ではありません。

最初の種類は、単純なプロトコルとテキストプロトコルを備えたボットにより適しています。 バイナリデータがサーバーに送信される場合、その構造を理解する必要があり、タスクが複雑になります。



2番目の種類はより現実的で、実装できます。 2番目のタイプのボットは、ゲームプロセスのメモリから有用な情報を受け取ります。 欠点は、クライアントのバージョンを定期的に更新できるため、目的のメモリアドレスを再度検索する必要がある場合があることです。



3番目のボットを検討します。なぜなら、 私見は、欠陥がないわけではありませんが、より魅力的です。

また、このアプローチはよりスポーティです:-)



この記事では、Windows用の最も単純なボット用のツールセットを検討します。



最も単純なボットの場合、マウスとキーボードのイベントを発行するだけで十分です。 ほとんどの場合、これはさまざまなゲームの日常業務を解決するのに十分です(最も効果的ではありませんが、人間の関与は必要ありません)。 ボットがより効率的に機能するには、ゲームからのフィードバックが必要です。 ゲームのスクリーンショットの受信と処理。



コード


アプリケーション開発には、Qt Creator + Qt 5程度(より詳しく)を使用し、Windows用ボットが+ windows.h(WinAPI)である場合を使用します。



含まれるもの:

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







ボットヘッダー:



 //   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]; };
      
      







コンストラクター:

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







ボットを制御するためのホットボタンの登録:



  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); //     
      
      







ボットボタンコントロールイベントの処理:



 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; }
      
      







マウスポインターを目的のポイントに移動します。

(あまり慎重に行われていません。修正することをお約束します:-))

 #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); }
      
      







クリック数:



 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); }
      
      







ドラッグアンドドロップ:



 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); }
      
      







ボット操作:



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







ユーザーマニュアル


Alt-F1ホットボタンでボットを起動する前に、ボットがクリックするコントロールの正しい座標を決定することにより、ボットを最初に構成する必要があります。

ポイントの座標を記憶するには、ポインターをその場所に移動してAlt-F4を押します。

ポイントの正確さを確認するには、ポインターを横に移動してAlt-F3を押します。

次のポイントを設定するには、Alt-F2を押します。

正しい座標を維持するには、Alt-F5を押します。



落とし穴


経験から、コントロールをクリックしてポインタを移動することを急ぐべきではないことがわかります。 多くの場合、ボタンの上にマウスを置くとゲームの速度が低下し、バックライトのレンダリングがトリガーされ、その他の未知のプロセスと急いでドラッグ時のクリックまたはキャプチャの誤動作が発生します。 そして、ボットの操作不能の結果として。 フィードバックは視覚器官を通じて機能するため、手動制御では、人々は通常、そのような迷惑なささいなことにも気付きません。 解決策は、すべての基本アクションの後に一時停止することです。



ゲームウィンドウは、Windowsからのメッセージまたはその他の理由により、任意に最小化される場合があります。 プログラムでは、クリックと一時停止のシーケンスにより、最小化されたゲームのアイコンをクリックする必要があります。



Qt Creator: qt-project.org/downloads

Githubプロジェクトのソースコード: github.com/rumaster/my_bot_v1



PSボットのソースコードを公開しているので、私がオンラインゲームの熱烈な相手だとは思わないでください。 私はAI(ボット)に対する差別と、その開発に反対しています。 それでも、ゲームは進歩の原動力です。



PPS AIと言えば、情報を受信して​​処理(分析)し、状況分析の目標と結果に従ってアクションを計画および実行できるプログラムを意味します。



All Articles