C#使ってWindowをキャプチャしたり、マウスイベントを送信したりする
背景
カァーッ、ゲームのボット作りてぇナァーッ
ソースコード
GitHubで公開してます。こちら。
https://github.com/kokeiro001/Kagamitsuki
できること
- 任意のウィンドウをキャプチャし、Bitmapインスタンスとして取得できる
- キャプチャ対象によっては他のウィンドウに隠れていても取得できる
- 任意のウィンドウに対し、マウスイベントを送信できる
- クリック、マウスカーソルの移動のみサポート
ざっくりとした使い方
GitHubリポジトリのSampleConsoleApp見れば何となく分かると思います。
これ。
https://github.com/kokeiro001/Kagamitsuki/blob/master/Kagamitsuki.SampleConsoleApp/Program.cs
WindowCapture
ウィンドウキャプチャするやつです。キャプチャ対象のウィンドウハンドルを渡す必要があります。
サンプルプロジェクトではWindowNativeHelper.GetWindowsメソッドを使ってます。System.Diagnostics.Process.GetProcessesメソッドを使って絞り込むことも出来ます。お好みで。
その後はCaptureメソッド呼べばキャプチャ画像が取得できます。終わり。
コンストラクタにキャプチャ範囲を渡すことで、ウィンドウの特定の範囲のみキャプチャすることが出来ます。大体の場合はウィンドウのタイトルバーとか不要で、ゲームの範囲だけ必要なのでいい感じに調整してくださいな。
VirtualMouse
ウィンドウに対してマウスのイベント送信するやつです。こいつも送信先対象のウィンドウハンドルを渡す必要があります。
生成したあとはClickメソッドとかMoveメソッド呼べば動きます。終わり。
こいつもWindowCaptureと同じく、クリック座標の原点を指定できます。無指定のままだとタイトルバー込の位置指定になっちゃいますが、任意の位置を指定することでゲームの範囲に集中することが出来ます。
ClickメソッドにはClickAsyncも用意してます。Clickメソッドはマウスボタン押す→ボタン離すが一瞬で行われます。マジで一瞬で。これで問題ないプログラムならそれでいいんですが、場合によってはボタン押して、0.2秒待って、ボタン離すみたいな動作が必要なことがあります。そういうときにAsync版使ってください。離すまでにディレイかけられます。
今後の課題、現状の問題点
描画順の都合、描画方法の違いの都合のため、キャプチャできるウィンドウとキャプチャ出来ないウィンドウとが存在します。
ブラウザ毎に下記のような違いがあります。
- Firefoxはウィンドウが他のウィンドウに隠れていてもキャプチャできます。神。マウスイベントも送信できます。神。
- InternetExprolerは他のウィンドウに隠れているところは他のウィンドウごとキャプチャしちゃいます。
- Chromeは真っ黒です。キャプチャできません。
とりあえずKagamitsuki使ってブラウザのキャプチャ、操作したい場合はFirefox系一択です。Firefoxは派生ブラウザ多く、その大体が本家同様の挙動を示すので好みのを使ってくださいな。
後記
OpenCvSharpとかと組み合わせることで、ちょっぴり賢いゲームのボットなんかも作れます。やったね。
ブログ投稿時点で既に8年くらい前のコードになりますが、マインスイーパーを自動で解かせてたやつがこちら。
https://github.com/kokeiro001/AutoMinesweeperSolver
Windows7のマインスイーパー向けのハードコードが多いので、Windows10だと動かないでぇす。
ココから必要な部分だけ引っこ抜いてきたのがKagamitsukiです。
今後作るボット次第でマウスホイールとかドラッグのサポート増えてくと思います。今後作るボット次第。