Python如何实现简单DNF脚本
文章目錄
- 效果
- 代碼過(guò)程
- 前言
- 使用環(huán)境
- 實(shí)現(xiàn)
- 鍵盤(pán)模擬
- 圖像分析
- 屏幕快照
- 相對(duì)位置移動(dòng)
效果
GIF大小限制沒(méi)錄太多,過(guò)程中加入了操作延遲*2來(lái)保障穩(wěn)定
(判斷速度過(guò)快會(huì)導(dǎo)致當(dāng)前位置判斷出錯(cuò)導(dǎo)致走過(guò)頭,細(xì)節(jié)沒(méi)有去做判斷,就直接雙倍延遲處理了)
代碼過(guò)程
1.每隔0.1-0.2秒獲取一次窗口句柄截圖 掃描后得到人物坐標(biāo)X1,Y1及左上角開(kāi)始的第一個(gè)物品的坐標(biāo)X2,Y2;
優(yōu)先級(jí)(錢(qián)>道具>裝備)
2.判斷坐標(biāo)差計(jì)算出大致按鍵時(shí)間
1)if(兩者距離像素>5) 跳轉(zhuǎn)回第一步繼續(xù)獲取坐標(biāo)
2)if(兩者距離像素>5) 跳轉(zhuǎn)至第三步
3.執(zhí)行模擬按鍵X進(jìn)行道具拾取,如果數(shù)據(jù)還存在,則偏移量-1或者+1重新進(jìn)行2(此步驟是防止某些物品的名稱(chēng)過(guò)長(zhǎng))
P:如果是要做自動(dòng)打怪的腳本的話(huà),可以先對(duì)怪進(jìn)行貼圖處理,然后獲取人與怪的坐標(biāo),對(duì)每個(gè)技能維護(hù)一個(gè)按鍵->(范圍x,范圍y,冷卻時(shí)間)的key->map對(duì)象
判斷怪在范圍內(nèi)就按技能打怪,沒(méi)怪就執(zhí)行撿道具,沒(méi)道具就執(zhí)行過(guò)圖
emmmm,應(yīng)該可以實(shí)現(xiàn)全自動(dòng)…吧?
此處就不多做討論了哈,這個(gè)只是一時(shí)興起,以游戲?yàn)槔龑?shí)現(xiàn)這一類(lèi)的思路。
前言
在此聲明,本博客僅作學(xué)習(xí)交流使用,不可用于任何商業(yè)途徑與任何違法途徑。如有侵權(quán),請(qǐng)聯(lián)系刪除。
本博客只是從一個(gè)實(shí)現(xiàn)思路聊聊,而不會(huì)整體的貼代碼,所以想要完整腳本的請(qǐng)右轉(zhuǎn),想要不勞而獲的請(qǐng)右轉(zhuǎn),想要借此謀利的請(qǐng)右轉(zhuǎn),不要浪費(fèi)您寶貴的時(shí)間在我無(wú)聊的博客上面。
從小到大我就很喜歡玩游戲,所以閑下來(lái)也就想能不能用編程來(lái)做一點(diǎn)輔助程序?于是就網(wǎng)上一點(diǎn)點(diǎn)摸索資料去一步步實(shí)現(xiàn)。
做這樣一個(gè)簡(jiǎn)單的Demo腳本只是因?yàn)樯鹆艘稽c(diǎn)點(diǎn)興趣,想通過(guò)編程切切實(shí)實(shí)地做一些有幫助的東西,順便也能增長(zhǎng)一些技術(shù),興趣使人進(jìn)步。
使用環(huán)境
語(yǔ)言:Python
用到的包:PIL、Win32、WinIO
環(huán)境:WinIO只能模擬PS/2鍵盤(pán),就是最早的那種圓口接口的鍵盤(pán),筆記本一般是PS/2,臺(tái)式外接的我看過(guò)了我自己的電腦沒(méi)有PS/2的接口所以做不了。
實(shí)現(xiàn)
鍵盤(pán)模擬
第一層想到的要能到操作游戲的層面肯定是要模擬鼠標(biāo)鍵盤(pán)的輸入了。一開(kāi)始用java調(diào)用JNA來(lái)使用一些winapi來(lái)進(jìn)行模擬,在游戲外能完美實(shí)現(xiàn)鍵盤(pán)的操作,但是游戲內(nèi)部通常采用了一些機(jī)制來(lái)防止這些虛擬按鍵的生效,于是在查閱了許多資料后找到了WinIO的方式來(lái)進(jìn)行驅(qū)動(dòng)級(jí)的按鍵模擬。
一開(kāi)始用java模擬WinIO并不順利,java在腳本以及一些底層方法的調(diào)用上總是存在問(wèn)題,比如Use32獲取句柄能獲取到一般的窗口但是獲取不到DNF的界面句柄,又比如在使用WinIO的API時(shí)鍵盤(pán)模擬總是會(huì)丟失或者延遲,百度查詢(xún)未果,可能是緩存數(shù)據(jù)丟失或者沖突。
重復(fù)輸入abcdefg結(jié)果如下
棄用Java轉(zhuǎn)用Python后句柄能正常獲取并且鍵盤(pán)模擬沒(méi)有出現(xiàn)過(guò)任何丟失情況,Python中的包為rabird.winio可查閱資料。
WinIO驅(qū)動(dòng)級(jí)模擬是給驅(qū)動(dòng)發(fā)送指令,主要是兩個(gè)端口,
KBC_KEY_CMD=0x64命令端口
KBC_KEY_DATA=0x60數(shù)據(jù)端口
完整的按鍵模擬方法包引用自網(wǎng)絡(luò),以下為發(fā)送鍵盤(pán)按下的一段。
scancode為鍵盤(pán)掃描碼。
參考自
https://blog.csdn.net/qq_37232329/article/details/79926440
圖像分析
當(dāng)成功通過(guò)程序完成鍵盤(pán)模擬后我就知道我可以用編程來(lái)實(shí)現(xiàn)一些簡(jiǎn)單的東西了,那如果要實(shí)現(xiàn)它的自動(dòng)化就需要獲取一些數(shù)據(jù)進(jìn)行分析,比如人物和怪物的坐標(biāo)位置,掉落道具的坐標(biāo)位置,最直觀的方式當(dāng)然是讀取內(nèi)存獲取,我也沒(méi)傻乎乎的去讀一個(gè)游戲的內(nèi)存獲取修改免得封號(hào),不如采取一些取巧的方式比如說(shuō)大圖找小圖?
查閱了大量的資料,通過(guò)相似度等方式比較兩張大小像素都不相同的圖片似乎都不可取,我又想到了能不能通過(guò)文字識(shí)別的方式,把人物的貼圖換成一個(gè)字,以識(shí)別字的方式來(lái)讀取文字的坐標(biāo),當(dāng)真正做了之后發(fā)現(xiàn),雪崩般的效率加馬賽克般的識(shí)別率!
于是手寫(xiě)了一個(gè)大圖中找小圖的Demo,其實(shí)就是強(qiáng)行比較像素點(diǎn),當(dāng)找到小圖左上角第一個(gè)相同的像素點(diǎn)時(shí)進(jìn)行一輪四個(gè)角的比較,再取中間N個(gè)隨機(jī)點(diǎn)進(jìn)行比較,如果匹配度有90以上則記錄坐標(biāo),簡(jiǎn)單的測(cè)試了一下發(fā)現(xiàn)效率還可以,從屏幕快照中尋找一個(gè)小截圖,成功率基本是100%并且時(shí)間也只耗費(fèi)0.5秒就能記錄下坐標(biāo)。
關(guān)鍵性的問(wèn)題馬上就出現(xiàn)了,DNF的圖像,只要你一動(dòng),圖片肉眼看上去長(zhǎng)的是一樣的,但是!!!!他的內(nèi)部像素點(diǎn)就出現(xiàn)了一些波動(dòng),比如同樣是金色,但是RGB在某一個(gè)范圍內(nèi)都是金色…大圖找小圖來(lái)定位坐標(biāo)的想法破滅。
于是直接就改用了大圖找某一像素的方式,一張圖內(nèi)如果出現(xiàn)某一個(gè)像素就直接定位該坐標(biāo),而這個(gè)像素,可以通過(guò)補(bǔ)丁插件強(qiáng)行用畫(huà)圖軟件點(diǎn)一個(gè)點(diǎn)上去,圖像分析是可以定位出像素點(diǎn)的。
屏幕快照
于是制約效率的方式馬上就暴露在了屏幕快照上,如果你電腦3秒鐘截圖一次,那還做什么個(gè)腳本呢?正巧Python有一個(gè)window的API能在0.2秒左右完成界面的截圖,而我需要的只是DNF的界面,這個(gè)時(shí)間就壓縮到了0.05-0.1秒。
快速截圖方式如下
在0.05-0.1秒內(nèi)獲取到圖片后就可以通過(guò)圖片分析找到像素并定位直接返回,也不需要對(duì)整張圖片的像素進(jìn)行分析,于是坐標(biāo)獲取就是0.2秒一次
相對(duì)位置移動(dòng)
按這種獲取坐標(biāo)的方式效率,完全可以采取循環(huán)來(lái)一直獲取坐標(biāo)
根據(jù)獲取到的人物位置與相對(duì)位置來(lái)進(jìn)行按鍵模擬并執(zhí)行打怪或拾取的動(dòng)作,直到地圖上沒(méi)有怪物及道具的坐標(biāo)循環(huán)結(jié)束,過(guò)多的代碼我就不貼了,完結(jié)。
總結(jié)
以上是生活随笔為你收集整理的Python如何实现简单DNF脚本的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: mac使用Alfred搜索外接移动硬盘失
- 下一篇: vijos1942——小岛 Floye