zoukankan      html  css  js  c++  java
  • C#使用WebBrowser制作网页游戏辅助工具关键技术分析

    使用WebBrowser控件,实现起来确实很方便,但灵活性差,比不上直接组包发包。对三国风云这款网页游戏来说,WebBrowser用的好的话理论上可以实现想要的功能(我只实现了整点自动"举荐名士",
    其他就没兴趣实现了,原理都是一样)。
    使用抓包工具,可以查看游戏过程中都有哪些包,自己大概有些了解。
    有些网页游戏是Flash界面的,如校内的开心农场.WebBrowser就不适合做这个游戏的辅助工具。.NET中也有Flash的控件,但这个控件功能很弱,Flash中的很多东西都得不到。现在想到的办法也只
    有原始的组包发包。
    WebBrowser有个缺点,它只能存在主线程中。在webBrowser处理数据过程中,整个程序处在繁忙状态,点击程序会没反应(未响应)。在程序运行过程中尽量减少webBrowser处理数据时间,除了
    webBrowser更新数据,其他的都在其他线程中实现。
    webBrowser.Navigate(strURL);
    通过webBrowser可以得到其字符串内容:
    webBrowser.Document.Body.InnerHtml;
    “游戏指南”其实就是一个链接:
    <A class=topbutton-guide title=游戏指南 href=\"javascript:MM_iframePost('guide.nation');\">游戏指南</A>
    只要在代码中执行“javascript:MM_iframePost('guide.nation');”这个脚本,就相当于用鼠标点击游戏中的“游戏指南”。
    执行脚本可以用HtmlElement.InvokeMember。
    ...
    HtmlElementCollection aHtml = webBrowser.Document.GetElementsByTagName("a");
    DoClick("游戏指南");
     private void DoClick(string name)
    {
        foreach (HtmlElement h in aHtml)
        {
            if (h.InnerText != null && h.InnerText.Contains(name))
            {
                h.InvokeMember("click");
                //等待webBrowser刷新完成
                WaitForEventCompleted(1000);
                break;
            }
            else
            {
                continue;
            }
        }
    }
    private void WaitForEventCompleted(int time)
    {
        autoResetEvent.Reset();
        while (autoResetEvent.WaitOne(time, false) == false)
        {
            Application.DoEvents();
        }
    }
     
    每次点击相应的链接后,webBrowser都要相应的刷新数据,因此,在操作后都要等待webBrowser更新数据完成。每次更新数据时,webBrowser_DocumentCompleted event执行的不是一次,
    好像是3次,但是找到原因了,现在又忘记了,代码这里还不稳定,可以抓包研究下原因。
    定时执行“举荐名士”,不同线程之间同步使用到DoCallback, Invoke:
     private void TimerDoFamous()
    {
        while (true)
        {
            if (DateTime.Now.Second == 10 && DateTime.Now.Minute == 2)
            {
                if (webBrowser.InvokeRequired)
                {
                    DoCallback d = new DoCallback(DoFamousGeneral);
                    this.Invoke(d);
                    d = new DoCallback(Wait);
                    this.Invoke(d);
                    d = new DoCallback(DoAnotherGeneral);
                    this.Invoke(d);
                }
                else
                {
                    DoCallback d = new DoCallback(DoFamousGeneral);
                    this.Invoke(d);
                    d = new DoCallback(Wait);
                    this.Invoke(d);
                    d = new DoCallback(DoAnotherGeneral);
                    this.Invoke(d);
                }
            }
        }
    }
     
    怎样从webBrowser.Document.Body.InnerHtml中得到自己想要的html element,用的是正则表达式。同样用正则表达式可以得到当前城镇的所有数据:资源数,建筑等级等。
    得到铁矿数量的正则表达式:
     
    // iron
    public const string IronNowPat = @"<SPAN id=iron_now>\d*</SPAN>";
    public const string IronNowHeader = @"<SPAN id=iron_now>";
    public const string IronIncreasePat = @"id=iron_increase>\d*</SPAN>";
    public const string IronIncreaseHeader = @"id=iron_increase>";
    我测试的帐号是中有一个代管帐号。
    现在程序运行的结果是, 点击“button1”立即执行“举荐名士”,自己的帐号做完之后,自动转到代管的帐号做代管帐号的“举荐名士”。我测试用的2个帐号,其中一个是代管帐号。所以现在的程序只能支
    持一个代管帐号,修改成2个原理一样。点击“button2”,在每次电脑时间秒针等于10时,执行“举荐名士”(定时无限次数)。
    转到代管帐号时,会弹出一个含有“确定”的对话框,必须点击“确定”后才能真正转到代管帐号的界面。这个“确定”按钮是一个含“input” Tag的html element,这个跟“游戏指南”是一个含“a”
    Tag的html element道理一样。
    以上谈到的关键点好像能完成三国风云游戏中想要的大部分功能了,只要能想到什么功能。比起组包,发包方便很多,但效率上 就差很多.
  • 相关阅读:
    springboot启动时不加载数据库
    ElasticSearch常用的查询操作
    Windows10 搭建ElasticSearch集群服务
    windows10安装ElasticSearch7.5遇到两个警告解决方法
    MybatisPlus自动生成代码配置
    初识RabbitMQ ------基本概念
    深拷贝与浅拷贝的区别
    Java8中 LocalDateTime与Date互相转换
    Spring中常用的工具类StringUtils、DateUtils、CollectionUtils等
    SpringBoot定时任务 @Scheduled cron 表达式说明
  • 原文地址:https://www.cnblogs.com/top5/p/1904810.html
Copyright © 2011-2022 走看看