使用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,用的是正則表達式。同樣用正則表達式可以得到當前城鎮的所有數據:資源數,建築等級等。
得到鐵礦數量的正則表達式: