有很多Flash游戏要求你做重复动作。一个例子是FarmVille或获取在线扑克游戏的统计数据。
在屏幕上看到的内容,机器人的算法和点击鼠标之间创建界面的最佳方法是什么。
所以基本上,当我在脸书上玩德州扑克时,如果我得到AA,我希望机器人点击全押。如果我没有获得AA,我想弃牌。这只是一个例子,而不是实际的策略。或者另一个例子是在farmville中路由任务。
基本上是这样的。它必须抓住屏幕的图片。识别模式并将其转换为算法的输入。输出算法会点击其他一些(可能是相同的)模式。有什么建议吗?
答案 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()));
}