たくのろじぃのメモ部屋

プログラミング関係や数学、物理学などの内容を備忘録として残すブログ。プログラミングはC#を中心に書いています。

【C#】Minecraft自動化 #8 プレイヤー自動操作

久しぶりの自動化です。今回はコマンドを投げるわけではなく、プレイヤー自身を動かすためのプログラムを書きます。

実行環境

1. ウィンドウのアクティブ化

まずは起動しているウィンドウをアクティブにする必要があります。アクティブはそのウィンドウが選択された状態です。

アクティブ化するにはアノテーションが必要です。今回使用するアノテーションDLLImportuser32.dll を読み込みます。これはウィンドウAPIすなわちインターフェースを操作するためのDLLです。

また、ウィンドウを指定するのに前回の記事で書いたプロセス名を使用します。マインクラフトのプロセス名は javaw です。

IntPrt はポインタを渡すための構造体らしいのですが、詳しくはよくわかりません。引数にはプロセスのウィンドウハンドル(イベント)が入るようです。

[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);

2. キー入力

プレイヤーを動かすには W, S, A, D のいずれかのキーを押して動かしますが、これをC#からやるためには参照が必要です。

必要な参照は Windows.Forms です。これを参照すると、SendKeysクラスが使用できます。キーを入力するには SendWait メソッドを使用します。引数は文字列型なので入力したいキーを二重引用符で囲みます。

キー入力を連続入力する場合は {キー 回数} を文字列として引数に入れることでできます。連続入力しないとプレイヤーを動かせないのでこの形で入れるのをおススメします。繰り返し文で回してもいいですが、こっちのほうが楽できます。

以上を踏まえて実装します。

class Program
{
    static void Main(string[] args)
    {
        SendToMinecraft();
    }

    [DllImport("user32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);

    public static void SendToMinecraft()
    {
        //マイクラのプロセス
        var process = Process.GetProcessesByName("javaw");

        SetForegroundWindow(process[0].MainWindowHandle);
        Console.WriteLine("Press W key...");
        SendKeys.SendWait("{W 1000}");
        Thread.Sleep(500);
        Console.WriteLine("Press S key...");
        SendKeys.SendWait("{S 1000}");
        Console.WriteLine("Press D key...");
        SendKeys.SendWait("{D 1000}");
        Thread.Sleep(500);
        Console.WriteLine("Press A key...");
        SendKeys.SendWait("{A 2000}");
    }
}

3. 実行結果

実行している様子です。

youtu.be

なぜか実行するとしゃがんでしまいます...。

4. おわりに

プログラムを実行すると、アクティブ化したウィンドウにマウスカーソルが持っていかれてしまいます。なので、一瞬視点がおかしくなってしまいます。

今の段階では自動化とは言えないかもしれませんね。