You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows平台下用C#实现游戏Farming Bot按键监听与控制方案咨询

Windows下C#实现事件驱动的Farming Bot方案

核心思路

要实现全局监听F1/ESC按键(游戏运行时控制台可能处于后台),结合事件驱动逻辑控制自动按键的启停,需通过Windows全局键盘钩子实现按键监听,再配合自定义事件触发Bot的启动/停止逻辑。

1. 封装Windows API(含已有的按键模拟)

先封装必要的User32.dll函数,包括全局钩子相关方法和按键模拟:

using System;
using System.Runtime.InteropServices;
using System.Threading;

public static class User32
{
    public delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

    public const int WH_KEYBOARD_LL = 13;
    public const int WM_KEYDOWN = 0x0100;
    public const int VK_F1 = 0x70;
    public const int VK_ESCAPE = 0x1B;

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool UnhookWindowsHookEx(IntPtr hhk);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr GetModuleHandle(string lpModuleName);

    // 按键模拟实现(统一封装已有逻辑)
    [DllImport("user32.dll", SetLastError = true)]
    public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);

    public const uint KEYEVENTF_KEYDOWN = 0x0000;
    public const uint KEYEVENTF_KEYUP = 0x0002;

    public static void PressKey(byte keyCode)
    {
        keybd_event(keyCode, 0, KEYEVENTF_KEYDOWN, UIntPtr.Zero);
        Thread.Sleep(50); // 模拟按键按下延迟,可调整
        keybd_event(keyCode, 0, KEYEVENTF_KEYUP, UIntPtr.Zero);
        Thread.Sleep(50);
    }
}

2. 全局键盘钩子(事件驱动监听)

实现全局钩子管理器,当F1/ESC按下时触发自定义事件:

public class GlobalKeyboardHook : IDisposable
{
    private User32.LowLevelKeyboardProc _hookCallback;
    private IntPtr _hookId = IntPtr.Zero;

    // 自定义事件,供外部订阅
    public event EventHandler StartBotRequested;
    public event EventHandler StopBotRequested;

    public GlobalKeyboardHook()
    {
        _hookCallback = HookProc;
        _hookId = SetupHook();
    }

    private IntPtr SetupHook()
    {
        using (var currentProcess = System.Diagnostics.Process.GetCurrentProcess())
        using (var mainModule = currentProcess.MainModule)
        {
            return User32.SetWindowsHookEx(User32.WH_KEYBOARD_LL, _hookCallback, 
                User32.GetModuleHandle(mainModule.ModuleName), 0);
        }
    }

    private IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam)
    {
        // 仅处理按键按下事件
        if (nCode >= 0 && wParam == (IntPtr)User32.WM_KEYDOWN)
        {
            var keyCode = Marshal.ReadInt32(lParam);
            switch (keyCode)
            {
                case User32.VK_F1:
                    StartBotRequested?.Invoke(this, EventArgs.Empty);
                    break;
                case User32.VK_ESCAPE:
                    StopBotRequested?.Invoke(this, EventArgs.Empty);
                    break;
            }
        }
        // 传递钩子给下一个处理程序,避免影响系统其他按键
        return User32.CallNextHookEx(_hookId, nCode, wParam, lParam);
    }

    public void Dispose()
    {
        User32.UnhookWindowsHookEx(_hookId);
    }
}

3. Farming Bot逻辑(事件驱动控制)

实现Bot类,通过Start/Stop方法控制自动按键循环,用volatile保证线程安全:

public class FarmingBot
{
    private volatile bool _isRunning;
    private Thread _botThread;

    public void Start()
    {
        if (_isRunning) return;
        _isRunning = true;
        _botThread = new Thread(RunAutoPressLoop) { IsBackground = true };
        _botThread.Start();
    }

    public void Stop()
    {
        _isRunning = false;
        _botThread?.Join();
    }

    private void RunAutoPressLoop()
    {
        while (_isRunning)
        {
            // 循环按下A、B、C
            User32.PressKey(0x41); // A键
            User32.PressKey(0x42); // B键
            User32.PressKey(0x43); // C键
            Thread.Sleep(1000); // 循环间隔,根据游戏需求调整
        }
    }
}

4. 整合到控制台程序

在Main方法中初始化钩子和Bot,订阅事件并保持程序运行:

class Program
{
    static void Main(string[] args)
    {
        using var hook = new GlobalKeyboardHook();
        var bot = new FarmingBot();

        hook.StartBotRequested += (_, __) =>
        {
            Console.WriteLine("Bot已启动(F1按下)");
            bot.Start();
        };

        hook.StopBotRequested += (_, __) =>
        {
            Console.WriteLine("Bot已停止(ESC按下)");
            bot.Stop();
        };

        Console.WriteLine("按F1启动Bot,ESC停止Bot,按任意键退出程序...");
        Console.ReadKey();

        bot.Stop();
    }
}

5. 整合到.NET Core Worker Service

如果用Worker Service,在Worker类中初始化资源并处理生命周期:

public class Worker : BackgroundService
{
    private GlobalKeyboardHook _keyboardHook;
    private FarmingBot _farmingBot;

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _keyboardHook = new GlobalKeyboardHook();
        _farmingBot = new FarmingBot();

        // 订阅钩子事件
        _keyboardHook.StartBotRequested += (_, __) => _farmingBot.Start();
        _keyboardHook.StopBotRequested += (_, __) => _farmingBot.Stop();

        // 程序停止时清理资源
        stoppingToken.Register(() =>
        {
            _keyboardHook.Dispose();
            _farmingBot.Stop();
        });

        await Task.Delay(Timeout.Infinite, stoppingToken);
    }
}

注意事项

  • 建议以管理员身份运行程序,避免全局钩子被系统或游戏拦截。
  • 按键延迟和循环间隔需根据游戏的输入响应速度调整,确保按键被正确识别。
  • 全局钩子会监听系统所有按键,需确保钩子回调逻辑简洁,避免影响系统性能。

内容的提问来源于stack exchange,提问作者Benjamin Martin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 23:40:29