40

机器人,它们是如何工作的?他们是否告诉视频游戏按下了键或单击了鼠标?

如果没有,有没有办法让你的程序告诉另一个程序按下了一个键?我想制作一个程序来击败一些游戏。因此,感谢任何资源或示例。

更新:所以一种方法是模拟击键,那么有哪些方法可以做到这一点(在任何语言中)?

4

11 回答 11

53

我曾经写过一堆机器人(从 Pogo 游戏到 Yohoho Puzzle Pirates)。对于窗口,您通常要么发送 Win32 事件来模拟鼠标移动,要么在实际单击鼠标时欺骗窗口之间发送的实际低级消息。很大程度上取决于程序的反应方式(通过接受带有坐标的消息,或者在 Java 的情况下,立即读取鼠标坐标)。“自动化”部分通常涉及读取屏幕并编写用于确定状态的启发式或算法,但也可以像数据包嗅探(在糟糕的扑克实现中存在大量信息)一样好,或者像直接读取内存位置一样笨拙。相当大的“领域”,并且记录不充分,因为它非常有利可图并且不难进入。

发送输入

C/C++(在 Windows 中)

对于键,请尝试 CodeProject:

http://www.codeproject.com/KB/cpp/sendkeys_cpp_Article.aspx

和消息:

http://www.codeproject.com/KB/threads/sendmsg.aspx

最好的办法是学习使用 Win32 API 发送消息,然后使用类似 Spy++ 或其衍生工具来“逆向工程”如何将按键和鼠标移动发送到窗口。

爪哇

Java 有一个非常可移植的 Robot 类,它能够:

  1. 从屏幕读取像素。
  2. 控制鼠标。
  3. 发送密钥。

如果您正在寻找快速简便的方法,我会试一试。

基本逻辑

这在 Internet 上的其他地方进行了深入描述,但大多数机器人都遵循简单的状态机程序流程。您阅读屏幕(或数据包或内存),根据您的读数和过去的数据找出您所处的“状态”,进行计算,然后将结果发送回程序。

阅读屏幕可能很困难,但如果您考虑到很多时候,相对于窗口有一些“幸运”像素,可以让您了解程序处于什么状态,这会变得更容易。可以自动找到这些像素。

于 2009-06-23T13:18:00.087 回答
6

有几种机器人。从我以前玩CS时的记忆(很久很久以前)

一些机器人使用应用程序本身的库来检查环境(地图、玩家所在的位置等)。机器人还使用该库来控制移动。我怀疑有很多机器人实现调用鼠标消息来告诉游戏如何移动等......

一些机器人模拟应用程序级协议(如果它是多人游戏)。所以换句话说,游戏甚至不需要运行。机器人可以在虚拟游戏中运行。

我将与另一位发帖人的建议背道而驰:编写游戏机器人可能比实际玩游戏更有价值,对它们的工作方式感到好奇是一个好兆头。:)

于 2009-06-23T13:12:37.337 回答
4

一些程序(例如在 MMORPG 中为您提供的程序)只是模拟击键。执行此操作的工具是AutoIt

至于真正自己玩游戏的机器人,我并没有真正对它们做过任何事情,但我假设它们会使用某种预定义的动作集,也许是启发式的,但不太可能。

于 2009-06-23T13:13:22.327 回答
4

这个概念最大的缺陷不是输入,而是游戏输出。您的机器人不能只是随机按键,它需要知道“正在发生”什么。很少有游戏允许您查询这些数据,这会让您的机器人解决一个非常棘手的问题——将每秒 60 帧的 2D 视觉数据转换为虚拟空间。

实际上,有一些游戏不仅允许机器人玩家,而且鼓励他们。Open RTS就是其中之一,但也有更简单的 RTS,例如GUN-TACTYXcrobots,它们是很好的起点。

于 2009-06-23T13:21:45.603 回答
2

像您描述的机器人将简单地模拟按键和鼠标移动/点击,因此游戏无法判断是人类在玩还是其他程序。它根本不需要与游戏交互。

于 2009-06-23T13:13:08.960 回答
2

机器人将充当游戏(服务器)的客户端。然后,他们可以像用户手动发送一样发送适当的数据。bot(客户端)将分析来自服务器的数据(“有人要从左边攻击”)等等。然后客户端应该能够计算出最佳移动并将适当的数据发送到服务器以执行它。

我不确定这是否适用于所有游戏。

于 2009-06-23T13:15:07.583 回答
2

这在很大程度上取决于游戏。例如,我为 Travian(这是一个在线游戏)制作了一个机器人,它使用 Internet Explorer activeX 来自动移动。我用 c# 编写了应用程序,让它完成工作大约需要 30 分钟。在 activeX 上调用方法很简单,使其执行诸如填充文本字段或单击按钮之类的操作。例如,对于登录,我使用了以下内容:

var inputs = web.Document.GetElementsByTagName("input").
                        Cast<HtmlElement>();
var nume = inputs.First(h => h.GetAttribute("type") == "text");
var pass = inputs.First(h => h.GetAttribute("type") == "password");
var login = inputs.First(h => h.GetAttribute("type") == "image");
var form = web.Document.GetElementsByTagName("form")[0];

nume.SetAttribute("value", "user");
pass.SetAttribute("value", "pass");
login.InvokeMember("Click");

对于那些基于桌面的游戏,事情变得更加复杂。Windows 允许一个应用程序向另一个应用程序发送消息,所以我想您可以使用它向游戏发送消息(尽管这适用于使用 directX 作为输入的游戏,我不知道)

于 2009-06-23T13:24:29.543 回答
2

当您说“控制程序”时,请考虑如何控制程序。大多数接受键盘/鼠标输入。

如果您编写一个程序来模拟键盘/鼠标输入,就可以了。

对此的推论是,如果程序接受通过输入框传递的参数,则编写一个程序来发送参数,就好像它们是通过输入框发送的一样。

这就是所有机器人的工作方式。希望它为您提供一些启示!

编辑:这就是绝大多数机器人的工作方式:-)

于 2009-06-23T13:31:39.327 回答
1

您可以使用Robot类在 Java 中模拟鼠标移动/单击和键盘输入。它还可以让您拍摄屏幕截图。

于 2009-06-23T13:50:06.280 回答
1

我认为AutoIT是做这类软件的一种很好的语言。尽管我没有用它来构建机器人,但发送点击和按键非常容易。

于 2009-06-23T14:02:40.310 回答
1

我的理解是,大多数高端游戏机器人使用系统调用将自己映射到游戏客户端的内存空间,对其布局进行逆向工程,并直接操纵客户端程序的内部变量。这比我单纯为了好玩要多得多。

于 2009-06-23T14:07:03.890 回答