MENU
目次

【HearthstoneReconnector】タスキルツールでバトグラの戦闘をスキップする方法【Battlegrounds】

ハースストーンのタスキルツール

この記事を読むと

目次

HearthstoneReconnectorで出来ること

このツールを利用することで、ハースストーン(バトルグラウンド)の戦闘フェーズをスキップし、酒場フェーズの時間を長くすることができます。
これを通称タスクキルと呼んでいます。

タスキルのメリット

  • 思考時間が増える
  • 勝率が上がる
  • 戦闘が長すぎて雇用フェーズが無くなるケースを防げる
こちらは簡易版ツールの動画です
うる

酒場フェーズが長くなれば忙しい構成では有利ね

U

タスキルすると勝率は間違いなく上がりますね

本アプリケーションのご利用は自己責任でお願いします。一切の責任は負いません。

VS Windowsファイアーウォール

Windowsファイアーウォールによる切断は手軽ですが、挙動が不安定なのでお勧めしません
これはファイアーウォールでHearthstoneの通信を切断する際、再接続するために必要な通信まで切断してしまうためです。

Windowsファイアーウォールの場合

Windowsファイアーウォールの場合、サーバーとHearthstoneの全ての通信を遮断してしまう
Windowsファイアーウォールの場合、すべての通信を遮断してしまう

Reconnectorの場合

Reconnectorはアニメーションスキップに必要な通信のみ切断できる
Reconnectorはアニメーションスキップに必要な通信のみ切断
スクロールできます
Itemメリットデメリット
ファイアーウォール手軽に実装可能挙動が不安定で再接続できない場合が多い
Reconnector
ほぼ100%切断して再接続できる実装が少し手間

私の環境ではファイアーウォール切断時の再接続率が50%くらいだったので、使い物になりませんでした。
雇用フェーズの時間を増やしたいのに、再接続できずに逆に雇用時間が短くなるのは厳しいです。。

ファイアーウォールによるタスキル参考記事

note(ノート)
ダラランのために~数秒でできるタスキル~|chox ■この記事について  この記事では、ハースストーン バトルグラウンドにおいて、雇用フェイズでの操作時間を確保するための手段「タスキル(=タスクキル)」と呼ばれる方...

HearthstoneReconnectorを作成する手順

こちらは簡易版のタスキルツールの作成方法です。
より高機能な構築済みタスキルツールをすぐに利用したい場合は、以下のボタンから構築済みツールをダウンロードしてください。

それではタスキルツールを構築していきましょう。

1. VisualStudioをインストール

Windowsアプリケーションを作成するため、Visual Studioの公式サイトから最新版をインストールしてください。コミュニティエディションでOKです。

Visual Studio
Visual Studio Tools のダウンロード - Windows、Mac、Linux 用の無料インストール Visual Studio IDE または VS Code を無料でダウンロードします。 Windows、Mac で Visual Studio Professional または Enterprise エディションをお試しください。

※Visual Studio Codeではありません

以下のような選択画面が表示されたら、画像のように3つ選択してください。

必要な機能をインストール

2. 新規プロジェクトを作成

① 新しいプロジェクトの作成をクリックしてください。
②「Windows Forms アプリケーション (.NET Framework)」を検索し、C# のテンプレートを選択します。
③ プロジェクト名(例:HearthstoneReconnector)を入力し、適当な保存場所を指定して「作成」をクリックします。

3. コードをコピペ

コードをコピペしてアプリケーションを構築していきます。

Program.cs の編集

プロジェクト作成時に自動生成された Program.cs を開き、以下のコードに書き換えます。

Program.csは画面左上のソリューションエクスプローラーで開いてください。

ソリューションエクスプローラーでProgram.csを開く
ソリューションエクスプローラー
Program.cs
using System;
using System.Windows.Forms;

namespace HearthstoneReconnector
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

Form1.cs の編集

ソリューションエクスプローラーから Form1.cs をダブルクリックしてエディタで開きます。

ソリューションエクスプローラーでForm.csを開く

コードエディターが開かない場合は、フォームの空白部分をダブルクリックすると、Form.csのコードエディターが開きます。

Form.csが開けない場合の開き方
Form.csのエディターが開かない場合は、フォームをダブルクリックして開く


以下のコードをコピペしてください。

Form1.cs
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace HearthstoneReconnector
{
    public partial class Form1 : Form
    {
        private const uint MIB_TCP_STATE_DELETE_TCB = 12;
        private const uint MIB_TCP_STATE_ESTAB = 5;
        private Button btnDisconnect;
        private Timer autoRestoreTimer;
        private Timer restoreTimer;
        private bool enableLogging = true;
        private readonly int targetRemotePort = 3724;
        private Color originalButtonBackColor;

        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Formロード時の処理
        /// ・ウィンドウサイズとタイトルの調整
        /// ・常に最前面に表示する設定 (TopMost)
        /// </summary>
        private void Form1_Load(object sender, EventArgs e)
        {
            // ウィンドウタイトルの設定
            this.Text = "HearthstoneReconnector";
            // 常に最前面に表示
            this.TopMost = true;
            // クライアントサイズを調整(ボタンサイズに合わせ余白を残す)
            this.ClientSize = new Size(350, 140);

            // Disconnect ボタンの生成とデザイン設定
            btnDisconnect = new Button
            {
                Text = "Disconnect",
                Size = new Size(150, 50),
                Location = new Point((this.ClientSize.Width - 150) / 2, 20),
                Font = new Font("Segoe UI", 14, FontStyle.Bold),
                FlatStyle = FlatStyle.Flat,
                BackColor = Color.SteelBlue,
                ForeColor = Color.White,
                Cursor = Cursors.Hand
            };
            // ボタンの枠線設定
            btnDisconnect.FlatAppearance.BorderSize = 2;
            btnDisconnect.FlatAppearance.BorderColor = Color.DarkBlue;
            btnDisconnect.FlatAppearance.MouseOverBackColor = Color.CornflowerBlue;

            // 元の背景色を保持
            originalButtonBackColor = btnDisconnect.BackColor;

            btnDisconnect.Click += BtnDisconnect_Click;
            this.Controls.Add(btnDisconnect);
        }

        /// <summary>
        /// Disconnect ボタン押下時の処理
        /// ・対象通信を切断
        /// ・0.5秒後に切断解除処理(restoreTimer)
        /// ・5秒後にボタンを再有効化(autoRestoreTimer)
        /// </summary>
        private void BtnDisconnect_Click(object sender, EventArgs e)
        {
            // ボタンの連続クリック防止&グレーアウト
            btnDisconnect.Enabled = false;
            btnDisconnect.BackColor = Color.Gray;

            try
            {
                // 対象通信を切断(リモートポートが3724の通信全て)
                ForceDisconnectTargetConnections();

                // 0.5秒後に切断解除処理(今回は何も実施せずタイマー停止のみ)
                restoreTimer = new Timer();
                restoreTimer.Interval = 500;
                restoreTimer.Tick += RestoreTimer_Tick;
                restoreTimer.Start();

                // 5秒後にボタンを再有効化するタイマー開始
                autoRestoreTimer = new Timer();
                autoRestoreTimer.Interval = 5000;
                autoRestoreTimer.Tick += AutoRestoreTimer_Tick;
                autoRestoreTimer.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show("エラー: " + ex.Message);
                btnDisconnect.Enabled = true;
                btnDisconnect.BackColor = originalButtonBackColor;
            }
        }

        /// <summary>
        /// 0.5秒後に呼ばれる切断解除処理(今回は何も行わずタイマー停止のみ)
        /// </summary>
        private void RestoreTimer_Tick(object sender, EventArgs e)
        {
            restoreTimer.Stop();
            restoreTimer.Tick -= RestoreTimer_Tick;
            restoreTimer.Dispose();
            restoreTimer = null;
        }

        /// <summary>
        /// 5秒後にボタンを再有効化するタイマーの Tick イベントハンドラ
        /// </summary>
        private void AutoRestoreTimer_Tick(object sender, EventArgs e)
        {
            autoRestoreTimer.Stop();
            autoRestoreTimer.Tick -= AutoRestoreTimer_Tick;
            autoRestoreTimer.Dispose();
            autoRestoreTimer = null;

            btnDisconnect.Enabled = true;
            // 元の背景色に復元
            btnDisconnect.BackColor = originalButtonBackColor;
        }

        /// <summary>
        /// TCP テーブルから対象の通信(リモートポート 3724 の通信)を切断する
        /// 正常系では切断対象のログのみ出力
        /// </summary>
        private void ForceDisconnectTargetConnections()
        {
            int buffSize = 0;
            uint ret = GetExtendedTcpTable(IntPtr.Zero, ref buffSize, true, AF_INET, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 0);
            IntPtr tcpTablePtr = Marshal.AllocHGlobal(buffSize);
            try
            {
                ret = GetExtendedTcpTable(tcpTablePtr, ref buffSize, true, AF_INET, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 0);
                if (ret != 0)
                    throw new Exception("TCP テーブルの取得に失敗しました。エラーコード:" + ret);

                int rowCount = Marshal.ReadInt32(tcpTablePtr);
                IntPtr rowPtr = IntPtr.Add(tcpTablePtr, sizeof(int));
                int rowSize = Marshal.SizeOf(typeof(MIB_TCPROW_OWNER_PID));
                bool found = false;

                for (int i = 0; i < rowCount; i++)
                {
                    MIB_TCPROW_OWNER_PID tcpRow = (MIB_TCPROW_OWNER_PID)Marshal.PtrToStructure(rowPtr, typeof(MIB_TCPROW_OWNER_PID));
                    
                    if (tcpRow.state == MIB_TCP_STATE_ESTAB)
                    {
                        int remotePort = ntohs((ushort)tcpRow.remotePort);
                        if (remotePort == targetRemotePort)
                        {
                            found = true;
                            // 正常系ログ(対象通信の切断のみ)
                            if (enableLogging)
                            {
                                try
                                {
                                    string logMessage = $"{DateTime.Now}: 切断対象 - リモートIP: {new IPAddress(tcpRow.remoteAddr)}, リモートポート: {remotePort}{Environment.NewLine}";
                                    string logFilePath = Path.Combine(Application.StartupPath, "HearthstoneDisconnect.log");
                                    File.AppendAllText(logFilePath, logMessage);
                                }
                                catch (Exception logEx)
                                {
                                    Debug.WriteLine("ログ出力エラー: " + logEx.Message);
                                }
                            }
                            // 対象通信を切断(DELETE_TCB 状態へ変更)
                            if (tcpRow.state != MIB_TCP_STATE_DELETE_TCB)
                            {
                                tcpRow.state = MIB_TCP_STATE_DELETE_TCB;
                                uint setRet = SetTcpEntry(ref tcpRow);
                            }
                        }
                    }
                    rowPtr = IntPtr.Add(rowPtr, rowSize);
                }

                if (!found)
                    MessageBox.Show("指定された通信が見つかりませんでした。");
            }
            finally
            {
                Marshal.FreeHGlobal(tcpTablePtr);
            }
        }

        /// <summary>
        /// ネットワークバイトオーダーからホストバイトオーダーへの変換(16bit)
        /// </summary>
        private ushort ntohs(ushort netshort)
        {
            return (ushort)(((netshort & 0xFF) << 8) | ((netshort >> 8) & 0xFF));
        }

        #region P/Invoke 定義

        private const int AF_INET = 2;

        public enum TCP_TABLE_CLASS
        {
            TCP_TABLE_BASIC_LISTENER,
            TCP_TABLE_BASIC_CONNECTIONS,
            TCP_TABLE_BASIC_ALL,
            TCP_TABLE_OWNER_PID_LISTENER,
            TCP_TABLE_OWNER_PID_CONNECTIONS,
            TCP_TABLE_OWNER_PID_ALL,
            TCP_TABLE_OWNER_MODULE_LISTENER,
            TCP_TABLE_OWNER_MODULE_CONNECTIONS,
            TCP_TABLE_OWNER_MODULE_ALL
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_TCPROW_OWNER_PID
        {
            public uint state;
            public uint localAddr;
            public uint localPort;
            public uint remoteAddr;
            public uint remotePort;
            public int owningPid;
        }

        [DllImport("iphlpapi.dll", SetLastError = true)]
        public static extern uint GetExtendedTcpTable(
            IntPtr pTcpTable,
            ref int dwOutBufLen,
            bool sort,
            int ipVersion,
            TCP_TABLE_CLASS tblClass,
            uint reserved
        );

        [DllImport("iphlpapi.dll", SetLastError = true)]
        public static extern uint SetTcpEntry(ref MIB_TCPROW_OWNER_PID pTcpRow);

        #endregion
    }
}

4. プロジェクトをビルド

Visual Studio の上部メニューから「ビルド」→「ソリューションのビルド」を選択します。
正常にビルドされると、VisualStudioの下部に「ビルド成功」と表示されます。

5. Reconnectorを実行

ビルドすると以下のようなフォルダ構成となり、DebugまたはReleaseフォルダ内に「HearthstoneRecconector.exe」が作成されています。

ビルドされたアプリケーションパス(プロジェクトフォルダがデスクトップの場合)
デスクトップ(プロジェクトフォルダの場所によって変わる)
└── HearthstoneRecconector
    └── HearthstoneRecconector
        └── bin
            ├── Debug
            │   └── HearthstoneRecconector.exe
            └── Release
                └── HearthstoneRecconector.exe

ビルドされたHearthstoneRecconector.exeを右クリックし、「管理者として実行」を選択します。
Windowsポップアップが表示されたら「はい」をクリックし、Reconnectorを起動しましょう。

アプリケーションウィンドウが表示され、中央に「Disconnect」ボタンが現れます。
バトルグラウンドをプレイ中に「Disconnect」をクリックすると、通信の切断・再接続が実施されます。

タスキルツールは通信を遮断するため管理者権限が必要です。必ず管理者として実行してください。

タスキルできない場合の対処法

簡易版ではタスキルできないケースがあります。

タスキルできないケース

ハースストーンのアップデートやパッチ更新直後に、ハースストーンの通信情報が変化し、タスキルできなくなるケースがあります。

対処法

時間経過とともに、ハースストーンの通信情報が元に戻りタスキルできるようになります。

すぐに必要な場合、以下の高機能版を使用してください。
高機能版は切断すべき通信を自動で特定するため、通信情報変更の影響を受けにくいです。

高機能版のタスキルツールをダウンロード

簡易版ツールの構築が難しい場合や、より確実にタスキルしたい場合は、高機能版をダウンロードしてください。

高機能版と簡易版の違い

  • ハースストーンのアニメーション通信を自動で特定するので、確実にタスキルできる
  • ダウンロードするだけで使える
  • ツールを最前面に表示するか選択可能

差分を表にまとめました。

スクロールできます
高機能簡易版
確実にタスキルできるハースストーンの通信情報が変わると機能しない場合がある
ダウンロードするだけですぐに使える自分で構築する必要がある
有料無料

高機能タスキルツールの画面

高機能版のUIは以下のようになっており、ログファイルの特定や簡単なUI設定が可能です。

高機能版のUI画面高機能版の設定画面

ツールのダウンロード方法

以下のURLからダウンロードできます。

ツールのダウンロードURLと詳細マニュアルは購入後に閲覧できます

Ueda
フリーランスエンジニア
RPAエンジニアです。
UipathやVBAを使用した開発を得意としています。優れた可読性と効率的な設計を併せ持つRPA開発を心がけています。
RPA初心者向けの教育経験多数あり。RPAの開発サポートも承ります。

Wordpressを用いたHP制作のお仕事も経験があります。本サイトもWordpressを用いて制作しております。

ペットのチワプーと暮らしてます。
  • URLをコピーしました!

コメント

コメントする

目次