大家都知道騰訊作為目前市場上最大的游戲市場巨頭,所以騰訊代理的以及開發的游戲是多不勝數,同時騰訊針對游戲外掛的打擊力度也是非常強大的,但是在騰訊如此之大的打擊力度下各類游戲外掛依舊滔滔不絕,其中外掛最為猖狂的要數騰訊的幾款大型網絡游戲了,dnf,cf,和平精英相信每一個人基本上都玩過 也都遇到過各種外掛,今天小二帶大家了解下dnf腳本外掛飛機的各個品類及成本以及騰訊為什么不能徹底打掉這個龐大的游戲外掛市場。
?dnf玩家使用外掛無非就是升級搬磚和打團本,以前是分為全自動和半自動用法國的玩家應該都知道半自動有無視隊友功能可以打團本,但是近期無視隊友功能被全網和諧,所以現在市場上的外掛腳本可以分為三類 ,全自動半自動和團本專用了。
?大家為什么那么喜歡用外掛這個應該不需要我細說基本都是奔著倍攻和自動以及pk,拿旭旭寶寶來說,寶哥的游戲賬號打造花了不止一千萬,但是你用外掛幾塊錢就可以擊敗寶哥,只是會伴隨著一定幾率的封號可能,還有就是搬磚,人家手動辛辛苦苦半小時刷完一個賬號,用腳本的一路秒秒秒看著電影抽著煙比你手動刷的還快,所以大家對外掛情有獨鐘,市場有需求就有人接著做這個行業,所以騰訊也是怎么打擊都打擊不掉這個外掛市場。
另外還有一個大家都不陌生的群體游戲工作室,相比于普通玩家來說工作室對dnf這款游戲影響特別大,因為工作室最小都是16臺電腦大的有幾百幾千臺,使用上全自動腳本連換號都不需要每天那么多電腦自動搬磚對游戲金幣的交易比例造成了很大影響,最近幾年底端電腦價格一落千丈一臺工作室電腦只需要兩三百,導致很多人進入這個工作室行業。
另外給大家介紹下腳本的成本及大概價格,腳本基本分為端口腳本和內部腳本,端口類型的都是零成本無限制卡只要搞個端口就可以無限制卡,內部類型的就是用制卡器紙卡出一張卡和開發結算多少多少錢,市場上所有腳本周卡價格只要是超過20就說明你拿到的是經過好幾手的,今天先給大家介紹到這里還需要了解什么請評論區留言哦
最近刷了一段時間提燈與地下城這個游戲,太肝了,毛都干沒了,于是想制作一個替我刷圖的腳本,說干就干,總結下思路。
總思路是 識別當前地圖 --> 與地圖中可以交互的點交互 --->識別當前地圖。
當然這種是比較簡單的思路,后期可以拓展。
準備
思路是使用opencv識別人物,道具和怪物等元素,但是考慮到怪物種類不一而足,素材收集也非一日之功,于是轉換思路,從小地圖入手,小地圖的圖標是種類固定的,像這樣:
buff
怪物
出口
青蛙
寶石
金幣
這里注意,采集到的圖標需要和手機或者模擬器的圖標一一對應。小地圖的圖片可以通過adb screencap命令獲取或者minicap也是可以的。
首先觀察小地圖的長框可以發現是275 x 275,進一步觀察可以發現分為11*11的格子,然而上面兩格比較容易匹配出錯,所以我們可以用一個11x9的整數數組來表示地圖分布:
地圖等分
func GetDevidedCentralPoint(piecesX ,piecesY int,src gocv.Mat)[][]int{
//formed up a vector of (11-2)*11
//use line to devide the map picture into 9x11 pieces
width:=src.Cols()
height:=src.Rows()
lgr.Debug("width:%v height:%v",width,height)
WPP:=width/piecesY
HPP:=height/piecesX
res:=make([][]int,piecesX)
green := color.RGBA{0, 255, 0, 0}
for i:=0;i<piecesX;i++{
resInY:=make([]int,piecesY)
for j:=0;j<piecesY;j++{
Img,err:=src.ToImage()
if err!=nil{
lgr.Debug("Transform to image failed,err:",err)
}else{
colour:=Img.At(WPP*j+WPP/2,HPP*i+HPP/2)
pt:=image.Point{WPP*j+WPP/2,HPP*i+HPP/2}
str:=fmt.Sprintf("%v",j)
gocv.PutText(&src,str,pt,gocv.FontHersheySimplex,0.5,green,1)
r,g,b,_:=colour.RGBA()
if (uint8(r)>20 && uint8(g)>20 && uint8(b)>20){
//lgr.Debug("current point(%v,[%d,%v,%v]) color is : %v",pt,uint8(r),uint8(g),uint8(b),colour)
//gocv.Circle(&src,pt,2,green,1)
resInY[j]=1
}else{
resInY[j]=0
}
}
}
res[i]=resInY
}
return res
}
然后再分別匹配上面收集的圖標,匹配到就將地圖數組中對應的位置改為相應的數字,定義如下:
/*-1 for store, 0 for unknow status, 1 for path, 2 for hero,3 for exit,4 for gold,5 for pet ,6 for enermys ,7 for iron box,8 for red box,9 for buff , 13 for frog,-2 for goldbox,-3 for temple, */
const heroImg= "./asset/hero.jpg"
const enermyImg= "./asset/enermy.jpg"
const exitImg= "./asset/exit.jpg"
const goldImg= "./asset/gold.jpg"
const gemImg= "./asset/gem.jpg"
const redboxImg= "./asset/redbox.jpg"
const templeImg= "./asset/temple.jpg"
const IronboxImg= "./asset/Ironbox.jpg"
const buffImg= "./asset/buff.jpg"
const petImg= "./asset/pet.jpg"
const pet1Img= "./asset/pet1.jpg"
const pet2Img= "./asset/pet2.jpg"
const pet3Img= "./asset/pet3.jpg"
const frogImg= "./asset/frog.jpg"
const selectorImg= "./asset/selector.jpg"
const storeImg= "./asset/store.jpg"
const goldboxImg= "./asset/goldbox.jpg"
const canceImg= "./asset/cancel.jpg"
const piecesX=9
const piecesY=11
然后,將采集到的地圖元素與當前地圖一一匹配,使用的方法是之前提過的gocv.MatchTemplate()方法,然后使用gocv.MinMaxLoc()得到可信度和對應的坐標,代碼如下:
func MatchTarget(imgTempl,imgSrc ,imgSrc1 gocv.Mat,type_ int ,res [][]int){
result:=gocv.NewMat()
defer result.Close()
m :=gocv.NewMat()
blue := color.RGBA{0, 0, 255, 0}
gocv.MatchTemplate(imgTempl,imgSrc,&result,gocv.TmCcoeffNormed,m)
//gocv.MatchTemplate(imgTempl,imgSrc,&result,1,m)
m.Close()
minValue,maxConfidence,_,maxLoc :=gocv.MinMaxLoc(result)
if maxConfidence < 0.9 {
lgr.Debug("Max confidence of %f is too low. MatchTemplate could not find template in scene.", maxConfidence)
return
}
width:=imgSrc.Cols()
height:=imgSrc.Rows()
WPP:=width/piecesY
HPP:=height/piecesX
for {
//lgr.Debug("The most possible location is : %v,value is : %v",maxLoc,maxConfidence)
rect:=image.Rect(maxLoc.X,maxLoc.Y,maxLoc.X+imgTempl.Cols(),maxLoc.Y+imgTempl.Rows())
indx:=(maxLoc.X+imgTempl.Cols()/2)/WPP
indy:=(maxLoc.Y+imgTempl.Rows()/2)/HPP
pt:=image.Pt(indy,indx)
lgr.Debug("x:%v ,y:%v %v,type:%v",indy,indx,maxLoc,type_)
if type_==2{
HeroPosition=pt
}
res[indy][indx]=type_
if type_==3{
ExitPosition=pt
Dtm:=time.Since(starttime)
wtm:=time.Duration(10)*time.Minute
kc:=40
if killedCnt<kc&&Dtm<wtm&&!IsFirstFloor{
res[indy][indx]=0
}
}
if type_==-1{
IsFirstFloor=true
}
gocv.Rectangle(&imgSrc1, rect, blue, 1)
//lgr.Debug("outer result adress:%v",result)
maxLoc,maxConfidence=GetNextMaxLoc(result,maxLoc,minValue,imgTempl.Cols(),imgTempl.Rows())
if maxConfidence<0.9{
break
}
}
}
func GetNextMaxLoc(result gocv.Mat,maxLoc image.Point,minValue float32,templateW,templateH int)(image.Point,float32){
startX:=maxLoc.X-templateW
startY:=maxLoc.Y-templateH
endX :=maxLoc.X + templateW
endY :=maxLoc.Y + templateH
//lgr.Debug("Inner result adress:%v",result)
if startX<0 || startY <0 {
startX = 0
startY = 0
}
if endX >result.Cols()-1 || endY > result.Rows()-1{
endX=result.Cols()-1
endY=result.Rows()-1
}
for y:=startY;y<endY;y++{
for x:=startX;x<endX;x++{
//ret:=result.GetFloatAt(y,x)
//lgr.Debug("Get point (%v,%v) to %v",x,y,ret)
result.SetFloatAt(y,x,minValue)
//ret:=result.GetFloatAt(y,x)
//lgr.Debug("set point (%v,%v) to %v",x,y,ret)
}
}
_,maxConfidence,_,maxLoc :=gocv.MinMaxLoc(result)
lgr.Debug("the point %v is max confidence point %v",maxLoc,maxConfidence)
return maxLoc,maxConfidence
}
對每一個地圖元素,調用MatchTarget 方法來刷新當前地圖數組[][]rest,最后就得到了當前的地圖元素。
然后就是尋路的算法,我自己使用的是A*算法,大家有興趣的可以自己去實現一下.
最后附上腳本運行的錄屏。
播放
00:00
進入全屏
50
點擊按住可拖動視頻