某寶上吹的神乎其神的晶片壓槍簡直。。。,價格膨脹的看不下去。。。

其實原理很簡單的,無非就是飛易來配合自己寫的驅動來實現壓槍

另外什麼

自動識別

武器配件之類的,就是螢幕取色來判斷是裝備了什麼槍械

下面就由筆者帶大家揭秘一下具體原理

武器識別

筆者使用的是

Asprise-OCR

來實現武器名稱識別(取色也可以,只不過需要不同的取色點,要麻煩一些)

1。1 擷取指定位置圖片

Bitmap

image

=

new

Bitmap

globalParam

weapon0Location

“basicSize”

]。

X

globalParam

weapon0Location

“basicSize”

]。

Y

);

Bitmap

image1

=

new

Bitmap

globalParam

weapon1Location

“basicSize”

]。

X

globalParam

weapon1Location

“basicSize”

]。

Y

);

Graphics

imgGraphics

=

Graphics

FromImage

image

);

imgGraphics

CopyFromScreen

globalParam

weapon0Location

“basic”

],

new

Point

0

0

),

new

Size

image

Width

image

Height

));

1。2 裁剪圖片/反轉顏色

private

void

CutImage

Bitmap

source

string

imageName

{

int

width

=

globalParam

IdenWeaponImg

Width

//獲取圖片寬度

int

height

=

globalParam

IdenWeaponImg

Height

//獲取圖片高度

Bitmap

newmap

=

new

Bitmap

width

height

);

//儲存新圖片

int

x

=

globalParam

IdenWeaponPoint

X

int

y

=

globalParam

IdenWeaponPoint

Y

int

lengthX

=

x

+

width

int

lengthY

=

y

+

height

int

originX

=

0

int

originY

=

0

Color

pixel

//顏色匹對

for

int

i

=

x

i

<

lengthX

i

++)

{

for

int

j

=

y

j

<

lengthY

j

++)

{

pixel

=

source

GetPixel

i

j

);

//獲取舊圖片的顏色值(ARGB儲存方式)

int

r

g

b

a

r

=

pixel

R

g

=

pixel

G

b

=

pixel

B

//白色RGB(255,255,255),黑色(0,0,0)

//判斷是否屬於白色背景

if

r

==

255

&&

g

==

255

&&

b

==

255

{

//設定新圖片中指定畫素的顏色為黑色

newmap

SetPixel

originX

originY

Color

FromArgb

0

0

0

));

}

else

if

r

==

0

&&

g

==

0

&&

b

==

0

{

//設定新圖片中指定畫素的顏色為白色

newmap

SetPixel

originX

originY

Color

FromArgb

255

255

255

));

}

else

{

newmap

SetPixel

originX

originY

Color

FromArgb

255

-

r

255

-

g

255

-

b

));

}

originY

++;

}

originY

=

0

originX

++;

}

newmap

Save

imageName

);

}

1。3 呼叫OCR識別圖片中文字即武器名稱

private

string

GetOCR

string

imageName

{

string

s

=

Marshal

PtrToStringAnsi

OCR

GetOCR

imageName

-

1

));

LogHelper

ShowLog

“圖片識別結果 {0}”

s

);

return

Regex

Replace

s

@“\s”

“”

);

}

1。4 配件識別

private

Dictionary

<

string

string

>

QueryAccessories

Dictionary

<

string

Point

>

dic

Bitmap

image

{

Dictionary

<

string

string

>

result

=

new

Dictionary

<

string

string

>();

Point

basePoint

=

dic

“basic”

];

Point

baseSize

=

dic

“basicSize”

];

Point

points0

=

dic

“qiangkou”

];

Point

points1

=

dic

“woba”

];

Point

points2

=

dic

“danxia”

];

Point

points3

=

dic

“qiangtuo”

];

Point

points4

=

dic

“scope”

];

//設定截圖區域

string

colorHex4

=

GetImage

image

basePoint

points4

);

string

colorHex3

=

GetImage

image

basePoint

points3

);

string

colorHex2

=

GetImage

image

basePoint

points2

);

string

colorHex1

=

GetImage

image

basePoint

points1

);

string

colorHex0

=

GetImage

image

basePoint

points0

);

LogHelper

ShowLog

“Get Color: {0}, {1}, {2}, {3} {4}”

colorHex0

colorHex1

colorHex2

colorHex3

colorHex4

);

Dictionary

<

string

Dictionary

<

string

string

>>

dict

=

new

Dictionary

<

string

Dictionary

<

string

string

>>();

if

globalParam

ScreenHeight

==

1080

{

dict

=

colorDict

Pixel_1080

}

else

if

globalParam

ScreenHeight

==

1440

{

dict

=

colorDict

Pixel_1440

}

Dictionary

<

string

string

>

qiangkouDict

=

dict

“qiangkou”

];

qiangkouDict

TryGetValue

colorHex0

out

string

qiangkouValue

);

result

Add

“qiangkou”

qiangkouValue

!=

null

qiangkouValue

“槍口空”

);

Dictionary

<

string

string

>

woBauDict

=

dict

“woBa”

];

woBauDict

TryGetValue

colorHex1

out

string

woBaValue

);

result

Add

“woBa”

woBaValue

!=

null

woBaValue

“握把空”

);

Dictionary

<

string

string

>

magazineDict

=

dict

“magazine”

];

magazineDict

TryGetValue

colorHex2

out

string

magazineValue

);

result

Add

“magazine”

magazineValue

!=

null

magazineValue

“無”

);

Dictionary

<

string

string

>

qiangTuoDict

=

dict

“qiangTuo”

];

qiangTuoDict

TryGetValue

colorHex3

out

string

qiangTuoValue

);

result

Add

“qiangTuo”

qiangTuoValue

!=

null

qiangTuoValue

“槍托空”

);

Dictionary

<

string

string

>

scopeDict

=

dict

“scope”

];

scopeDict

TryGetValue

colorHex4

out

string

scopeValue

);

result

Add

“scope”

scopeValue

!=

null

scopeValue

“1倍鏡”

);

return

result

}

至此絕地求生揹包中裝備的武器配件識別完畢

接下來為了配合飛易來還需要壓槍資料以及壓槍演算法

2 壓槍邏輯

筆者經過大量測試最佳化後較穩定的壓槍邏輯

public

static

void

OpenFire

()

{

Player

player

=

Player

GetPlay

();

GunsViewModel

gunsViewModel

=

GunsViewModel

GetGunsViewModel

();

JichuViewModel

jichuViewModel

=

JichuViewModel

GetJichuViewModel

();

bool

_HasAmmo

=

true

GlobalParam

globalParam

=

GlobalParam

GetGlobalParam

();

MouseStatus

mouseStatus

=

MouseStatus

GetMouseStatus

();

AppInfo

appInfo

=

AppInfo

GetAppInfo

();

if

player

runLogic

&&

player

isShoot

&&

player

useMissiles

&&

string

IsNullOrEmpty

player

useWeapon

weapon

&&

player

useWeapon

weapon

Equals

“空”

))

{

string

[]

str

=

player

useWeapon

modelData

datas

Split

‘|’

);

double

[]

datas

=

Array

ConvertAll

str

double

Parse

);

int

x

=

0

y

=

0

int

count

=

int

datas

6

];

int

magNum

=

40

int

logicTime

=

int

datas

7

/

datas

6

-

1

);

Task

Run

(()

=>

{

ValiAmmo

ref

_HasAmmo

);

});

if

(!

player

runXueWuLogic

&&

jichuViewModel

XueWu

{

player

runXueWuLogic

=

true

Task

Run

(()

=>

{

ExecLogic

player

);

});

}

int

index

=

0

while

mouseStatus

leftDown

&&

_HasAmmo

&&

player

isShoot

{

DateTime

startTime

=

DateTime

Now

// 判斷是否沒有子彈

double

j

=

0

if

magNum

==

40

{

j

=

datas

0

];

index

=

0

}

else

if

magNum

<

40

&&

magNum

>=

34

{

j

=

datas

1

];

index

=

1

}

else

if

magNum

<

34

&&

magNum

>=

27

{

j

=

datas

2

];

index

=

2

}

else

if

magNum

<

27

&&

magNum

>=

19

{

j

=

datas

3

];

index

=

3

}

else

if

magNum

<

19

&&

magNum

>=

9

{

j

=

datas

4

];

index

=

4

}

else

{

j

=

datas

5

];

index

=

5

}

for

int

i

=

0

i

<

count

i

++)

{

if

_HasAmmo

&&

player

isShoot

{

YouyiSdk

M_MoveR2

globalParam

m_Handle

0

int

j

);

Task

Run

(()

=>

{

if

index

!=

globalParam

DataIndex

{

globalParam

DataIndex

=

index

gunsViewModel

RaisePropertyChanged

“Datas”

);

}

LogHelper

ShowLog

“壓槍耗時 {0} 壓槍幅度:{1} 步進:{2}”

0

j

i

);

});

Thread

Sleep

logicTime

);

}

}

magNum

-=

1

Task

Run

(()

=>

{

ValiAmmo

ref

_HasAmmo

);

Task

Run

(()

=>

{

ValiShoot

globalParam

player

);

});

});

}

}

}

以上就是整個壓槍晶片驅動中比較核心的邏輯

ps: 寫java後臺的菜鳥,業餘時間現學C#現賣的程式碼,各位多多包涵

某大型同性交友網站有完整原始碼

注意!本軟體不得用於商業用途,僅做學習交流使用