如何为在线flash游戏构建机器人?
有很多flash游戏要求你做重复动作。例如FarmVille或在线扑克游戏统计数据 在屏幕上看到的内容、机器人的算法和鼠标点击之间创建界面的最佳方式是什么 所以基本上,当我玩德州扑克时,如果我得到AA,我希望机器人点击全部进入。如果我得不到AA,我想折叠。这只是一个例子,而不是实际的战略。另一个例子是farmville中的路由任务 基本上是这样。它必须抓取屏幕上的图片。识别模式并将其转换为算法的输入。输出算法将单击其他(可能相同)模式如何为在线flash游戏构建机器人?,flash,browser,mouse,bots,Flash,Browser,Mouse,Bots,有很多flash游戏要求你做重复动作。例如FarmVille或在线扑克游戏统计数据 在屏幕上看到的内容、机器人的算法和鼠标点击之间创建界面的最佳方式是什么 所以基本上,当我玩德州扑克时,如果我得到AA,我希望机器人点击全部进入。如果我得不到AA,我想折叠。这只是一个例子,而不是实际的战略。另一个例子是farmville中的路由任务 基本上是这样。它必须抓取屏幕上的图片。识别模式并将其转换为算法的输入。输出算法将单击其他(可能相同)模式 有什么建议吗?在尝试解析屏幕图像和产生鼠标点击(这将非常困难
有什么建议吗?在尝试解析屏幕图像和产生鼠标点击(这将非常困难)之前,首先查看浏览器和服务器之间游戏实际发送/接收的数据。像平常一样与游戏交互,并使用类似的方法捕获数据包,看看是否可以实现自动化 这是不可能的(因为他们特别不希望人们做你正试图做的事情),但与服务器的通信可能只是带有参数的简单请求。(我知道MySpace游戏很久以前就是这样,比如《龙之战》和《黑手党战争》)
如果数据是您可以解析和理解的,那么您可以完全跳过Flash界面,自己编写。我有为在线纸牌游戏构建简单的基于计算机视觉的机器人的经验 我使用了一个名为autopy的跨平台python库来处理自动鼠标点击和键盘输入。每0.5秒显示一次机器人捕获屏幕,然后将捕获的屏幕转换为numpy数组进行分析。Python具有良好的图像处理(PIL、OpenCV Python绑定)和机器学习实用程序(scikit学习)。对于简单的图像模式识别,bot提取图像区域像素亮度的平均值进行决策。对于复杂的情况,采用OpenCV模板匹配和SVM分类器 服务器第一次抓到了我的机器人,所以我猜服务器端有一些机器人检测。在我添加了更多的随机性和灵活的决策之后,bot绕过了服务器端bot检测 这一切都花了我一个星期六的时间,我很享受周日的时光。我用c#和一个简单的webBrowser控件制作了很多机器人。 但是,通常我会尝试在一个元素上自动执行“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()));
}
这里有一个类似的帖子,链接到构建一个扑克机器人。显然,我也想做类似的smtn,但我很好奇现在是否有更好的工具。尽管查看发送和接收的数据更容易,但查看屏幕然后让计算机移动鼠标更一般。看起来这可能也是一种方法,听起来不错。我会调查的。但我对c也很好奇,我是否可以通过屏幕进行交互,因为它更通用,而且可能还可以节省计算发送的值的时间。@kirill_igum:可能有一些库可以将数据以鼠标/键盘输入的形式发送到屏幕。例如,WatiN是一个相当不错的.NET库,用于与浏览器交互(HTML元素,虽然可能还有其他元素,但对Flash来说并不多)。然而,从屏幕上读取数据将是极其困难的。即使它是可能的(可能是一个更准确的词),我也不认为它会像你期望的那样通用。如果你知道你在寻找什么,我不明白这有多么困难。例如:我使用一个程序拍摄flash游戏、浏览器或屏幕的屏幕截图。将其转换为矩阵,其中每个元素都是表示颜色的数字。代码将子矩阵与我的库(我正在寻找的预存储模式)中的子矩阵相匹配。如果匹配,代码将输出模式的位置。所以当我想使用它时,我只需要输入我正在寻找的模式。如果他们改变了。我必须亲自更换,我仍会调查WatiN。我确实同意你的观点,在很多情况下,直接浏览数据会更简单,但我想探索或了解这两种方法。@kirill_igum:听起来这将是一个非常棒的开源库。您可能会在这样的项目中找到一些不错的社区兴趣,但我不是主持开源项目的专家。