【问题标题】:How can a program control another program?一个程序如何控制另一个程序?
【发布时间】:2010-11-05 04:08:22
【问题描述】:

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

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

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

【问题讨论】:

    标签: bots


    【解决方案1】:

    我曾一次或多次编写过一堆机器人(从 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

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

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

    如果您想要快速简便,我会试一试。

    基本逻辑

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

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

    【讨论】:

    • +1,主要是因为您要区分运行益智类游戏的非常基本的机器人和使用应用程序内存的更复杂的机器人。
    • (+1) 以获得良好的答案,以及拼图海盗参考。伙计,我想念那场比赛。
    • @devinb Lol,我很高兴有人玩过那个游戏。我提到它的每个人都说“Yohoho 什么?”和笑,但他们不知道;)
    • @geo:这是一个非常标准的读取内存示例。 FreeCell 比大多数人必须处理的要简单得多,而动态分配(或托管代码)使整个事情变得困难 100 倍。 codeproject.com/KB/trace/freecellreader.aspx
    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 也有键盘可以记录按键序列。
      • 呃……机器人怎么会知道游戏中的任何障碍物或敌人在哪里,似乎只是盲目地遵循一组指令的机器人将毫无用处跨度>
      • @altCognito 在模拟击键的情况下,您必须“训练”机器人,使其知道其路径、目标、交互等的边界。从某种意义上说,指令集字面意思是“使用”。如果指令没有产生任何好的结果,那它确实是没用的。
      • 知道 autoit 如何模拟这些击键吗?
      • 它基本上是一个虚拟键盘和鼠标。 Windows 允许程序将自己插入到硬件/驱动层和应用程序之间(登录期间除外)。
      【解决方案4】:

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

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

      【讨论】:

      • 对于多人游戏,通常可以阅读网络聊天并弄清楚发生了什么。
      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

        • 它适用于所有游戏,前提是您可以访问,或者可以为特定游戏使用的任何协议制定规范……自然,对于某些游戏来说,这比其他游戏要困难几个数量级。 (想想魔兽世界与 ASCII 国际象棋服务器)
        【解决方案7】:

        这在很大程度上取决于游戏。 例如,我为 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 作为输入的游戏,我不知道)

        【讨论】:

          【解决方案8】:

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

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

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

          这就是所有机器人的工作方式。希望能给你一些启发!

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

          【讨论】:

            【解决方案9】:

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

            【讨论】:

            • 我猜您阅读了我的个人资料以查看我的主要语言,感谢您的帮助:D
            • @Anton:不,我只是碰巧在做一个个人机器人项目,而机器人是它的核心。 :)
            【解决方案10】:

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

            【讨论】:

              【解决方案11】:

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

              【讨论】:

                猜你喜欢
                • 2013-07-20
                • 2011-03-07
                • 1970-01-01
                • 2014-10-24
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-02-19
                相关资源
                最近更新 更多