代码之家  ›  专栏  ›  技术社区  ›  kirill_igum jfriend00

如何为在线Flash游戏构建机器人?

  •  7
  • kirill_igum jfriend00  · 技术社区  · 14 年前

    有很多flash游戏要求你重复动作。例如Farmville或获取在线扑克游戏的统计数据。

    在屏幕上看到的东西、机器人的算法和鼠标点击之间创建界面的最佳方法是什么?

    所以,基本上,当我玩德州扑克的时候,把他们放在脸书上,如果我得了AA,我想让机器人点击全部。如果我没有AA,我想折叠。这只是一个例子,而不是实际的策略。或者另一个例子是在Farmville中路由任务。

    基本上是这样。它必须抓取屏幕的照片。识别模式并将其转换为算法的输入。输出算法将单击其他(可能相同)模式。

    有什么建议吗?

    3 回复  |  直到 10 年前
        1
  •  4
  •   Kh40tiK    10 年前

    我有经验,建立一个简单的计算机视觉为一个在线纸牌游戏机器人。

    我使用了一个跨平台的python库 自动复制 处理自动鼠标点击和键盘输入。bot捕获屏幕每0.5秒,然后将捕获的屏幕转换为numpy数组进行分析。python具有良好的图像处理(pil、opencv python绑定)和机器学习实用程序(scikit-learn)。对于简单的图像模式识别,机器人提取图像区域上像素亮度的平均值进行决策。对于复杂的问题,采用OpenCV模板匹配和SVM分类器。

    服务器第一次捕获了我的bot,所以我想服务器端有一些bot检测。在添加了更多的随机性和灵活的决策之后,bot绕过了服务器端bot检测。

    整个星期六我都过得很愉快。

        2
  •  4
  •   David    14 年前

    在尝试解析屏幕图像并生成鼠标点击(这将非常困难)之前,首先查看浏览器和服务器之间的游戏实际发送/接收的数据。像平常一样与游戏互动,使用 WireShark 以捕获数据包并查看它是否是您可以自动化的东西。

    不太可能(因为他们 不要 希望人们做你想做的事情),但与服务器的通信可能只是简单的带有参数的请求。(我知道很久以前MySpace游戏就是这样的,比如龙战和黑手党战争。)

    如果数据是您可以解析和理解的,那么您可以完全跳过Flash接口,只需编写自己的。

        3
  •  1
  •   Msegling    10 年前

    我用C和一个简单的WebBrowser控件制作了许多bot。 不过,通常我尝试在元素上自动执行“click”功能,而不使用实际模拟光标和调用click。

    例子:

    webBrowser1.Document.GetElementById("elementid").InvokeMember("Click");
    

    我发现这比实际模拟光标容易得多,但是模拟光标也相对容易实现,下面是我通常使用的代码:

    //Example of how to use it:
        Point controlLoc = this.PointToScreen(webbrowser1.Location);
        controlLoc.X = controlLoc.X + webbrowser1.Document.GetElementById("elementid").OffsetRectangle.Left;
        controlLoc.Y = controlLoc.Y + webbrowser1.Document.GetElementById("elementid").OffsetRectangle.Top;
        Cursor.Position = controlLoc;
        MouseSimulator.ClickLeftMouseButton();
    
    public class MouseSimulator
     {
    [DllImport("user32.dll", SetLastError = true)]
    static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize);
    
    [StructLayout(LayoutKind.Sequential)]
    struct INPUT
    {
        public SendInputEventType type;
        public MouseKeybdhardwareInputUnion mkhi;
    }
    [StructLayout(LayoutKind.Explicit)]
    struct MouseKeybdhardwareInputUnion
    {
        [FieldOffset(0)]
        public MouseInputData mi;
    
        [FieldOffset(0)]
        public KEYBDINPUT ki;
    
        [FieldOffset(0)]
        public HARDWAREINPUT hi;
    }
    [StructLayout(LayoutKind.Sequential)]
    struct KEYBDINPUT
    {
        public ushort wVk;
        public ushort wScan;
        public uint dwFlags;
        public uint time;
        public IntPtr dwExtraInfo;
    }
    [StructLayout(LayoutKind.Sequential)]
    struct HARDWAREINPUT
    {
        public int uMsg;
        public short wParamL;
        public short wParamH;
    }
    struct MouseInputData
    {
        public int dx;
        public int dy;
        public uint mouseData;
        public MouseEventFlags dwFlags;
        public uint time;
        public IntPtr dwExtraInfo;
    }
    [Flags]
    enum MouseEventFlags : uint
    {
        MOUSEEVENTF_MOVE = 0x0001,
        MOUSEEVENTF_LEFTDOWN = 0x0002,
        MOUSEEVENTF_LEFTUP = 0x0004,
        MOUSEEVENTF_RIGHTDOWN = 0x0008,
        MOUSEEVENTF_RIGHTUP = 0x0010,
        MOUSEEVENTF_MIDDLEDOWN = 0x0020,
        MOUSEEVENTF_MIDDLEUP = 0x0040,
        MOUSEEVENTF_XDOWN = 0x0080,
        MOUSEEVENTF_XUP = 0x0100,
        MOUSEEVENTF_WHEEL = 0x0800,
        MOUSEEVENTF_VIRTUALDESK = 0x4000,
        MOUSEEVENTF_ABSOLUTE = 0x8000
    }
    enum SendInputEventType : int
    {
        InputMouse,
        InputKeyboard,
        InputHardware
    }
    
    public static void ClickLeftMouseButton()
    {
    
        INPUT mouseDownInput = new INPUT();
        mouseDownInput.type = SendInputEventType.InputMouse;
        mouseDownInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTDOWN;
        SendInput(1, ref mouseDownInput, Marshal.SizeOf(new INPUT()));
    
        INPUT mouseUpInput = new INPUT();
        mouseUpInput.type = SendInputEventType.InputMouse;
        mouseUpInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTUP;
        SendInput(1, ref mouseUpInput, Marshal.SizeOf(new INPUT()));
    }
    

    这将左键单击加载的WebBrowser控件中名为“elementID”的任何元素。注意其他可以轻松实现的mouseEventFlags:

    下面是右键单击的示例:

    public static void ClickRightMouseButton()
    {
        INPUT mouseDownInput = new INPUT();
        mouseDownInput.type = SendInputEventType.InputMouse;
        mouseDownInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_RIGHTDOWN;
        SendInput(1, ref mouseDownInput, Marshal.SizeOf(new INPUT()));
    
        INPUT mouseUpInput = new INPUT();
        mouseUpInput.type = SendInputEventType.InputMouse;
        mouseUpInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_RIGHTUP;
        SendInput(1, ref mouseUpInput, Marshal.SizeOf(new INPUT()));
    }