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

时间:2010-11-20 18:55:51

标签: flash browser mouse bots

有很多Flash游戏要求你做重复动作。一个例子是FarmVille或获取在线扑克游戏的统计数据。

在屏幕上看到的内容,机器人的算法和点击鼠标之间创建界面的最佳方法是什么。

所以基本上,当我在脸书上玩德州扑克时,如果我得到AA,我希望机器人点击全押。如果我没有获得AA,我想弃牌。这只是一个例子,而不是实际的策略。或者另一个例子是在farmville中路由任务。

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

有什么建议吗?

3 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:4)

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

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

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

所有人都带我一个星期六,我很享受星期天。

答案 2 :(得分:1)

我使用c#和一个简单的webBrowser控件制作了很多机器人。 通常我会尝试自动化"点击"在不使用实际模拟光标和调用点击的情况下对元素起作用。

示例:

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()));
}

这将左键点击任何名为" elementid"的元素。在加载的webBrowser控件中。注意可以轻松实现的其他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()));
}