背景:
坦克世界游戏内部使用flash来构建游戏界面,我们的插件也是使用flash开发,所以可以说这是win32程序与flash实时通讯的问题。
) X* M O% e5 [但是由于游戏禁止了其内部flash的很多功能,例如socket,导致我们无法使用常规手段进行通讯。
$ S* G) U- i1 B- q
: P1 M, `/ W3 |’ ~; j* y& H实现方式:; `2 j0 |( c, V
flash内有一个LoadVars函数,这个函数读取flash文件所在目录下的FileName文件,然后返回该文件的内容。x7 X: ?’ w( }’ q
我们的通讯即是以此函数为突破口,用FileName来传递数据,只要FileName中带有WOTBOX协议头,盒子客户端都会接收并处理所带功能函数,来实现flash插件端和盒子客户端的通讯。5 m |( x6 a2 p1 C1 D
(注意:由于游戏内部所有数据都是统一转小写,所以有大写的字母得先进行转义,即FileName的所有内容都要转义,大写的转义是跟盒子客户端约定好的,看如下示例代码便知). }" _; h2 Q, L( d$ Z
4 a3 x# Q u) d$ i! V0 k8 g
API接口说明:6 |! |’ ~, f0 p, r# i- p0 G E" ^% e+ `
1.TankSkin(TankName) 调用坦克涂装命令,成功返回 true,失败返回false
1 _6 o( ~$ [% y* ^2 T9 m2.SetConfig(Key,Value) 保存一个设置,成功返回 true,失败返回false" M7 @) h% M2 W& b6 |3.GetConfig(Key) 获取一个设置,成功返回设置的值,失败返回空文本* ?5 b* N. D; j0 }8 X- @1 X4.SubmitSearch(JSON对象) 提交一个搜索,返回一个搜索句柄,JSON对象结构为4 W7 s4 A. k; D" A8 b, g$ @, c{"PlayCount" : 3, "PlayInfo":[{"Name":"小明","Tank":"M26"},{"Name":"小小明","Tank":"S51"},{"Name":"明小小","Tank":"M110"}]}" @. 7 k) M$ K: T5.GetSearchResult(搜索句柄) 获取搜索信息,成功返回一个JSON对象,超时返回timeout,搜索未完成返回当前搜索句柄+ O3 R% r: u! d6.SetCrosshair(ID) 设置瞄准插件样式,ID为瞄准插件ID,详见确认集成图标/瞄准样式表,成功返回true,失败返回false. i+ o/ |+ j9 K f
7.HelloBox(Random) 检测盒子是否运行的函数, Random为一个随机产生的数字, 成功运行的话返回 Random这个数字给插件,表示盒子正常运行! i+ b1 t G; c8.ReceiveMSG(Command) 告知盒子已经收到盒子发送的消息,参数为命令执行的返回值,如UpdateSkin执行成功可以返回true2 }# |/ J8 f2 ^, / C: _8 M9.UnZip(ZipPath) 告知盒子解压某个Zip文件,ZipPath的根路径目录为插件目录,解压目录也是插件目录/ }( r& C; @9 G’ Y* W10.IsFileExists(FilePath) 判断某个文件是否存在,FilePath为相对..res_mod�.8.6的文件路径,存在返回true,不存在返回false。* R1 _8 D, U! C! m: O4 x’ {1 l% e3 O
11.PluginLog(strLog) 写出一条日志语句,日志文件为盒子安装目录下的PlguinLog.txt文件,成功返回true,失败返回false’ C9 q2 ] T) ]: C4 N12.UserLogin(strServer, strName) 用户登录时调用此信息,告知盒子已登录用户的昵称和服务器,成功返回true,失败返回false- F% x9 O" d7 g2 V& N13.GetFileHash(FilePath) 获取某个文件的Hash值,FilePath为相对..res_mod�.8.6的文件路径,成功返回Hash,失败返回空。
- F( M7 r- s’ X( n- f9 h1 b14.SetTreeVisible(TreeVisible, OnAim);TreeVisible = true 就正常显示草丛,false就去除;OnAim = true 只在开镜时生效 ,false 不启用( u0 @’ C; ~: j( @( I: b
(注意:上面函数中如果有多个参数,在实际应用中是以#-#作为分隔符的,而非逗号,详情见示例)% L6 V x% ?$ M# r: d4 s2 g, T# D( d$ K, _" z# Z
flash插件端示例代码:7 H8 Y+ S1 @) m Y
下面,我以SetConfig(Key,Value)为例,保存一个值,键名为FirstKey,赋值为duowan+ i3 H1 ^$ U/ N5 l’ s0 O5 ]) R. {/ a4 T
-----------------------start code---------------------------------------------------------------------------5 K1 o0 d7 L) h8D+ i1 N% e: j! R! Y$ N# T+ x5 Y4 |/ F2 d1 N’ Dfunction parseData(fileName){$ g+ {% _! V2 a/ G var unEncoded:String = fileName;9 o4 h) r& E$ I2 c# c9 [
unEncoded = myReplace(unEncoded,"", "^1~");& a. z. L3 O4 m% ]. X) f
unEncoded = myReplace(unEncoded,"/", "^2~");& H4 A! f& z; _0 Y- q. w* S
unEncoded = myReplace(unEncoded,":", "^3~");7 g4 s6 o# Y7 z1 F# c( T I R //A-Z0 H( [1 W3 p7 X w" y% P0 ~ unEncoded = myReplace(unEncoded, "A", "^10~");0 B" B% c# ? i9 E( F/ A* |) S
unEncoded = myReplace(unEncoded, "B", "^11~");# u3 g9 W& E3 L. D; [5 Z- ~: R8 I unEncoded = myReplace(unEncoded, "C", "^12~");3 G% }4 {6 Y$ L- |! J
unEncoded = myReplace(unEncoded, "D", "^13~");0 p$ v u, k6 t unEncoded = myReplace(unEncoded, "E", "^14~");2 }- |) |& x/ l+ # j
unEncoded = myReplace(unEncoded, "F", "^15~");) w5 r. _! ! A% b unEncoded = myReplace(unEncoded, "G", "^16~");$ ]$ ~: t7 _) / C’ W3 [
unEncoded = myReplace(unEncoded, "H", "^17~");1 s. a. C, s! ?4 O0 g& B
unEncoded = myReplace(unEncoded, "I", "^18~");& c2 F; D; L- {9 ~ unEncoded = myReplace(unEncoded, "J", "^19~");! R( V% j5 v9 e
unEncoded = myReplace(unEncoded, "K", "^20~");’ ]/ D% u. x3 v- E" j
unEncoded = myReplace(unEncoded, "L", "^21~");/ g/ x) S. Y @- Q
unEncoded = myReplace(unEncoded, "M", "^22~");/ V" A7 ?- `$ N
unEncoded = myReplace(unEncoded, "N", "^23~");- p( k2 }# i: l, i$ e2 i
unEncoded = myReplace(unEncoded, "O", "^24~");% i( C. Z& j3 r1 z0 x’ a& I
unEncoded = myReplace(unEncoded, "P", "^25~");: g( K/ j x’ |# L unEncoded = myReplace(unEncoded, "Q", "^26~");: f3 J, X$ B0 j- F) X- m( C
unEncoded = myReplace(unEncoded, "R", "^27~");/ T’ c+ f’ M( V" {+ g9 i8 h; W
unEncoded = myReplace(unEncoded, "S", "^28~");6 d2 _0 Y# z$ Q5 W! i unEncoded = myReplace(unEncoded, "T", "^29~");7 @1 o0 x F, K2 f
unEncoded = myReplace(unEncoded, "U", "^30~");+ b2 V4 P- k/ |! ^) C% z) R
unEncoded = myReplace(unEncoded, "V", "^31~");6 o* ?- Y% q5 M, w& X& G unEncoded = myReplace(unEncoded, "W", "^32~");$ }* E, C; _’ l+ Y
unEncoded = myReplace(unEncoded, "X", "^33~");$ J* q/ y R- I9 P, V
unEncoded = myReplace(unEncoded, "Y", "^34~");8 ?" j6 , {5 s; n
unEncoded = myReplace(unEncoded, "Z", "^35~");7 a$ r5 G7 ]* U1 I return(unEncoded);4 |6 g# p" I3 {0 H- `* , ~; `}5 f4 w- s# |% S4 m’ O" A, h4 u# |$ t8 K0 I9 j9 I! q
function myReplace(str, strFind, strReplace) {
3 Q* J) S% I* @ var a = str;/ A! r4 H T# f7 k" v7 ~4 @! b
a = a.split(strFind).join(strReplace);. O8 _7 l’ | ]" S return(a);8 n5 x( w3 G9 m$ k5 K3 [’ _% b}+ ` ^/ e1 _9 h, B$ [K" Z+ H+ u+ L5 X8 z; S& F function callWOTBOX(fileName) {0 w: k4 B6 d. A3 y: s2 j
//先把fileName所有内容都大写转义3 |( h$ J( g5 _& j# O var _parseData = parseData(fileName);1 - N6 R. k! y7 M //跟盒子通讯,调用盒子开放APIq( D6 n( r7 V& d2 A getBoxData("WOTBOX-" + _parseData);6 F4 K/ W0 h" C. `; K* o5 b/ P6 ? $ K6 W- H X( }/ x$ J
function getBoxData(fileName) {* m’ a# t) E# e: }) `$ l3 z0 u var _local1 = new LoadVars();% g5 r% ~% `) |2 Z _local1.onData = function (src) {& G/ F6 y5 d$ A# v! c$ p2 Z6 Jif (src ==undefined) {, x. r% Y- @, S/ w% D+ H: ^
return(undefined);& k: I% Z/ a3 q" L}7 J$ v5 K: r6 i’ M8 G9 s. W3 Pif (src!="true")’ i j8 @0 R+ d$ U! a{1 � J7 G7 a2 B( I* v2 ^. J
//盒子返回的数据6 $ h5 J9 s3 ]; S( Atrace(src);* c6 T+ s; Z; [. m9 t’ y5 e! k% g}2 g9 ]) a# x# }. `: f7 f! u};|0 ] Q) ]- V/ O) V& k7 H6 O# C
_local1.load(fileName);/ R9 K+ N( m8 V1 @7 m}& p6 O. `9 @" K. @
; W8 G; t. N; J9 a% J. O8 o
//callWOTBOX,调用盒子接口函数
& r; M/ q5 ~& {4 z. B0 S5 A callWOTBOX("setconfig|FirstKey#-#duowan");
4 d O# M9 ] [+ e& O5 }" L# n3 c’ |- F0 s$ L7 x
----------------------end code---------------------------------------------------------------------------, b* c4 R( ^9 x- G8 `’ m; y3 s3 Z2 Y. ^0 f4 t- t& Y& J* W( e/ ~5 t
只要代码成功运行,该键名和所带的值都会保存在游戏客户端;以上的其他API接口函数都是类似用法,自己写好调用盒子接口函数,写入相应的API函数及传入参数,即可实现相应的功能
比如34的装甲20+KV的装甲75不小心撞上去你就瘪了。因为你车上没有安全气囊,即使有防撞钢梁吸能区也会让你残疾的,虽然你有坡度,但是铁皮也能给你撞得卷起来。
更别奢望应你那日本JJ一样的炮随便就想打穿人家,75的装甲理解为一块75的钢板这块钢板还有坡度,人家再摆个角度效果能达到120也说不定。所以,你要用80穿深的炮打穿数据75的装甲,你就得动动脑子了。比如侧面装甲,或者后部,再或者弱点,还要注意炮塔的相关数据,比如小飞象的炮塔