色尼玛亚洲综合影院,亚洲3atv精品一区二区三区,麻豆freexxxx性91精品,欧美在线91

用C#打造"QQ對(duì)戰(zhàn)平臺(tái)擠房器"

一、什么是“QQ對(duì)戰(zhàn)平臺(tái)擠房器”?

喜歡在“QQ對(duì)戰(zhàn)平臺(tái)”或“浩方對(duì)戰(zhàn)平臺(tái)”玩游戲的人都知道。平常平臺(tái)上的房間基本很多都是人滿的,如果想找個(gè)房間,那可是要費(fèi)好長(zhǎng)的時(shí)間來“擠”才能進(jìn)去,如果是節(jié)假日或晚上,那更要花費(fèi)更多的時(shí)間在“擠”房上了,如下圖:

qq-fr-tr-1

而對(duì)于“QQ對(duì)戰(zhàn)平臺(tái)”,如果房間已滿擠不進(jìn)去,卻變態(tài)的還會(huì)彈出兩次提示!平時(shí),就只有拼命的按“回車鍵”或“空格鍵”關(guān)閉這兩個(gè)討厭的彈出窗口,然后再用鼠標(biāo)點(diǎn)房間,如果房間還是進(jìn)不去,就只能再按上面來一次循環(huán)……一次、兩次不是問題;五次、十次也許還不是問題;但如果十幾次或上百次還是擠不進(jìn)去,還手按那就有問題了!當(dāng)然,如果你喜歡手虐那就另外說了-_-#

我不喜歡手虐,所以當(dāng)有次碰到N次還是擠不進(jìn)去時(shí),我就在想,為什么不寫個(gè)工具來代替我的手,用工具自動(dòng)去幫我“擠”房間,幫我點(diǎn)那兩個(gè)討厭的提示窗口呢?于是這篇文章中的“QQ對(duì)戰(zhàn)平臺(tái)擠房器”就這樣誕生了(這可解放多少人的雙手啊,大家鼓掌……)

二、“擠房”要怎樣“擠”?

上面說了,“擠房器”就是幫我們自動(dòng)“擠”房,但是它要怎么幫我們“擠”呢?它畢竟是機(jī)器,而不是人,它不會(huì)自動(dòng)一看到房間就幫我們“擠”,除非我們給它定制了一套規(guī)則(也可以叫命令)。機(jī)器就是機(jī)器,有規(guī)則它才會(huì)去做事,如果沒規(guī)則也會(huì)做事,那它就是“人”(智能機(jī)器人?)了。

這規(guī)則要怎樣定制?讓我們先來看看我們平時(shí)進(jìn)入房間的流程,如下圖:

qq-fr-tr-2

好了,根據(jù)上面的流程,我們要給“擠房器”定制的規(guī)則就是分別以下幾條:

1)、點(diǎn)擊房間。

2)、判斷是否已進(jìn)入房間,如果沒有進(jìn)入房間,則負(fù)責(zé)將顯示房間滿的兩個(gè)討厭的提示窗口關(guān)閉掉,并重新回到第1步。

3)、已進(jìn)入房間,則停止“擠”房動(dòng)作。

三、自動(dòng)“擠房”的實(shí)現(xiàn)。

這里的實(shí)現(xiàn),就是用代碼去實(shí)現(xiàn)上面定制的三個(gè)規(guī)則。

1、點(diǎn)擊房間

在這里我們簡(jiǎn)單點(diǎn),只是模擬鼠標(biāo)去點(diǎn)擊鼠標(biāo)當(dāng)前所在的房間。說到這里,也許做過WINDOWS應(yīng)用程序開發(fā)的朋友已想到了用哪幾個(gè)API函數(shù)去模擬,對(duì)!就是以下幾個(gè)API的結(jié)合一起使用,就能實(shí)現(xiàn)鼠標(biāo)的模擬點(diǎn)擊了。

1)、GetCursorPos : 獲取鼠標(biāo)的當(dāng)前所在位置。

定義原型如下:

[DllImport("user32.dll")]
internal static extern bool GetCursorPos(out Point lpPoint);

此函數(shù)返回當(dāng)前鼠標(biāo)所在的坐標(biāo)位置。

2)、mouse_event : 鼠標(biāo)事件的模擬

定義原型如下:

[DllImport("user32.dll", EntryPoint = "mouse_event")]
public static extern void mouse_event(
    int dwFlags,
    int dx,
    int dy,
    int dwData,
    int dwExtraInfo
);

此函數(shù)通過不同的dwFlags參數(shù)定義,可以模擬不同的鼠標(biāo)事件,如鼠標(biāo)左鍵的按下、彈起事件等。

結(jié)合以上兩個(gè)API函數(shù),我們就能實(shí)現(xiàn)自動(dòng)點(diǎn)擊鼠標(biāo)所在的房間"的效果了,類似如下代碼:

Point point;

if(Win32API.GetCursorPos(out point)){

     //MouseAPI是對(duì)mouse_event API函數(shù)的一個(gè)簡(jiǎn)單封裝。

     MouseAPI.SendMouseEvent(MouseAPI.MouseEvents.LeftButtonDown | MouseAPI.MouseEvents.LeftButtonUp, point, true);

}

但是上面的代碼是非常“機(jī)械”的,也即是不管當(dāng)前鼠標(biāo)所在的窗口是不是在房間上,它都會(huì)自動(dòng)“點(diǎn)擊”一次!這樣可不人性化,所以我們?cè)俑倪M(jìn)一下,點(diǎn)擊時(shí)先判斷當(dāng)前鼠標(biāo)停留的是不是在對(duì)戰(zhàn)平臺(tái)的房間上,但可惜的QQ對(duì)戰(zhàn)平臺(tái)的房間不是標(biāo)準(zhǔn)WINDOWS控件,所以無法獲取到房間的數(shù)據(jù),最后只好簡(jiǎn)單點(diǎn)判斷鼠標(biāo)停留的窗口是不是QQ對(duì)戰(zhàn)平臺(tái)的大廳,因?yàn)榇髲d是可獲取到的WINDOWS窗口控件,如下圖是用Spy++獲取到的大廳數(shù)據(jù):

qq-fr-tr-3

也就是我們判斷鼠標(biāo)停留的窗口的類型是不是屬于“Afx:400000:3”即可,如果是則表明鼠標(biāo)是停留在QQ對(duì)戰(zhàn)平臺(tái)的游戲大廳中的,就可以點(diǎn)擊房間了(注意:這里停留的位置不一定是房間上,但這不影響使用,所以我就沒加以處理了)

這里需要使用的API有:

3)、WindowFromPoint : 獲取某個(gè)坐標(biāo)位置所在的窗口

定義原型如下:

[DllImport("user32.dll")]
internal static extern IntPtr WindowFromPoint(Point Point);

4)、GetClassName : 獲取某個(gè)窗口的類型名稱

定義原形如下:

[DllImport("user32.dll",  CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern int GetClassName(IntPtr hWnd, StringBuilder buf, int nMaxCount);

加入上面的條件判斷,上面的代碼改進(jìn)后如下:

if (Win32API.GetCursorPos(out point)){    hwnd = Win32API.WindowFromPoint(point);    if (hwnd != IntPtr.Zero)    {        string className = Win32API.GetWindowClassName(hwnd);        if (className.Equals("Afx:400000:3"))        {            MouseAPI.SendMouseEvent(MouseAPI.MouseEvents.LeftButtonDown | MouseAPI.MouseEvents.LeftButtonUp, point, true);        }    }}
這樣“點(diǎn)擊房間”這步就可以算完美了,當(dāng)鼠標(biāo)不在房間(正確的說不在游戲大廳)上停留時(shí),鼠標(biāo)也不會(huì)亂點(diǎn),這就方便在“擠房間”時(shí)隨時(shí)可以切換窗口了。

2、判斷是否已進(jìn)入房間,如果沒有進(jìn)入房間,則負(fù)責(zé)將顯示房間滿的兩個(gè)討厭的提示窗口關(guān)閉掉。

 1)判斷是否已進(jìn)入房間: 和上面那步判斷鼠標(biāo)是否停留在游戲大廳一樣,也是判斷鼠標(biāo)是否停留在聊天室中,如果是那么就表示已擠進(jìn)去了。用Spy++獲取到聊天室的窗口類型分別是“RichEdit20A”和“Afx:44a0000:0” ,所以判斷代碼如下:

//判斷鼠標(biāo)是否停留在聊天窗口上if (Win32API.GetCursorPos(out point)){    hwnd = Win32API.WindowFromPoint(point);    if (hwnd != IntPtr.Zero)    {        string className = Win32API.GetWindowClassName(hwnd);        if (className.Equals("RichEdit20A")            || className.Equals("Afx:44a0000:0"))        {            isOk = true;        }    }}

如果isOk=true則表示已擠進(jìn)房間。則就可以停止“擠房”,否則就要處理那兩個(gè)討厭的提示窗口了。

2)關(guān)閉提示窗口

先需要判斷是否有這兩個(gè)提示窗口出現(xiàn),因?yàn)樵跀D房過程中,QQ對(duì)戰(zhàn)平臺(tái)會(huì)優(yōu)先顯示一個(gè)進(jìn)度條(窗口)。我們?yōu)榱撕?jiǎn)單點(diǎn)處理,只是判斷當(dāng)前活動(dòng)窗口是否是“提示窗口”即可,也即是簡(jiǎn)單的判斷當(dāng)前活動(dòng)窗口中是否包含那個(gè)“確定”按鈕,如果存在,那么就簡(jiǎn)單的認(rèn)為這窗口是那提示窗口,關(guān)閉它即可。需要用到的API函數(shù)有以下幾個(gè):

A、GetForegroundWindow : 獲取當(dāng)前活動(dòng)窗口

它的定義原形:

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetForegroundWindow();

B、FindWindowEx : 查找某個(gè)窗口

它的定義原型:

[DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

關(guān)閉提示窗口,則只使用簡(jiǎn)單的方法,也即是發(fā)送“回車鍵”即可,因?yàn)槲覀儷@取到的窗口是當(dāng)前活動(dòng)窗口,并且又是模式窗口,所以它能接受鍵盤消息。關(guān)于鍵盤的模擬,請(qǐng)參考我的這篇文章《C#對(duì)游戲手柄的編程開發(fā)-API篇(3)》。

最后代碼如下:

if (!isOk){    //沒有擠進(jìn)去,則判斷是否有提示窗口彈出,有的話關(guān)閉掉它    hwnd = Win32API.GetForegroundWindow();    if (hwnd != IntPtr.Zero)    {        //查找活動(dòng)窗口是否包含有"確定"按鈕        IntPtr buttonHwnd = Win32API.FindWindowEx(hwnd, IntPtr.Zero, "Button", null);        if (buttonHwnd != IntPtr.Zero)        {            KeyboardAPI.SendKeyEvent(Keys.Enter, KeyboardAPI.KeyboardEvents.KeyDown | KeyboardAPI.KeyboardEvents.KeyUp);        }    }}

isOk是上面判斷有沒有“擠”進(jìn)去的值,如果沒有“擠”進(jìn)去就進(jìn)行上面的“關(guān)閉提示窗口”的操作,如果已“擠進(jìn)去”則停止即可。

到此,將上面的所有代碼整合到一起,并加入到Timer的定時(shí)執(zhí)行中,我們的“QQ對(duì)戰(zhàn)平臺(tái)擠房器”就實(shí)現(xiàn)了。

 

以下提供程序下載(不提供源碼,但你可以對(duì)其反編譯查看):

/Files/kingthy/QQBattleThruster.rar

NET技術(shù)用C#打造"QQ對(duì)戰(zhàn)平臺(tái)擠房器",轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 新密市| 泗阳县| 台东县| 疏勒县| 汕头市| 治多县| 福泉市| 毕节市| 广东省| 伊宁市| 宜宾县| 颍上县| 余庆县| 南乐县| 台南县| 义马市| 古田县| 鄂托克旗| 吕梁市| 齐河县| 阳谷县| 新沂市| 宜川县| 凤山市| 五华县| 济南市| 灌云县| 改则县| 电白县| 宜昌市| 上杭县| 巴林右旗| 宁夏| 勃利县| 都安| 楚雄市| 海宁市| 辉县市| 怀安县| 赤城县| 岚皋县|