使用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,用的是Regex。同樣用Regex可以得到當前城鎮的所有資料:資源數,建築等級等。
得到鐵礦數量的Regex:
// 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道理一樣。
以上談到的關鍵點好像能完成三國風雲遊戲中想要的大部分功能了,只要能想到什麼功能。比起組包,發包方便很多,但效率上 就差很多.
如果有人有興趣繼續完善這個程式,歡迎討論。我現在對這個遊戲完全沒興趣了-_-!