




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
課程分四個(gè)大章節(jié)初級(jí)篇,中級(jí)篇,進(jìn)階篇,高級(jí)篇初級(jí)篇內(nèi)容:編寫(xiě)一個(gè)完整的,簡(jiǎn)單的外掛C++的數(shù)據(jù)類(lèi)型:Byte,Word,DWORD,int,floatAPI函數(shù)的調(diào)mouseevent,GetWindowRect,SetCursorPos,FindWindow,SendMessage)CE5.4工具的使用方法中級(jí)篇內(nèi)容:調(diào)試工具的使用技巧,功能CALL的概念調(diào)試工具0DL1的使用技巧(如硬件斷點(diǎn),條件斷點(diǎn),內(nèi)存斷點(diǎn)。常用匯編指令與對(duì)應(yīng)高級(jí)語(yǔ)言的轉(zhuǎn)換。游戲功能CALL概念找第一個(gè)功能CALL外掛框架的構(gòu)建(通用)進(jìn)階篇內(nèi)容:分析游戲內(nèi)部數(shù)據(jù),分析常用功能CALL游戲數(shù)據(jù)實(shí)踐找各種功能CALL(如打怪,選怪,物品使用,技能欄之類(lèi))及相應(yīng)的代碼編寫(xiě)高線篇內(nèi)容?編寫(xiě)完整外柱完成二個(gè)相對(duì)完整的外掛,實(shí)現(xiàn)自動(dòng)掛機(jī),打怪,存放物品之類(lèi)的功能1入門(mén)篇.一個(gè)最簡(jiǎn)單的外掛游戲窗口數(shù)據(jù)分析(SPY++) 10a、取得窗口相對(duì)坐標(biāo)b、讀出游戲窗口信息GetWindowRectc、移動(dòng)鼠標(biāo)指針SetCursorPos1.2用VC++寫(xiě)個(gè)最簡(jiǎn)單的外掛(實(shí)現(xiàn)游戲開(kāi)局)--12a、鼠擬鼠標(biāo)單擊mouse_eventb、鼠標(biāo)指針移動(dòng)還原一c、集成到startgame函數(shù)里用CE查找棋盤(pán)數(shù)據(jù) 14CE中的數(shù)據(jù)類(lèi)型a、數(shù)據(jù)類(lèi)型:Bit,Byte,Word,Dword,float,doubleb,用CE查找出坐位號(hào);c、保存分析數(shù)據(jù)編程讀出坐位號(hào); 15a、遠(yuǎn)程讀取進(jìn)程數(shù)據(jù)b、打開(kāi)遠(yuǎn)程進(jìn)程c、讀取遠(yuǎn)程進(jìn)程數(shù)據(jù)用CE杳出棋盤(pán)基址; 16a、找棋盤(pán)數(shù)據(jù)基址b、分析棋盤(pán)數(shù)據(jù)結(jié)構(gòu)讀出當(dāng)前棋盤(pán)數(shù)據(jù) 17a、編程讀出棋盤(pán)數(shù)據(jù)b、棋盤(pán)數(shù)據(jù)顯示出來(lái)用模擬技術(shù)編制外掛 181.3.1分析棋子與棋盤(pán)坐標(biāo)關(guān)系a、鼠標(biāo)軟件模擬,函數(shù)SendMessageb、分析窗口內(nèi)棋子相對(duì)坐標(biāo)X,丫c、軟件模擬點(diǎn)擊棋盤(pán)坐標(biāo)x,y處的棋子1.3.2消掉一對(duì)棋子的算法框架 20a、遍歷棋盤(pán)同類(lèi)型棋子配對(duì)b、構(gòu)建算法框架1.3.3(Check2p)大致框架(算法核心) 21a、在這一對(duì)棋子間找相通路徑的原理b、(Check2P函數(shù))框架代碼c,(CheckLine函數(shù))檢測(cè)2點(diǎn)是否仃連通.1.3.4CheckLine實(shí)現(xiàn)23a、CheckLine函數(shù)實(shí)現(xiàn)b、Check2P核心代碼架構(gòu)TOC\o"1-5"\h\z1.3.5Check2P完整代碼實(shí)現(xiàn) 25a、完整的Ceheck2P代碼解析b、完善CheckLine函數(shù)1.3.6Click2P函數(shù)實(shí)現(xiàn),單消棋子功能實(shí)現(xiàn) 33a、完成Click2P函數(shù)b、單消一對(duì)棋子的實(shí)現(xiàn)c,修改ClearPair函數(shù)1.3.7掛機(jī)/秒殺/ 35a、自動(dòng)開(kāi)局b、掛機(jī)下棋1.3.8游戲外掛界面美化 38a、添加進(jìn)度條b、界面調(diào)整c、Slider控件屬性設(shè)置1.3.9倒計(jì)時(shí)與棋子數(shù)(基址查找) 40a、查找棋子數(shù)b、查找倒計(jì)時(shí)c、開(kāi)局標(biāo)志1.4編寫(xiě)完整外掛 401.4.1優(yōu)化自動(dòng)開(kāi)局函數(shù)StartGamea、讓游戲窗口iWjiWj在上b、優(yōu)化開(kāi)局函數(shù)去掉游戲倒計(jì)時(shí)限制-- -42a、找到計(jì)時(shí)代碼b、動(dòng)態(tài)修改游戲代碼(OD使用初探)c、去掉計(jì)時(shí)限制 44 44a、功能測(cè)試b、修改完善外掛c、讀出當(dāng)前棋子數(shù)d、秒殺實(shí)現(xiàn)4.4初級(jí)篇小結(jié) 46a、游戲分析小結(jié)b、編程小結(jié)2中級(jí)篇以XX3D游戲?yàn)槔治銮暗臏?zhǔn)備..CALL簡(jiǎn)介: 491.1,CALL的概念(遠(yuǎn)程調(diào)用CALL)a、寫(xiě)個(gè)調(diào)用示例(假想游戲客戶端)b、用0D找CALL,初探(用0D找出我們自己寫(xiě)的CALL)c、代碼注入器,遠(yuǎn)程CALL調(diào)用2.1.2、遠(yuǎn)程CALL調(diào)用代碼實(shí)現(xiàn) 51a、CreateRemoteThreadAPI函數(shù)b、無(wú)參數(shù)的遠(yuǎn)程CALL調(diào)用(代碼實(shí)現(xiàn))2.1.3、調(diào)試工具0D簡(jiǎn)介(人物角色)血值,魔力值,坐標(biāo)偏移;53a、CE找出當(dāng)前血值偏移b、0D分析出魔力值,坐標(biāo)偏移c、導(dǎo)出游戲關(guān)鍵代碼TOC\o"1-5"\h\z2.1.4、游戲基址概念; 54a、基址+偏移概念b、讀寫(xiě)內(nèi)存函數(shù)參數(shù)簡(jiǎn)介c、編程實(shí)現(xiàn)讀出(血值,魔力值)2.1.5、常用匯編指令詳解 56a、Mov指令的幾種形式b、匯編指與高級(jí)語(yǔ)言的轉(zhuǎn)換c、push指令2.1.6>內(nèi)聯(lián)匯編編程實(shí)例 58a、加法addb、減法subc、純匯編調(diào)用函數(shù)CALL(參數(shù)的傳遞)d、堆棧平衡技能欄使用-游戲分析利器OD(OllyDbg)吃金創(chuàng)藥CALL- —-59a、CE工具使用技巧b、0D斷點(diǎn)F2c、分析CALL的參數(shù)d、代碼注入器測(cè)試CALL編寫(xiě)自己的CALL測(cè)試代碼61a、遠(yuǎn)程分配內(nèi)存空間VirtualAllocExb、向游戲進(jìn)程注入自己代碼c、遠(yuǎn)程調(diào)用《吃金創(chuàng)藥》DLL外掛框架構(gòu)建1、DLL動(dòng)態(tài)鏈接庫(kù)構(gòu)建,與調(diào)用 62a、建立MFC動(dòng)態(tài)鏈接庫(kù)dllb、EXE程序中調(diào)用DLL函數(shù)API與回調(diào)函數(shù)64a、鍵盤(pán)勾子回調(diào)函數(shù)keyProcb、安裝函數(shù)SetupFunc、注入DLL至游戲進(jìn)程空間DLL中構(gòu)建窗口 66a、DLL中插入窗口資源b、在游戲內(nèi)創(chuàng)建DLL窗口c、DLL內(nèi)CALL代碼書(shū)寫(xiě)(以吃紅藥為例)選怪功能實(shí)現(xiàn)TOC\o"1-5"\h\z找怪物列表基址 68a、選定怪IDb、怪物數(shù)組基址c、怪物數(shù)組大小4.2、分析怪對(duì)象屬性 70a、怪對(duì)象IDb、怪與玩家距離c、怪物死亡狀態(tài)遍歷怪物列表 71a、選怪關(guān)鍵代碼b、定位一個(gè)怪對(duì)象c、選怪功能實(shí)現(xiàn)選怪功能優(yōu)化 73a、0D分析選怪功能對(duì)應(yīng)代碼b、寫(xiě)測(cè)試代碼讓選定怪物血條正確顯示c、集成選怪函數(shù)到SelMonO用0D分析游戲功能CALL.《XXXXXX》為例:主要是找CALL普通攻擊CALL關(guān)鍵代碼分析75a、更新游戲選怪基址b、分析攻擊CALL關(guān)鍵代碼c、匯編指令與應(yīng)高級(jí)語(yǔ)言對(duì)照翻譯d、編程測(cè)試5.2、掛機(jī)打怪功能 751、更新選怪CALL地址2,優(yōu)化代碼結(jié)構(gòu)3、自動(dòng)選怪代碼編寫(xiě)4、自動(dòng)打怪代碼編寫(xiě)5、代碼測(cè)試2.5.3、物品背包數(shù)組基址+偏移分析(CE+OD) 79a、確定突破口b、回溯基址c、用0D驗(yàn)證d、推導(dǎo)出基址+偏移公式TOC\o"1-5"\h\z2.5.4、使用指定物品UseGoods(intindex=0); 80a、算法原理b、返回物品在背包中的下標(biāo)intGetGoodsIndex(char*name);c,useGoods(GetGoodsIndex("金創(chuàng)藥(小)”);TabCtrl控件的使用(VC++基礎(chǔ)好的可跳過(guò)) 84a、mtab.Insertitemb、mtab.GetCurSel()c、Create(IDDPAG1,GetDlgltem(IDCTAB))TabCtrl控件BUG修證(VC++基礎(chǔ)好的可跳過(guò)) 85a、修證亂碼b、修證對(duì)齊c、局部美化(位置大小調(diào)整)撿物功能分析實(shí)現(xiàn) 86a、撿物功能CALL分析b、撿物CALL參數(shù)分析c、找出所仃動(dòng)作CALL(打坐/普攻/撿物/交易/組隊(duì)/走跑切換)d、測(cè)試及封裝到pickgoods()函數(shù)F1-F10技能數(shù)組分析 88a、Fl-Fl0技能欄數(shù)組(基址+偏移)b、F1-F10功能調(diào)用核心代碼分析F1-F10功能CALL 90a、找出真的功能CALLb、F1-F10功能CALL參數(shù)分析c、F1-F10功能CALL測(cè)試(集成功能至GameProc.h)3、進(jìn)階篇主要講功能CALL的參數(shù)分析匯編浮點(diǎn)指令/浮點(diǎn)運(yùn)行/浮點(diǎn)數(shù)整數(shù)轉(zhuǎn)換/匯編里的指針喊話功能CALL地址 —93a、找喊話內(nèi)容地址b、分析出關(guān)鍵CALLc、測(cè)試關(guān)鍵CALL喊話功能VC++實(shí)現(xiàn) 94a、分析喊話CALL參數(shù)基址+偏移b、匯編指令leac、字串操作REPNZ/REPNE與SCASd、V++代碼實(shí)現(xiàn)973.2.1、走路相關(guān)數(shù)據(jù)分析(為分析走路/尋路CALL做準(zhǔn)備)一97a、查找當(dāng)前角色坐標(biāo)(xhy)b、杳找目的地坐標(biāo)(xhy)偏移+基址c、找出相關(guān)CALLTOC\o"1-5"\h\z3.2.2、走路功能CALL及相關(guān)分析 98a、隱藏的push指令b、測(cè)試走路CALLc、確定功能CALL及參數(shù)3.2.3、對(duì)找到的幾個(gè)疑是CALL進(jìn)行測(cè)試 100a、分析出疑是CALL相關(guān)參數(shù)b、對(duì)找到的CALL進(jìn)行逐一測(cè)試c、確定真正的走路CALL人物走跑站狀態(tài)開(kāi)關(guān)分析 102a、走路CALL狀態(tài)開(kāi)關(guān)分析b、分析狀態(tài)開(kāi)關(guān)基址+偏移c、分析走路目的地址相關(guān)基址+偏移利用分析數(shù)據(jù)實(shí)現(xiàn)走路/尋路 104a、走路功能代碼實(shí)現(xiàn)b、測(cè)試c、封裝到walk(x,y)d、瞬移(穿墻)怪物過(guò)濾怪物列表關(guān)鍵代碼分析 105a、怪物列表(分析原理)b、回溯怪物列表基址+偏移c、取得怪物對(duì)象的公式3.2、怪物屬性分析 107a、怪物名b、怪物血量c、怪物IDd、怪物與玩家距離e、提取特征碼怪物過(guò)濾的編寫(xiě)代碼 108a、讀出怪物列表b、過(guò)濾掉指定怪物c、選定特定怪物d、過(guò)濾打怪測(cè)試e、選中最近怪物物品過(guò)濾物品屬性分析 111a、物品IDb、物品對(duì)象c、物品屬性分析物品過(guò)濾(編程讀出物品列表數(shù)據(jù)) 112a、讀出物品列表b、條件判斷是否撿物(距離,物品名)C、顯示出提示信息撿物過(guò)濾 113a、分析撿物深層CALLb、PickID(物品ID);c、撿物過(guò)濾d、撿物范圍控制游戲多開(kāi)實(shí)現(xiàn) 116a、游戲防止多開(kāi)的原理b、找出本游戲多開(kāi)的方法c、測(cè)試驗(yàn)證組隊(duì)相關(guān)選定指定角色 118a、多開(kāi)BUG修證b、分析玩家屬性c、遍歷玩家列表d、選定指定玩家角色原理e、intSelPlayEr(pchar玩家名);計(jì)算玩家間的距離(已知坐標(biāo)) 120a、坐標(biāo)系內(nèi)的點(diǎn)1與點(diǎn)2b、2點(diǎn)間的距離計(jì)算公式c、準(zhǔn)備知識(shí)d、planRange(intpl,intp2)函數(shù)構(gòu)建組隊(duì)功能123a、更新組隊(duì)動(dòng)作CALLb、選定指定玩家c、邀請(qǐng)指定玩家加入隊(duì)伍intInvite(char*playName);離隊(duì)功能 124a、分析離隊(duì)動(dòng)作b、逆向分析離隊(duì)代碼c、初識(shí)封包d、Repstos[edi]e、內(nèi)存中的數(shù)據(jù)與byte,int的對(duì)應(yīng)關(guān)系f、封裝離隊(duì)函數(shù)voidexitTeamO;售物/購(gòu)物(封包的世界)售物功能封包分析 1261、封包回溯,找未加密的封包2、確家關(guān)鍵CALL3、分析封包(物品數(shù)量,類(lèi)型,位置)4、功能測(cè)試SellGoods函數(shù)構(gòu)建6.2售物封包參數(shù)來(lái)源分析 1281、數(shù)量分析2、出售物品類(lèi)型分析3、出售物品在背包里的格數(shù)4、各種數(shù)據(jù)的來(lái)源編程實(shí)現(xiàn)出售背包指定物品 1321、遍歷背包指定物品2、出售背包第一格物品3、出售背包第N格物品完善售物功能 1341、構(gòu)建函數(shù)intFindlndex(char*name);Findindex〃用來(lái)查詢(xún)指定物品名name在背包中的位置2、垃圾物品清單3、遍歷出售所有垃圾物品SellGoods4、移植函數(shù)到Gameproc,h6.5、打開(kāi)NPC購(gòu)物/售物對(duì)話框 1371、打開(kāi)NPC對(duì)話2、打開(kāi)NPC(買(mǎi)進(jìn)/賣(mài)出)窗口3、封裝到intOpenNpc_buysell();測(cè)試購(gòu)物功能封包分析 1401、封包回溯,找未加密的封包2、確家關(guān)鍵CALL3、分析封包4、數(shù)量分析5、出售物品類(lèi)型分析6、功能測(cè)試3.7、擺攤.開(kāi)店3.7.1開(kāi)店封包分析 142a、店名分析b、封包參數(shù)分析c、為T(mén)AB選項(xiàng)卡2添加內(nèi)容d、不同CPP之間共享函數(shù)及變量的方法d、寫(xiě)申請(qǐng)開(kāi)店代碼測(cè)試3.7.2開(kāi)店封包(掛店物品分析) 145a、分析封包b、封包出售物品的格式分析c、寫(xiě)代碼測(cè)試4、高級(jí)篇4.0、編寫(xiě)相對(duì)完整的外掛 1494.0.1、窗口界面整理a、常規(guī)選項(xiàng)卡b、保護(hù)選項(xiàng)卡c、撿物選項(xiàng)卡d、喊話選項(xiàng)卡4.0.2、常規(guī)選項(xiàng)卡一自動(dòng)打怪函數(shù)構(gòu)建 154a、關(guān)聯(lián)變量b、選怪函數(shù)優(yōu)化c、共享變量externd、算法設(shè)計(jì)e、功能測(cè)試4.0.3、保護(hù)選項(xiàng)卡-自動(dòng)補(bǔ)紅補(bǔ)藍(lán)函數(shù)構(gòu)建 159a、402中的BUG修整b、算法設(shè)計(jì)c、編寫(xiě)代碼d、功能測(cè)試4.0.4、撿物選項(xiàng)卡-自動(dòng)撿物函數(shù)構(gòu)建 164a、過(guò)濾垃圾物品-不撿垃圾列表里的物品b、算法設(shè)計(jì)c、編寫(xiě)代碼d、功能測(cè)試4.0.5^喊話選項(xiàng)卡-自動(dòng)喊話設(shè)置 168a、關(guān)聯(lián)變量b、喊話功能算法設(shè)計(jì)c、編寫(xiě)代碼d、功能測(cè)試TOC\o"1-5"\h\z游戲更新后的外掛更新 174腳本功能 175盜號(hào)的實(shí)現(xiàn) 180初級(jí)篇1.1.1教學(xué)目標(biāo):模擬鼠標(biāo)操作游戲數(shù)據(jù)分析(SPY++)a、取得窗口相對(duì)坐標(biāo)b、讀出游戲窗口信息GetWindowRectc、移動(dòng)鼠標(biāo)指針SetCursorPosHWNDFindWindow(LPCTSTRIpClassName,〃窗口類(lèi)名LPCTSTRIpWindowName〃窗口標(biāo)題);教學(xué)過(guò)程:取游戲標(biāo)題:QQ游戲-連連看角色版取開(kāi)局所在坐標(biāo):x=655;y=577//Iparam0x0241028f攔截消息:WM_LBL'TT0ND0WN,WM_LBUTTONUPAPI-FindWindow(NULL,"QQ游戲-連連看角色版”);//FindWindow,GetWindowRect,SetCursorPos////////////////////////////////////首先還是要用SPY查找游戲窗口,這里用到的是中文版,用“查找窗口”找到游戲標(biāo)題:“QQ游戲-連連看角色版”,再次用查找窗口功能,這次選擇“消息”,用來(lái)查找鼠標(biāo)指向開(kāi)始按鈕的消息位置.先讓消息停下來(lái),這次選擇消息的類(lèi)型WM_LBUTT0ND0WN和WM_LBUTTONUP,找到鼠標(biāo)點(diǎn)擊位置取開(kāi)局所在坐標(biāo):x=655;y=577//Iparam0x0241028f下面打開(kāi)VC,新建-工程-MFCEXE-工程名是LLKWG,然后選擇基本對(duì)話框,完成即可
ax還要在編輯框中關(guān)聯(lián)變量,建立類(lèi)向?qū)x還要在編輯框中關(guān)聯(lián)變量,建立類(lèi)向?qū)г谟螒蜷_(kāi)局按鈕輸入代碼//Thesystemcallsthistoobtainthecursortodisplaywhiletheuserdrags//theminimizedwindow.HCURSORCLlkwgDlg::OnQueryDraglcon()(return(HCURSOR)mhlcon;)HWNDgameh;〃游戲窗口句柄RECTrl; //RECT結(jié)構(gòu)表示一個(gè)矩形區(qū)域voidCLlkwgDlg::OnStartGame()(//TODO:Addyourcontrolnotificationhandlercodeheregameh=::FindWindow(NULL,"QQ游戲-連連看角色版");//獲取游戲窗口句柄::GetWindowRect(gameh,&rl); 〃這里取坐標(biāo),雙冒號(hào)是全局的意思this->m_x=rl.left;this->m_y=rl.top;〃讀出窗LI左上角坐標(biāo),this是關(guān)聯(lián)變量UpdateData(false); 〃顯示到編輯框〃設(shè)置鼠標(biāo)指針位置取開(kāi)局所在坐標(biāo):x=655;y=577//Iparam0x0241028fSetCursorPos(655+rl.left,577+rl.top);〃當(dāng)前窗口坐標(biāo)+開(kāi)局按鈕坐標(biāo)1.1.2用VC++寫(xiě)個(gè)最簡(jiǎn)單的外掛(實(shí)現(xiàn)游戲開(kāi)局)a、鼠擬鼠標(biāo)單擊mouse_eventb、鼠標(biāo)指針移動(dòng)還原c、集成到startgame函數(shù)里教學(xué)過(guò)程:〃模擬鼠標(biāo)的單擊(鼠標(biāo)按下/鼠標(biāo)抬起)//MOUSEEVENTFLEFTDOWNSpecifiesthattheleftbuttonisdown.//MOUSEEVENTFLEFTUP〃鼠標(biāo)在當(dāng)前位置按Fmouseevent(MOUSEEVENTFLEFTDOWN,0,0,0,0);〃鼠標(biāo)在當(dāng)前位置抬起mouseevent(MOUSEEVENTFLEFTUP,0,0,0,0);小結(jié):mouseevent,Sleep,SetCursorPos///////////////這次用到了鼠標(biāo)點(diǎn)擊的函數(shù)mouse_event鼠標(biāo)硬件模擬,如果調(diào)用不成功則延時(shí)一下Sleep(200),然后再將鼠標(biāo)移回原位SetCursorPos這個(gè)是位置設(shè)置函數(shù)調(diào)用成功后,將函數(shù)放在一個(gè).h頭文件里,方便以后調(diào)用.新建c/c++HeaderFile,文件名GameProc#include"stdafx.h"〃游戲功能函數(shù)HWNDgameh;RECTrl;POINTp;//x,yvoidstartGame()(//TODO:Addyourcontrolnotificationhandlercodehere〃獲取游戲窗口句柄gameh=::FindWindow(NULL,"QQ游戲-連連看角色版”);::GetWindowRect(gameh,&rl);〃保存當(dāng)前鼠標(biāo)指針//取得當(dāng)前鼠標(biāo)位置GetCursorPos(&p);〃設(shè)置鼠標(biāo)指針位置取開(kāi)局所在坐標(biāo):x=655;y=577//Iparam0x0241028fSetCursorPos(655+r1.left,577+r1.top);〃模擬鼠標(biāo)的單擊(鼠標(biāo)按下/鼠標(biāo)抬起)mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);〃鼠標(biāo)在當(dāng)前位置按下mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);〃鼠標(biāo)在當(dāng)前位置抬起mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);Sleep&OO);〃過(guò)一段時(shí)間再執(zhí)行后邊的代碼SetCursorPos(p.x,p.y);〃還原鼠標(biāo)位置當(dāng)然還要將這個(gè).h文件包涵進(jìn)主函數(shù)里Sinclude"stdafx.h"#include"llk_wg.h”#include/Z1IkwgDlg.h?,#include"GameProc.h"然后這樣調(diào)用voidCLlkwgDlg::OnStartGame()(startGame();今天我們要一起學(xué)習(xí)的是L2.1教學(xué)目標(biāo):1.2.1、CE中的數(shù)據(jù)類(lèi)型a、數(shù)據(jù)類(lèi)型:Bit,Byte,Word,Dword,float,doubleb、用CE查找出坐位號(hào);c、保存分析數(shù)據(jù)教學(xué)過(guò)程:a、數(shù)據(jù)類(lèi)型:Bit,Byte,Word,Dword,float,doubleC++數(shù)據(jù)類(lèi)型bit/位1位取值范圍:0..1byte(字節(jié))=0..11111111(2進(jìn)制)=0..255(如進(jìn)制)=0..FF (16進(jìn)制)WORD(單字)=2Byte=0..65535(10進(jìn)制) =0..FFFF(16進(jìn)制)DWORD(雙字)=2W0RD=4Byte=0..4294967295=0..FFFFFFFFfloat(浮點(diǎn)數(shù))double(雙浮點(diǎn)數(shù))int(4字節(jié)),long(4字節(jié)),WORD,DW0RD(4字節(jié)),float(4字節(jié)),double字字節(jié))b、用CE查找出坐位號(hào);打開(kāi)QQ游戲連連看猜測(cè)0..5,1..6,順時(shí)針0..7坐位號(hào)地址:0x00B8D8E0///////////////////////////////////首先講了關(guān)于十六進(jìn)制/十進(jìn)制/八進(jìn)制/二進(jìn)制/字節(jié)/雙字節(jié)等基礎(chǔ)知識(shí)因?yàn)橛螒虍?dāng)中不同的座位號(hào)數(shù)據(jù)不一樣,所以首先要找到座位號(hào).用CE搜索游戲是字節(jié)型來(lái)查找游戲的座位號(hào),一桌是6個(gè)位置,猜測(cè)是從0到5,上面是0,順時(shí)針?lè)较蚣覮所以我們更換座位號(hào)后再繼續(xù)用CE搜索相應(yīng)的位置號(hào),注意附加的進(jìn)程可不要出錯(cuò)哦.QQ連連看的進(jìn)程名是KYODAI'LEXE,可以用任務(wù)管理若W找出找到后將CE的數(shù)據(jù)保存一下,方便下次調(diào)用.這節(jié)課主要講了字節(jié)的基礎(chǔ)知識(shí)和CE的基本用法今天我們要一起學(xué)習(xí)的是L2.2教學(xué)目標(biāo):編程讀出坐位號(hào);a、遠(yuǎn)程讀取進(jìn)程數(shù)據(jù)b、打開(kāi)遠(yuǎn)程進(jìn)程c、讀取遠(yuǎn)程進(jìn)程數(shù)據(jù)教學(xué)過(guò)程:API函數(shù)介紹1、FindWindow 〃獲取窗口句柄2、GetWindowThreadProcessId〃獲取窗口進(jìn)程ID3、OpenProcess 〃打開(kāi)指定進(jìn)程4、ReadProcessMemory 〃讀指定進(jìn)程內(nèi)存數(shù)據(jù)游戲進(jìn)程名:KYODAri.EXE游戲窗口標(biāo)題:"QQ游戲-連連看角色版”HWNDFindWindow(LPCTSTRIpClassName,//NULL忽略LPCTSTRIpWindowName//窗口標(biāo)題BOOLReadProcessMemory(HANDLEhProcess,//進(jìn)程句柄LPCVOIDIpBaseAddress,//基址0x00B8D8E0LPVOIDIpBuffer,//存放數(shù)據(jù)緩沖區(qū)DWORDnSize,//要讀取數(shù)據(jù)的字節(jié)數(shù)LPDWORDIpNumberOfBytesRead//實(shí)際讀取的字節(jié)數(shù)//////////////////////這次需要幾個(gè)函數(shù)來(lái)取得窗口/句柄/進(jìn)程/內(nèi)存等信息幾個(gè)函數(shù)要聯(lián)合運(yùn)用,前一個(gè)函數(shù)的返回值就是后一個(gè)函數(shù)的參數(shù)在VC代碼里添加座位號(hào)的變量m_Num類(lèi)型是UINT,新增一個(gè)按鈕,添加如下代碼constPCHARgameCaption="QQ游戲-連連看角色版”;voidCLlkwgDlg::0nButton2()(//游戲窗口標(biāo)題:“QQ游戲-連連看角色版”//1、FindWindow 〃獲取窗口句柄〃2、GetWindowThreadProcessId〃獲取窗口進(jìn)程ID〃3、OpenProcess 〃打開(kāi)指定進(jìn)程〃4、ReadProcessMemory 〃讀指定進(jìn)程內(nèi)存數(shù)據(jù)〃獲取窗口句柄HWNDgameh=::FindWindow(NULL,gameCaption);〃獲取窗口進(jìn)程IDDWORDprocessid;::GetWindowThreadProcessId(gameh,&processid);〃打開(kāi)指定進(jìn)程HANDLEprocessH=::OpenProcess(PROCESS_ALL_ACCESS,false,processid);〃讀指定進(jìn)程內(nèi)存數(shù)據(jù)DWORDbyread:LPCVOIDpbase=(LPCV0ID)0x00B8D8E0;〃讀取當(dāng)前的指針,強(qiáng)制轉(zhuǎn)換為L(zhǎng)PCVOID指針LPVOIDnbuffer-(LPVOID)&m_num; //保存當(dāng)前的指針,強(qiáng)制轉(zhuǎn)換為L(zhǎng)PVOID指針::ReadProcessMemory(processH,phase,nbuffer,4,&byread);UpdateData(false);〃更新變量的值到編輯框)今天我們要一起學(xué)習(xí)的是L2.3教學(xué)目標(biāo):用CE查出棋盤(pán)基址;a、找棋盤(pán)數(shù)據(jù)基址b、分析棋盤(pán)數(shù)據(jù)結(jié)構(gòu)19寬*11高:數(shù)組bytea[19][ll]byte0..255//00..FF0x0012A508 〃棋盤(pán)數(shù)組基址db地址〃以字節(jié)方式顯示指定地址內(nèi)存里的數(shù)據(jù)////////////////////////前面座位號(hào)的基址已經(jīng)找出了,所以這次要找出棋盤(pán)的數(shù)據(jù),要先查一下棋盤(pán)的2維排列,是19寬*11高,用QQ截圖查找一下長(zhǎng)和寬,然后計(jì)算出每一格的大小.猜測(cè)棋盤(pán)的棋子也是字節(jié)的,我們查找左上角第一棋子的數(shù)據(jù).用CE查找,如果有棋子就是大于0,變化了就再搜索更改的數(shù)值,沒(méi)有棋子就是0,多次查找就找到第一棋子的地址了.自己找個(gè)座位坐下來(lái),加個(gè)密碼不讓別人進(jìn),
多按幾次"練習(xí)”按鈕,這樣棋盤(pán)變化就方便找棋子數(shù)據(jù)了.老師也查找出錯(cuò)了,再來(lái)一次吧.找到后用0D加載一下看看,這樣的數(shù)據(jù)排序看的比較清楚這節(jié)課講解了CE查找的方法今天我們要一起學(xué)習(xí)的是L2.4教學(xué)目標(biāo):讀出當(dāng)前棋盤(pán)數(shù)據(jù)a、編程讀出棋盤(pán)數(shù)據(jù)b、棋盤(pán)數(shù)據(jù)顯示出來(lái)參考章節(jié):1.2.3,1.2.219寬*11高:數(shù)組bytea[U][19]//a[y][x]byte0..255//00..FF0x0012A508 〃棋盤(pán)數(shù)組基址db地址〃以字節(jié)方式顯示指定地址內(nèi)存里的數(shù)據(jù)itoa(要轉(zhuǎn)換的整數(shù),存放字符數(shù)組,要轉(zhuǎn)換的字符進(jìn)制)for(inty=0;y<=10;y++)//y++y:=Y+l;////////////////////////////////////Cstring類(lèi)添加了一個(gè)編輯框用來(lái)顯示棋盤(pán)數(shù)據(jù),再關(guān)聯(lián)一個(gè)變量m_ChessdataCstring類(lèi)增加”更新棋盤(pán)數(shù)據(jù)”按鈕,添加代碼如下:bytechessdata[ll][19];//a[y][x]voidCLlkwgDlg::OnBtnReadchess()//TODO:Addyourcontrolnotificationhandlercodehere〃獲取窗口句柄HWNDgameh=::FindWindow(NULL,gameCaption);〃獲取窗口進(jìn)程IDDWORDprocessid;::GetWindowThreadProcessId(gameh,&processid);〃打開(kāi)指定進(jìn)程HANDLEprocessH=::OpenProcess(PROCESSALLACCESS,false,processid);〃讀指定進(jìn)程內(nèi)存數(shù)據(jù)DWORDbyread:LPCVOIDphase-(LPCVOID)0x0012A508;〃棋盤(pán)數(shù)據(jù)基址LPVOIDnbuffer=(LPVOID)&chessdata;〃存放棋盤(pán)數(shù)據(jù)::ReadProcessMemory(processH,phase,nbuffer,11*19,&byread);charbuf[ll];〃/顯示棋盤(pán)數(shù)據(jù)m_chessdata="";〃先清空編輯for(inty=0;y<=10;y++)〃一?列一列的讀,FOR循環(huán):丫=0是循環(huán)的起始值,丫<=10是終止值,Y++是每次Y+1{for(intx=0;x<=18;x++)〃一行一行的讀(itoa(chessdata[y][x],buf,16);〃itoa整型轉(zhuǎn)換成字串m_chessdata+=buf;m_chessdata+=")'m_chessdata+="\r'n";〃換行}~UpdateData(false);〃更新數(shù)據(jù))今天我們要一起學(xué)習(xí)的是L3.1教學(xué)目標(biāo):1.3.1分析棋子與棋盤(pán)坐標(biāo)關(guān)系a、鼠標(biāo)軟件模擬,函數(shù)SendMessageb、分析窗口內(nèi)棋子相對(duì)坐標(biāo)X,Yc、軟件模擬點(diǎn)擊棋盤(pán)坐標(biāo)x,y處的棋子SendMessage;SendMessage(hwnd,WMLBUTTOMDOWN,0,YX);//hwnd=FindWindow(NULL,游戲標(biāo)題);SendMessage(hwnd,WMLBLTTOMLP,0,YX);//PostMessage/mouseevent2、獲取棋盤(pán)左上角棋盤(pán)第一格坐標(biāo).棋盤(pán)第一格坐標(biāo)x=21,y=192intx=22,y=187;hwnd=FindWindow(NULL,游戲標(biāo)題):SendMessage(hwnd,WM_LBUTTONDOWN,0,(y?16)+x);//SendMessage(hwnd,WM_LBUTT0NUP,0,(y?16)+x);//3、計(jì)算棋盤(pán)的寬度*高度589*385棋盤(pán)第?格坐標(biāo)x=21,y=19231*35棋子寬度,高度SendMessage(hwnd,WM_LBUTTONDOWN,0,(y?16)+x+31*2);//SendMessage(hwnd,WMLBUTTONUP,0,(y?16)+x);////SendMessage鼠標(biāo)模擬,〃WMLBL'TTONDOWN鼠標(biāo)左鍵按下〃WMLBUTTONUP鼠標(biāo)左鍵抬起//?左移指令//////////////////////////前面都是直接移動(dòng)了鼠標(biāo),這次要改發(fā)送鼠標(biāo)消息了,這樣鼠標(biāo)不移動(dòng)也會(huì)點(diǎn)擊游戲的開(kāi)始按鈕.SendMessage的參數(shù)是相對(duì)坐標(biāo),mouse_event的參數(shù)是絕對(duì)坐標(biāo)再次打開(kāi)SPY++,找到棋盤(pán)第一格的位置,X=21,丫=187新增一個(gè)按鈕,,點(diǎn)擊棋盤(pán)第一格,,方便測(cè)試,添加代碼如下:voidCLlk_wgDlg::0nButton3() 〃按鈕函數(shù)(intx=22,y=187; 〃定義座標(biāo)點(diǎn)HWNDhwnd=::FindWindow(NULL,gameCaption); 〃查找窗口int1param; 〃定義座標(biāo)點(diǎn)變量lparam=(y?16)+x+31*2; 〃表示指定格,丫*16是左移16位,發(fā)消息用的丫座標(biāo)點(diǎn)::SendMessage(hwnd,WM_LBUTTONDOWN,0,Iparam);〃鼠標(biāo)按下消息::SendMessage(hwnd,WMLBUTTONUP,0,Iparam);〃鼠標(biāo)抬起消息用QQ抓圖,查找棋子格子數(shù)大小,31*35的大小,以便計(jì)算出所有格子的座標(biāo)點(diǎn).今天我們要一起學(xué)習(xí)的是L3.2教學(xué)目標(biāo):消掉一對(duì)棋子的算法框架a、遍歷棋盤(pán)同類(lèi)型棋子配對(duì)b、構(gòu)建算法框架//〃遍歷整個(gè)棋盤(pán)找相同一對(duì)棋子//檢測(cè)這一對(duì)棋子是否可以消除〃如果可以消除,則模擬鼠標(biāo)點(diǎn)擊這2點(diǎn)最多一條三條連線能夠形式一條路線就表示可消除////////////////////////////更改”點(diǎn)擊棋盤(pán)第一格”代碼如下:voidClearPiar()//消除一對(duì)棋子(〃讀出棋盤(pán)數(shù)據(jù)至chessdata11,19updatdChess();〃遍歷整個(gè)棋盤(pán)找出相同類(lèi)型一對(duì)棋子POINTpl,p2;〃定義兩個(gè)點(diǎn),座標(biāo)型intxl,yl,x2,y2;〃定義座標(biāo)點(diǎn)for(yl=0;yl〈ll;yl++)〃點(diǎn)1循環(huán),從丫列開(kāi)始for(xl=0;xl〈19;xl++)〃點(diǎn)2循環(huán),從X行開(kāi)始{for(y2=yl;y2<ll;y2++)〃這是點(diǎn)2的丫循環(huán),由Y1開(kāi)始for(x2=xl;x2〈19;x2++)〃這是點(diǎn)2的X循環(huán),由XI開(kāi)始//棋子1與棋子2類(lèi)型是否相同,要求點(diǎn)1與點(diǎn)2相等則假,就是座標(biāo)不能相同.if((chessdataLyl][xl]==chessdata[y2][x2])&&(!((xl==x2)&&(yl==y2))))(pl.x=xl;pl.y=yl;p2.x=x2;p2.y=y2;〃檢測(cè)相同的2個(gè)棋子是否可消掉if(check2P(pl,p2))〃如果可消除則返回真{//click2p鼠標(biāo)模擬點(diǎn)擊pl,p2click2p(pl,p2);)這節(jié)課講的是VC編程,需要對(duì)邏輯運(yùn)算有一定的理解,要檢測(cè)兩點(diǎn)是否相同,同時(shí)要避免在同一點(diǎn),還要檢測(cè)兩點(diǎn)是否可消除,檢測(cè)的函數(shù)check2P先定義了一個(gè)空的,下節(jié)課再添加代碼.模擬鼠標(biāo)點(diǎn)擊的函數(shù)click2P本節(jié)課也沒(méi)有添加代碼.今天我們要一起學(xué)習(xí)的是L3.2教學(xué)目標(biāo):(Check2p)大致框架(算法核心)a、在這一對(duì)棋子間找相通路徑的原理b、(Check2P函數(shù))框架代碼c、(CheckLine函數(shù))檢測(cè)2點(diǎn)是古行連通LineNull(pl,p2);〃是否在棋盤(pán)上的2個(gè)點(diǎn)之前是否仃一條全為0的直線,如仃true,否則faIse1、剪貼游戲圖;丫坐標(biāo)相同的情況下pl,p2lineNulKpl.right,p2.left)〃可消除X坐標(biāo)相同的情況下pl,p2LineNull(pl.down,p2.up) 〃可消除X與丫坐標(biāo)都不相情況Fpl,p21ineN11(pl.down,pa),LineNull(p2.down,pb),LineNul1(pa,pb)〃可消除////////////////////////////////////現(xiàn)在就要來(lái)分析游戲了,連連看大家都知道,是需要判斷兩點(diǎn)間是否可以連接的,比如有直連,有一折后的連接,最多是二折后的連接.如果是直連的話,就要判斷中間是否所有的數(shù)據(jù)都為0,判斷的思路很主要,一定要搞清楚.而有折的連接則需要多條直線,最多是三條直線,這個(gè)需要遍歷,不斷的向下判斷.將VC代碼打開(kāi),插入一個(gè)類(lèi)GenericClass,名稱(chēng)為CChessPoint添加代碼如下:classCChessPoint(public:POINTp;〃臨時(shí)點(diǎn)POINTup;〃上點(diǎn)POINTdown;//卜一點(diǎn)POINTleft;〃左點(diǎn)POINTright;〃右點(diǎn)CChessPoint(POINTpxy);〃構(gòu)造函數(shù)virtual^CChessPoint(););還要在Cchesspoint.cpp實(shí)現(xiàn)部分修改代碼CChessPoint::CChessPoint(POINTpxy){up=pxy;down=pxy;left=pxy;right=pxy;〃將座標(biāo)初始化〃向上下左右擴(kuò)展P=pxy;up.y=pxy.y-1;down.y=pxy.y+1;left.x=pxy.x-1;right.x=pxy.x+1;〃這樣處理完之后每個(gè)棋子就包涵了上下左右中五個(gè)點(diǎn)的屬性CChessPoint::?CChessPoint()在按鈕部分增加代碼如下:bool1ineNull(POINTpl,POINTp2){returntrue;〃先寫(xiě)個(gè)空的,下?課繼續(xù).)boolcheck2p(POINTpl,POINTp2){〃檢測(cè)pl,p22個(gè)棋子是否可以消除//丫坐標(biāo)相同的情況下pl,p2//IineNul1(pl.right,p2.left)//可消除if(pl.y==p2.y)//如果列相同則執(zhí)行{CChessPointpa(pl),pb(p2);〃先建立類(lèi),初始化兩點(diǎn)if(1ineNull(pa.down,pb.up))returntrue;〃先將兩個(gè)點(diǎn)類(lèi)化,可消除返回真)//X坐標(biāo)相同的情況下pl,p2//LineNull(pl.down,p2.up) 〃可消除if(pl.x==p2.x)//如果行相同則執(zhí)行此句{CChessPointpa(pl),pb(p2);if(1ineNull(pa.down,pb.up))returntrue;〃*與丫坐標(biāo)都不相情況下pl,p2//lineNull(pl.down,pa),LineNull(p2.down,pb),LineNull(pa,pb)〃可消除returntrue;這節(jié)講VC,比較難理解,很多地方與DELPHI不同,老師寫(xiě)了很多代碼,我不太懂,是不是代碼寫(xiě)的太啰嗦了?還是我水平太差.我再繼續(xù)學(xué)學(xué)看,如果不懂的太多,就要參考別的VC教程一起學(xué)習(xí)了.這節(jié)課代碼還沒(méi)有寫(xiě)完,時(shí)間已經(jīng)到了,下節(jié)繼續(xù).今天我們要一起學(xué)習(xí)的是L3.4教學(xué)目標(biāo):CheckLine實(shí)現(xiàn)a、CheckLine函數(shù)實(shí)現(xiàn)b、Check2P核心代碼架構(gòu)boolCheckLine(POINTpl;POINTp2)(〃乂坐標(biāo)相同//pl.ytop2.y〃丫坐標(biāo)相同//pl.xtop2.x///////////////////////////////首先還是要添加修改兩點(diǎn)間是直線的判斷函數(shù)boolCheckLine(POINTpl,POINTp2)//檢測(cè)2點(diǎn)間是否連通(存在一條全為0的直線路徑)(intx,y;if(pl.x==p2.x)〃兩點(diǎn)X坐標(biāo)相同for(y=pl.y;y<=p2.y;y++)〃假如ChessData[y][pl.x]丫的某一個(gè)點(diǎn)大于0則說(shuō)明有棋子,就返回false;if(chessdata[y]Lpl.x]>0)returnfalse;elseif(pl.y==p2.y)(for(x=pl.x;x〈=p2.x;x++){〃假如ChessData[pl.y][x]X某一點(diǎn)有棋子則大于0返回false;if(chessdata[pl.y][x]>0)returnfalse;returntrue;再添加除了直線的兩點(diǎn)函數(shù)檢測(cè)的代碼boolcheck2p(POINTpl,POINTp2)(CChessPointpa(pl),pb(p2);〃初始化棋子類(lèi)POINTpll,p22;〃新建兩個(gè)變量指針,方便調(diào)用intx,y;〃新建兩個(gè)整型變量,方便調(diào)用//檢測(cè)pl,p22個(gè)棋子是否可以消除if(pl.y==p2.y)//丫坐標(biāo)相同的情況下pl,p2(if(CheckLine(pa.down,pb.up))returntrue;〃找到相同路線//pa,pb;pa,p_l;pb,p_2;pll=pl;p22-p2;for(y=0;y<ll;y++)(pll.y=p22.y=y;〃找到轉(zhuǎn)折的路線ifheckLine(pll,p22)&&CheckLine(pa.up,pll)&&CheckLine(pb.up,p22))returntrue;本節(jié)全是在編寫(xiě)VC代碼,思考如何判斷幾條連線,代碼也沒(méi)寫(xiě)完,也沒(méi)測(cè)試,不知道對(duì)不對(duì),時(shí)間到了,下節(jié)課繼續(xù)寫(xiě).今天我們要一起學(xué)習(xí)的是L3.5教學(xué)目標(biāo):1.3.5Check2P完整代碼實(shí)現(xiàn)a、完整的Ceheck2P代碼解析b、完善CheckLine函數(shù)Check2P實(shí)現(xiàn)原理;分類(lèi):丫坐標(biāo)相同:pa=pl.left,pb=p2.right//pa,pb之間是否連通則消除X坐標(biāo)相同:pa=pl.down,pb=p2.up〃pa,pb之間是否連通則消除X,丫坐標(biāo)都不相同pa,pb//pl,pa//pb,p2這三線路都連通則可消除pl,pa,//pa,pb//p2,pb這三線路都連通則可消除/////////////////////本節(jié)課老師講課用了FLASH工具,比起之前用畫(huà)圖要強(qiáng)的多,使我一下子就理解了這幾個(gè)點(diǎn)之間的關(guān)系.比如在兩點(diǎn)可以直連的情況下,第一個(gè)棋子是P1,第二個(gè)棋子是P2,第一個(gè)棋子與第二個(gè)棋子之間的點(diǎn)是PA到PB,這兩個(gè)點(diǎn)要不斷的循環(huán),查找其中是否為空,如果為空則可以消除.當(dāng)然這是橫向的連接,同時(shí)還有豎向的連接丫坐標(biāo)相同:pa=pl.left,pb=p2.right//pa,pb之間是否連通則消除當(dāng)然更多的是折線的連接X(jué),丫坐標(biāo)都不相同pa,pb//pl,pa//pb,p2這三線路都連通則可消除pl,pa,//pa,pb//p2,pb這三線路都連通則可消除老師已經(jīng)寫(xiě)好了三個(gè)函數(shù)的代碼boolCheckLine(POINTpl,POINTp2)(intx,y,t; //同一線上的兩點(diǎn)間全為0則返回真//如果pl==p2也返回真if((pl.x==p2.x)&&(pl.y==p2.y)&&(chessdata[pl.y][pl.x]==0)&&(chessdata[p2.y][p2.x]==0)){returntrue; }elseif((pl.x<0)|(pl.x>18)||(pl.y<0)||(pl.y>10)|(p2.x<0)||(p2.x>18)||(p2.y<0) (p2.y>10)){returnfalse;}if(pl.x==p2.x) 〃如果X軸相等則比較(if(pl.y>p2.y){t=pl.y;pl.y=p2.y;p2.y=t;}for(y=pl.y;y〈=p2.y;y++)(if(chessdata[y][pl.x]!=0){returnfalse;}if(pl.y==p2.y)( 〃如果丫軸相等則比較if(pl.x>p2.x){t=pl.x;pl.x=p2.x;p2.x=t;}for(x=pl.x;x〈=p2.x;x++)if(chessdataEpl.y][x]!=0){returnfalse;}returntrue;);另一個(gè)函數(shù),這個(gè)因?yàn)榕c窗口有關(guān)系,所以就轉(zhuǎn)移到Uk_wgDlg.cpp里boolClearPiar()〃消除~?對(duì)棋子(〃讀出棋盤(pán)數(shù)據(jù)至chessdata11,19updateChess();〃遍歷整個(gè)棋盤(pán)找出相同類(lèi)型一對(duì)棋子POINTpl,p2;intxl,yl,x2,y2;for(yl=0;yl<l1;yl++)for(xl=0;xl<19;xl++){for(y2=y1;y2<11;y2++)for(x2=xl;x2<19;x2++)if((chessdata[yl][xl]==chessdata[y2][x2])//棋子1與棋子2類(lèi)型是否相同&&(!((xl==x2)&&(yl==y2)))〃要求點(diǎn)1與點(diǎn)2相等則假){pl.x=xl;pl.y=yl;p2.x=x2;p2.y=y2;〃檢測(cè)相同的2個(gè)棋子是否可消掉if(Check2P(pl,p2))〃如果可消除則返回真{//click2p鼠標(biāo)模擬點(diǎn)擊pl,p2click2p(pl,p2);m_plx=xl;m_piy-yi;m_p2x=x2;m_p2y=y2;UpdateData(false);returntrue;returnfalse;還有一個(gè)最長(zhǎng)的函數(shù)boolCheck2p(POINTa,POINTb)(CChessPointpl(a),p2(b);POINTpa,pb;〃轉(zhuǎn)角點(diǎn)intx,y;//如果2點(diǎn)為同一點(diǎn)則返回假if((a.x==b.x)&&(a.y==b.y)) {returnfalse;}elseif((chessdata[a.y][a.x]==0)||(chessdata[b,y][b.x]==0)){returnfalse;}elseif(chessdata[a.y][a.x]!=chessdata[b.y][b.x]){returnfalse;}pa=a;pb=b;//在橫向一條線上y坐標(biāo)相同if(a.y==b.y){ //2點(diǎn)在y軸相鄰if((pl.right.x=p2.p.x)||(pl.left.x==p2.p.x)) {returntrue; }〃檢測(cè)這條線是否有一條路徑相通if(CheckLine(pl.right,p2.left)){returntrue;}〃檢測(cè)上下//y上pa二a;pb=b;if((pl.up.y>=0)&&(pl.up.y<=10))for(y=0;y〈=pl.up.y;y++)(pa.y=y;pb.y=y;if(CheckLine(pa,pl.up)&&CheckLine(pb,p2.up)&&CheckLine(pa,pb)) {returntrue;})//y下
pa=a;pb=b;if((pl.down,y>=0)&&(pl.down,y<=10))for(y=pl.down.y;y<=10;y++)(pa.y=y;pb.y=y;if(CheckLine(pa,pl.down)&&CheckLine(pb,p2.down)&&CheckLine(pa,pb)) {returntrue;}〃檢測(cè)左右因?yàn)閥軸相等,所以不存在左右路徑}else〃縱向一條線x坐標(biāo)相同if(a.x==b.x)(〃x下上相鄰不if((pl.down.y==p2.p.y)||(pl.up.y==p2.p.y)){returntrue;}〃檢測(cè)這條線是否有一條路徑相通if(CheckLine(pl.down,p2.up)) {returntrue;}〃檢測(cè)上下國(guó)為x軸相等所以不存在路徑〃檢測(cè)左右〃*左pa=a;pb=b;for(x=0;x<=pl.left,x;x++)(pa.x=x;pb.x=x;if(CheckLine(pa,pl.left)&&CheckLine(pb,p2.left)&&CheckLine(pa,pb)) {returntrue;}}〃x右pa=a;pb=b;for(x=pl.right.x;x<=18;x++)(pa.x=x;pb.x=x;if(CheckLine(pa,pl.right)&&CheckLine(pb,p2.right)&&CheckLine(pa,pb)) {returntrue;})}else//xy坐標(biāo)都不相同{{{{{{pa=a;pb=b;
if(a.x>b.x){ //p2點(diǎn)在左left////////////////xxxxxxxxxxxxxxxxx找x軸路徑
for(x=0;x<=p2.left.x;x++)pa.x=x;pb.x=x;if(CheckLine(pa,pl.left)&&CheckLine(pa,pb)&&CheckLine(pb,p2.left)){returntrue;}}//endforfor(x=p2.right,x;x<=pl.left.x;x++)(pa.x=x;pb.x=x;if(CheckLine(p2.right,pb)&&CheckLine(pa,pb)&&CheckLine(pa,pl.left)){returntrue;})for(x二p2?right.x;x<=18;x++)(pa.x=x;pb.x=x;if(CheckLine(pl.right,pa)&&CheckLine(p2.right,pb)&&CheckLine(pa,pb)) {returntrue;}}/////////////////yyyyyyyyyyyyyyyyyyyy找y軸路徑由于是從上向下搜索所以pl.y>p2.yCheckLine(pb,p2.up))pa.x=a.x;pb.x=b.x;〃初始化坐標(biāo)yllll漸變for(y=0:y<=pl.up.y;y++) //I段{pa.y=y;pb.y=y;if(CheckLine(pb,pa)&&CheckLine(pa,pl.up)&&{returntrue;})////////////////////////for(y=pl.down,y;y〈=p2.up.y;y++)〃2段pa.y=y;pb.y=y;if(CheckLine(pb,pa)&&CheckLine(pl.down,pa)&&CheckLine(pb,p2.up)) {returntrue;})///////////////////////for(y=p2.down,y;y<=10;y++)〃3段(///////////////////////////////pa.y=y;pb.y=y;if(CheckLine(pb,pa)&&CheckLine(pl.down,pa)&&CheckLine(p2.down,pb)){returntrue; })}else〃〃〃〃〃〃p2點(diǎn)在右righta.x>b.x(pa.y=a.y;pb.y=b.y;〃初始化坐標(biāo)for(x=0;x<=pl.left,x;x++);(pa.x=x;pb.x=x;if(CheckLine(pa,pb)&&CheckLine(pa,pl.left)&&CheckLine(pb,p2.left)) {returntrue;})/////////////////////for(x=pl.right,x;x<=p2.left.x;x++)(pa.x=x;pb.x=x;if(CheckLine(pa,pb)&&CheckLine(pl.right,pa)&&CheckLine(pb,p2.left)){returntrue;
///////////////////////for(x=p2.right,x;x<=18;x++)(pa.x=0;pb.x=x;if(CheckLine(pa,pb)&&CheckLine(pl.right,pa)&&CheckLine(p2.right,pb)){returntrue;}}Illi////////IlliIII////yyyyyyyyyyyyyyyyyy y軸漸變pa.x=a.x;pb.x=b.x;〃初始化坐標(biāo)if((pl.up.y>=0)&&(pl.up.y<=10))(for(y=0;y<=pl.up.y;y++) //I段{pa.y=y;pb.y-y;if(CheckLine(pa,pb)&&CheckLine(pa,pl.up)&&CheckLine(pb,p2.up)) {returntrue;}})//////pa.x-a.x;pb.x=b.x;〃初始化坐標(biāo)if((pl.down.y<=10)&&(p2.up.y〉=0)){for(y=pl.down,y;y<=p2.up.y;y++)〃2段(pa.y=y;pb.y=y;if(CheckLine(pa,pb)&&CheckLine(pl.down,pa)))&&CheckLine(pb,p2.up)) {returntrue;)////pa.x=a.x;pb.x=b.x;//初始化坐標(biāo)if(p2.down,y<=10)(for(y=p2.down,y;y<=10;y++)〃3段{pa.y=y;pb.y=y;if(CheckLine(pa,pb)&&CheckLine(pl.down,pa)&&CheckLine(p2.down,pb)){returntrue;}//xy坐標(biāo)都不相同}}}}}}}}}returnfalse;這節(jié)課的代碼實(shí)在太長(zhǎng)了,老師也是先自己寫(xiě)好了再發(fā)出來(lái)的,他說(shuō)如果在教程中寫(xiě)代碼的話起碼要1個(gè)小時(shí).添加一個(gè)按鈕兩個(gè)編輯框,將代碼來(lái)測(cè)試一下,先單消一次看看,好像已經(jīng)找到能夠消除的棋子了,但是還沒(méi)有實(shí)現(xiàn)自動(dòng)點(diǎn)擊,下節(jié)課繼續(xù)……這節(jié)課太難懂了,本來(lái)還想通過(guò)課程學(xué)學(xué)VC代碼,但是感覺(jué)更暈了.今天我們要一起學(xué)習(xí)的是L3.6教學(xué)目標(biāo):1.3.6Click2P函數(shù)實(shí)現(xiàn),單消棋子功能實(shí)現(xiàn)a、完成Click2P函數(shù)b、單消一對(duì)棋子的實(shí)現(xiàn)c、修改ClearPair函數(shù)棋盤(pán)第一格坐標(biāo)x=21,y=19231*35棋子寬度,高度SendMessage(hwnd,WMLBUTTONDOWN,0,(y<<16)+x+31*2);//SendMessage(hwnd,WM_LBUTTONUP,0,(y?16)+x);//boolClick2p(POINTpl,POINTp2)(〃點(diǎn)擊plHWNDhwnd=FindWindow(NULL,gameCaption);int1param;lparam=((pl.y*35+192)?16)+(pl.x*31+21);SendMessage(hwnd,WMLBUTTONDOWN,0,1param);//SendMessage(hwnd,WMLBUTTONUP,0,Iparam);////點(diǎn)擊p2lparam=((p2.y*35+192)?16)+(p2.x*31+21);SendMessage(hwnd,WM_LBUTTONDOWN,0,Iparam);//SendMessage(hwnd,WMLBUTTONUP,0,Iparam);//returntrue;//////////////////////前面的代碼只是分析出可消除的棋子,并沒(méi)有實(shí)現(xiàn)真正消除,所以本節(jié)課將模擬鼠標(biāo)點(diǎn)擊,發(fā)送鼠標(biāo)信息來(lái)實(shí)現(xiàn)自動(dòng)消除棋子boolClick2p(POINTpl,POINTp2)〃點(diǎn)擊兩點(diǎn)函數(shù)(〃點(diǎn)擊plHWNDhwnd=FindWindow(NULL,gameCaption);〃查找游戲窗IIintIparam;〃定義參數(shù)〃192是棋盤(pán)距離窗口上面的距離,21是棋盤(pán)距離左邊的距離lparam=((pl.y*35+192)?16)+(pl.x*31+21);〃通過(guò)棋子格子計(jì)算位置SendMessage(hwnd,WM_LBUTTONDOWN,0,Iparam);〃鼠標(biāo)按卜SendMessage(hwnd,WMLBUTTONUP,0,Iparam);〃鼠標(biāo)抬起〃點(diǎn)擊p2lparam=((p2.y*35+192)?16)+(p2.x*31+21);〃計(jì)算配對(duì)棋子位置SendMessage(hwnd,WMLBUTTONDOWN,0,Iparam);//SendMessage(hwnd,WMLBUTTONUP,0,Iparam);//returntrue;代碼添加完之后掛上游戲測(cè)試了一下,發(fā)現(xiàn)開(kāi)始可以消除棋子,后面就不動(dòng)了,再繼續(xù)查找代碼,分析哪里出錯(cuò).將boolCLlkwgDlg::ClearPiar()函數(shù)的for(xl=xl;xl<19;xl++)改為for(xl=0;xl<19;xl++)〃不要限制其格子數(shù)還要將for(x2=x1;x2<19;x2++)改成for(x2=0;x2<19;x2++)
這回可以消除所有棋子了這節(jié)課才14分鐘,代碼寫(xiě)的比較少,相比上節(jié)的代碼簡(jiǎn)單太多了,很容易理解,老師上節(jié)的代碼也沒(méi)仔細(xì)講解一下有空給講講,嘿嘿.看看后面有沒(méi)有講,如果沒(méi)講我就讓他其實(shí)記筆記主要是記課程當(dāng)中都講了什么內(nèi)容,以便以后查閱起來(lái)方便.今天我們要一起學(xué)習(xí)的是L3.7教學(xué)目標(biāo):1.3.7掛機(jī)/秒殺/a、b、c、自動(dòng)開(kāi)局掛機(jī)卜.棋秒殺UINTSetTimer(HWNDhWnd,UINTnIDEvent,UINTuElapse,TIMERPROCIpTimerFunc);////////師上節(jié)的代碼也沒(méi)仔細(xì)講解一下有空給講講,嘿嘿.看看后面有沒(méi)有講,如果沒(méi)講我就讓他其實(shí)記筆記主要是記課程當(dāng)中都講了什么內(nèi)容,以便以后查閱起來(lái)方便.今天我們要一起學(xué)習(xí)的是L3.7教學(xué)目標(biāo):1.3.7掛機(jī)/秒殺/a、b、c、自動(dòng)開(kāi)局掛機(jī)卜.棋秒殺UINTSetTimer(HWNDhWnd,UINTnIDEvent,UINTuElapse,TIMERPROCIpTimerFunc);////////指向窗口句柄時(shí)鐘標(biāo)識(shí)時(shí)間間隔(毫秒)指向回調(diào)函數(shù)的地址KillTimer(UINTnIDEvent);//時(shí)鐘標(biāo)識(shí)VOIDCALLBACKplayproc(HWNDhwnd,UINTuMsg,UINTidEvent,DWORDdwTime////////handleofwindowfortimermessagesWM_TIMERmessagetimeridentifiercurrentsystemtimeClearPiar();VOIDCALLBACKstrartproc(HWNDhwnd,UINTuMsg,UINTidEvent,DWORDdwTime)////////handleofwindowfortimermessagesWMTIMERmessagetimeridentifiercurrentsystemtimestartGame();)〃自動(dòng)開(kāi)局constPLAYID=111;constSTARTID=112;voidCLlkwgDlg::OnCheckl()(//TODO:AddyourcontrolnotificationhandlercodehereUpdateData(true);〃更新窗口內(nèi)容至變量if(mautoplay){SetTimer(PLAYID,1500,&playproc);}else(KillTimer(PLAYID);voidCLlkwgDlg::0nCheck2()(//TODO:AddyourcontrolnotificationhandlercodehereUpdateData(true);〃更新窗口內(nèi)容至變量if(mautoplay){SetTimer(STARTID,3*1000,&strartproc);}else(KillTimer(STARTID);〃〃〃〃〃〃〃上面都是教案中的內(nèi)容,下面是我記錄的內(nèi)容〃〃〃〃/在窗口上添加一個(gè)復(fù)選框CheckBox,設(shè)置為自動(dòng)開(kāi)局,再關(guān)聯(lián)兩個(gè)變量Mautoplay/Mautostart%了運(yùn)用這兩個(gè)屋量在函數(shù)中,又重新調(diào)整了一下頭Uk_wgDlg.cpp中的函數(shù),都是在定義全局變量/標(biāo)識(shí)符一類(lèi)的代碼調(diào)整,對(duì)我這個(gè)沒(méi)看VC++基礎(chǔ)的人來(lái)弗有點(diǎn)看不懂.這是添加復(fù)選框后的界面
- □自動(dòng)掛機(jī)口自動(dòng)開(kāi)局在“自動(dòng)掛機(jī)”和“自動(dòng)開(kāi)局”中添加如下代碼constPLAYID=111;〃定義一個(gè)數(shù)值方便調(diào)用,不要重復(fù)constSTARTID=112;〃可以隨便取數(shù),不要重復(fù)voidCLlk_wgDlg::0nCheckl()〃如果復(fù)選框被選中則執(zhí)行(//TODO:AddyourcontrolnotificationhandlercodehereUpdateData(true);〃更新窗口內(nèi)容至變量if(m_autop1ay)〃如果變量被設(shè)置則運(yùn)行{SetTimer(PLAYID,1500,&playproc);//自動(dòng)掛機(jī)}else(KillTimer(PLAYID);〃關(guān)掉定時(shí)器,不執(zhí)行回調(diào)函數(shù)voidCLlk_wgDlg::0nCheck2()(//TODO:AddyourcontrolnotificationhandlercodehereUpdateData(true);//更新窗口內(nèi)容至變量if(m_autoplay)〃如果變量被設(shè)置則運(yùn)行SetTimer(STARTID,3*1000,&strartproc);//自動(dòng)開(kāi)局
}else〃如果沒(méi)有被選中的話KillTimer(STARTID);代碼我做了比較多的注釋,基本上像我這樣的新手都能理解了.我發(fā)現(xiàn)VC++與DELPHI在編寫(xiě)代碼上確實(shí)存在很多不同之處,比如在時(shí)間的設(shè)置上,DELPHI中是加入時(shí)間控件,而VC++中卻是添加了一個(gè)函數(shù)SetTimer,感覺(jué)有點(diǎn)不太習(xí)慣,但人家說(shuō)了,VC++是專(zhuān)業(yè)人員用的,這就代表著專(zhuān)業(yè)唄今天我們要一起學(xué)習(xí)的是L3.8游戲外掛界面美化a、添加進(jìn)度條b、界面調(diào)整BOOLMoveWindow(F1WNDhWnd,intX,intY,intnWidth,intnHeight,BOOLbRepaintc、BOOLMoveWindow(F1WNDhWnd,intX,intY,intnWidth,intnHeight,BOOLbRepaint//窗口句柄//水平坐標(biāo)X//垂直坐標(biāo)Y//寬度//高度//是否重畫(huà)窗口true,false//::MoveWindow(this->m_hWnd,0,0,330,200,true);MoveWindow(0,0,330,200,true);滑塊(slider)voidSetTicFreq(intnFreq);intGetPos()const;voidSetRange(intnMin,intnMax,BOOLbRedraw=FALSE);MoveWindow(0,0,330,200,true);this->m_ctl_slider.SetRange(50,3000);//設(shè)置滑塊的最小值最大值this->m_ctl_slider.SetTicFreq(150);〃分隔線寬度this->m_ctl_slider.SetPos(lOOO);〃滑塊位置this->m_ctl_check.SetCheck(true);〃選中復(fù)選框//////////////////////////////這節(jié)課是要界面美化,因?yàn)榍捌诘暮诵拇a已經(jīng)編寫(xiě)了.更改界面,要?jiǎng)h除一些不用的控件,因?yàn)榭丶c代碼是關(guān)聯(lián)的,所以一個(gè)懶辦法就是將不用的控件移到窗口外面,這樣就看不到了.如果對(duì)窗口的調(diào)整還不滿意,就用編程來(lái)實(shí)現(xiàn),因?yàn)橛么a設(shè)置窗口及控件大小最精確了.注意MoveWindow函數(shù),如果是全局使用則是6個(gè)參數(shù),局部使用就是5個(gè)參數(shù)再給滑塊條設(shè)置一下分隔線:建立控件變量m_ctl_slider,然后查看一下該變量的定義,用于參考代碼寫(xiě)法,這幾個(gè)就是滑塊的類(lèi)成員函數(shù)滑塊(slider)voidSetTicFreq(intnFreq);intGetPos()const;voidSetRange(intnMin,intnMax,BOOLbRedraw=FALSE);設(shè)置好手放在窗口的初始化處,也就是Uk_wgDlg.cpp里的BOOLCLlkwgDlg::OnInitDialog()函數(shù)這樣在啟訪時(shí)就會(huì)設(shè)置好控件樣式在MoveWindow(0,0,330,200,true);下面添加代碼this->mctlslider.SetRange(50,3000);〃設(shè)置滑塊的最小值最大值this->m_ctl_slider.SetTicFreq(150);〃分隔線寬度this->m_ctl_slider.SetPos(lOOO); //滑塊位置用編輯框測(cè)試一下滑塊,調(diào)整好樣式.再設(shè)置一下”掛機(jī)速度調(diào)節(jié)”復(fù)選框來(lái)開(kāi)啟/關(guān)閉滑塊功能這個(gè)需要先建立一個(gè)BOOL類(lèi)型的變量m_sliderenable來(lái)進(jìn)行控制,添加代碼如下voidCLlkwgDlg::0nCheck3()(//TODO:AddyourcontrolnotificationhandlercodehereUpdateData(true);::EnableWindow(m_ctlslider.mhWnd,msliderenable);〃通過(guò)這個(gè)復(fù)選框來(lái)控制滑塊條是否可用)還要設(shè)置這個(gè)掛機(jī)速度調(diào)節(jié)初始默認(rèn)為開(kāi)啟,還需要在該控件中建立一個(gè)變量m_ctl_check最終的代碼設(shè)置如下在MoveWindow(0,0,330,200,true);下面添加代碼this->m_ctl_slider.SetRange(50,3000);〃設(shè)置滑塊的最小值最大值this->m_ctl_slider.SetTicFreq(150); //分隔線寬度this->m_ctl_slider.SetPos(lOOO);〃滑塊位置this->m_ctl_check.SetCheck(true);〃選中復(fù)選框設(shè)置的代碼都在上面的教案里.感覺(jué)VC++的MFC不如DELPHI的窗體/控件用著方便,而且是非常的麻煩,當(dāng)然也有的人用BCB,可能也是這個(gè)原因.今天我們要一起學(xué)習(xí)的是L3.9倒計(jì)時(shí)與棋子數(shù)(基址查找)a、杳找棋子數(shù)〃為了優(yōu)化自動(dòng)開(kāi)局b、查找倒計(jì)時(shí)〃這個(gè)倒計(jì)時(shí)有點(diǎn)討厭,去掉它c(diǎn)、開(kāi)局的標(biāo)志:1,棋子數(shù):$001166E0IByte,變更棋子數(shù):掃描類(lèi)型:精確數(shù)值2、倒計(jì)時(shí)基址:$00118088查找0t=t-n;//3000-10;1、棋子數(shù):$001166E0〃沒(méi)開(kāi)局之前0,開(kāi)局之后大于02、倒計(jì)時(shí)基址:$00118088〃毫秒3、開(kāi)局的標(biāo)志:01C3A7B4,01C4EF74,01C61F9C,01C84CF4//boolean///////////////////////////前面的代碼雖然可以自動(dòng)下棋了,但是有關(guān)于自動(dòng)開(kāi)局這里還不智能,所以要增加一個(gè)棋子數(shù)的判斷,當(dāng)棋子為空時(shí)就要點(diǎn)擊''開(kāi)始”按鈕,多找?guī)状尉驼业搅耸S嗥遄訑?shù)的地址.同時(shí)為了豐富功能,還要查找倒計(jì)時(shí)功能,將倒計(jì)時(shí)去掉.而倒計(jì)時(shí)是個(gè)進(jìn)度條,沒(méi)有確切的數(shù)值,所以我們只好猜測(cè),假設(shè)未開(kāi)局時(shí)是0,如果剛一開(kāi)始的時(shí)候估計(jì)其值可能會(huì)大于100,然后再查找不斷減少的數(shù)值,最后走完就是0,注意這個(gè)值是4字節(jié)的.找到了這兩個(gè)數(shù)值我們?nèi)绾巫瞿?可以將倒計(jì)時(shí)的數(shù)值鎖定,或者將
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 工程公司財(cái)務(wù)制度
- 咸寧彩色混凝土施工方案
- 磚砌污水井施工方案
- 砼護(hù)欄施工方案
- 南山車(chē)庫(kù)防水施工方案
- 廣西噴泉維修施工方案
- 6mm 650nm 5mw 紅光點(diǎn)狀激光 pd腳作用
- 5年級(jí)下冊(cè)人教版英語(yǔ)詞語(yǔ)表
- 5年級(jí)白鷺第二自然段改寫(xiě)成一段說(shuō)明文
- 橋梁端頭封堵施工方案
- 少兒美術(shù)繪本教案課件-3-6歲 《100層巴士》
- 鋼筋原材質(zhì)量證明書(shū)
- WH/T 42-2011演出場(chǎng)所安全技術(shù)要求第2部分:臨時(shí)搭建演出場(chǎng)所舞臺(tái)、看臺(tái)安全技術(shù)要求
- GB/T 5023.5-2008額定電壓450/750 V及以下聚氯乙烯絕緣電纜第5部分:軟電纜(軟線)
- GB/T 23445-2009聚合物水泥防水涂料
- 瓷貼面教學(xué)課件
- 尺骨冠突骨折課件
- 北師大版七年級(jí)下冊(cè)第一章整式的乘除計(jì)算題專(zhuān)項(xiàng)訓(xùn)練
- 2022年蘇州健雄職業(yè)技術(shù)學(xué)院?jiǎn)握锌荚嚸嬖囋囶}及答案解析
- 乳腺癌改良根治術(shù)
- 新版(七步法案例)PFMEA
評(píng)論
0/150
提交評(píng)論