这几天实在是太忙了,已经有4天没写博客了。上次的博客还是【111@365】。今天准备写一篇技术博客,继续解读noname。
【前情提要】上一篇根据electron的标准,按图索骥,package.json->main.js->app.html->redirect.js->index.js,对这几个文件的内容进行了简要的解读,发现了第一次安装程序初始化的内容(主要在index.js完成),真正的程序入口还是没有浮出水面。本期继续探索。
上一篇还提到redirect.js文件把game.js、package.js、update.js、config.js放到onload事件当中,随着app.html打开而自动加载。那这几个文件都有什么内容,都干什么事情呢?今天我们来一探究竟。
1、先看update.js文件,这个文件内容很简单,只有一个全局变量window.noname_update,里面记录了,升级后版本号,原原版本号,升级日志,本次升级的文件。以最新1.9.98.6为例,增加了地藏王、孟婆,修改了杨彪、陈登、界张嶷(yi)的bug,涉及到的文件有card/extra.js等。内容如下:
window.noname_update={
version:'1.9.98.6',
update:'1.9.98.5.1',
changeLog:[
'杨彪,陈登,界张嶷',
'地藏王,孟婆',
'bug修复',
],
files:[
'card/extra.js',
//'card/huanlekapai.js',
//'card/sp.js',
'card/standard.js',
//'card/swd.js',
//'card/mtg.js',
//'card/guozhan.js',
//'card/gwent.js',
//'card/yunchou.js',
//'card/zhenfa.js',
//'card/zhulu.js',
'character/diy.js',
//'character/extra.js',
//'character/hearth.js',
//'character/gujian.js',
//'character/gwent.js',
//'character/hearth.js',
'character/mobile.js',
//'character/mtg.js',
//'character/old.js',
'character/refresh.js',
'character/shenhua.js',
'character/sp.js',
//'character/tw.js',
'character/standard.js',
//'character/swd.js',
//'character/xianjian.js',
//'character/xinghuoliaoyuan.js',
'character/yijiang.js',
//'character/yxs.js',
//'extension/boss/extension.js',
//'layout/default/layout.css',
//'layout/nova/layout.css',
//'mode/identity.js',
'mode/doudizhu.js',
'mode/guozhan.js',
//'mode/chess.js',
//'mode/tafang.js',
//'mode/single.js',
//'mode/stone.js',
//'mode/brawl.js',
//'mode/versus.js',
'mode/boss.js',
'game/game.js',
//'game/NoSleep.js',
//'game/config.js',
//'game/package.js',
//'game/asset.js',
//'game/source.js',
'theme/style/hp/xinglass.css',
'theme/style/hp/xinround.css',
'theme/style/hp/image/xinglass1.png',
'theme/style/hp/image/xinglass2.png',
'theme/style/hp/image/xinglass3.png',
'theme/style/hp/image/xinglass4.png',
'theme/style/hp/image/xinround1.png',
'theme/style/hp/image/xinround2.png',
'theme/style/hp/image/xinround3.png',
'theme/style/hp/image/xinround4.png',
]
};
2、再来看看config.js,这个里面也是只有一个全局变量window.conifg,里面各种参数,比如禁表、玩家名称、超时设置、身份、游戏模式等的配置文件。内容如下:
window.config={
forbidai:['ns_liuzhang','xin_yuji','re_yuji'],
forbidai_user:[],
forbidall:[],
forbidstone:['zhugedan','pal_xuanxiao','hs_malfurion','lusu','chenlin','hs_siwangzhiyi',
'gjqt_bailitusu','yuanshao','swd_anka','swd_nicole','daqiao','re_daqiao','hs_xuanzhuanjijia',
'zhuran','huatuo','swd_tuwei','hs_guldan','wangyi','caoang','swd_guyue','swd_rongshuang',
'swd_jiangziya','guojia','re_guojia','shen_caocao','swd_qiner','caopi','hs_yngvar','guansuo',
'gjqt_aruan','swd_hanluo','hs_anduin','swd_huanglei','yxs_yujix','yxs_luzhishen','swd_muyun','ow_tianshi',
'pal_yuejinzhao','hs_antonidas','xushi','hs_lreno'
],
forbidchess:['hetaihou','swd_kangnalishi'],
forbidboss:['caiwenji','gjqt_aruan','pal_xuanxiao','swd_hupo'],
forbiddouble:['zhugedan','swd_kangnalishi','dongzhuo','wutugu','hs_siwangzhiyi','hs_ronghejuren','hs_shanlingjuren'],
forbidthreecard:['qiankunbiao','shenhuofeiya','gw_ciguhanshuang','gw_birinongwu','gw_qinpendayu','gw_poxiao'],
all:{
sgscharacters:['standard','shenhua','xinghuoliaoyuan','refresh','yijiang','sp','extra','old','mobile','tw'],
sgscards:['standard','extra','sp','guozhan','zhulu'],
sgsmodes:['identity','guozhan','versus','doudizhu','single','brawl','connect'],
stockmode:['identity','guozhan','versus','boss','doudizhu','single','chess','stone','connect','brawl','tafang'],
stockextension:['boss','cardpile','coin','wuxing'],
layout:['default','newlayout'],
theme:['woodden','music','simple'],
card_font:['xiaozhuan','huangcao','caoshu','xingshu'],
double_hp:['hejiansan','pingjun','zuidazhi','zuixiaozhi','zonghe'],
image_background_filter:['default','blur','gray','sepia','invert','saturate','contrast','hue','brightness'],
},
game:'sgs',
duration:500,
hoveration:1000,
doubleclick_intro:true,
cheat:false,
volumn_background:8,
volumn_audio:8,
connect_avatar:'caocao',
connect_nickname:'无名玩家',
config_menu:true,
auto_popped_config:true,
auto_popped_history:false,
auto_skill:true,
auto_confirm:true,
enable_drag:true,
enable_pressure:false,
pressure_taptic:true,
hover_handcard:true,
hover_all:true,
right_info:true,
longpress_info:true,
long_info:true,
background_music:'music_default',
background_audio:true,
background_speak:true,
glow_phase:'yellow',
die_move:'flip',
skin:{},
gameRecord:{},
extensionInfo:{},
autoskilllist:[],
hiddenModePack:[],
hiddenCharacterPack:[],
hiddenCardPack:[],
hiddenPlayPack:[],
hiddenBackgroundPack:[],
customBackgroundPack:[],
favouriteCharacter:[],
favouriteMode:[],
recentIP:[],
vintageSkills:[],
alteredSkills:[],
brokenFile:[],
theme:'woodden',
layout:'mobile',
card_style:'default',
cardback_style:'default',
hp_style:'default',
image_character:'default',
image_background:'default',
asset_image:true,
asset_font:true,
card_font:'xiaozhuan',
show_statusbar_ios:'off',
show_statusbar_android:false,
show_name:true,
show_replay:false,
show_round_menu:true,
show_pause:true,
show_auto:true,
show_volumn:true,
show_cardpile:true,
only_fullskin:true,
show_connect:true,
show_wuxie:false,
show_wuxie_self:true,
show_stat:true,
show_playerids:true,
show_scrollbar:false,
mousewheel:true,
fold_card:true,
threed_card:false,
vertical_scroll:false,
handcard_scroll:0,
animation:true,
skill_animation_type:'default',
paused:false,
title:false,
button_press:true,
damage_shake:true,
log_highlight:true,
player_border:'normal',
radius_size:'default',
modeconfig:false,
gameconfig:false,
appearence:false,
video:'20',
coin:0,
intro:'i',
right_click:'pause',
sort:'type_sort',
cards:['standard','ex','extra','sp','classic','basic'],
characters:['standard','shenhua','sp','yijiang','refresh','xinghuoliaoyuan','mobile','extra'],
connect_characters:[],
connect_cards:[],
plays:[],
extensions:[],
banned:[],
bannedcards:[],
forbidlist:[],
bannedpile:{},
customcardpile:{},
addedpile:{},
mode:'identity',
mode_config:{
global:{
player_number:8,
auto_identity:'off',
double_character:false,
save_progress:true,
free_choose:true,
swap:true,
change_identity:true,
battle_number:3,
double_hp:'pingjun',
},
identity:{
identity:[
['zhu','fan'],
['zhu','nei','fan'],
['zhu','zhong','nei','fan'],
['zhu','zhong','nei','fan','fan'],
['zhu','zhong','nei','fan','fan','fan'],
['zhu','zhong','zhong','nei','fan','fan','fan'],
['zhu','zhong','zhong','nei','fan','fan','fan','fan'],
],
choice:{
zhu:3,
zhong:4,
nei:5,
fan:3,
},
show_identity:true,
difficulty:'normal',
dierestart:true
},
guozhan:{
difficulty:'normal',
initshow_draw:'mark',
dierestart:true
},
},
current_mode:{},
customforbid:[],
forbid:[
['huashen'],
['rehuashen'],
['xinmanjuan'],
//['xinleiji','fuji'],
['xinleiji','xinfu_jijun'],
['reluanji','jueqing'],
['lianying','rende'],
['lianying','anxian'],
['lianying','yinguo'],
['lianying','qingjian'],
['boss_juejing','rende'],
['boss_juejing','anxian'],
['boss_juejing','yinguo'],
['boss_juejing','qingjian'],
['shangshi','rende'],
['shangshi','anxian'],
['shangshi','yinguo'],
['shangshi','qingjian'],
['rende','relianying'],
['anxian','relianying'],
['yinguo','relianying'],
['shenxing','relianying'],
['qingjian','relianying'],
['rende','yuling'],
['anxian','yuling'],
['yinguo','yuling'],
['qingjian','yuling'],
//['qingnang','yiji'],
//['qingnang','reyiji'],
//['qingjian','tuntian'],
// ['yiji','tuntian'],
// ['reyiji','tuntian'],
['tuntian','guidao'],
['tuntian','tiandao'],
['tuntian','huanshi'],
// ['tuntian','guicai'],
// ['jiang','chongzhen'],
// ['fenji','yuling'],
['jiushi','guixin'],
['xiuhua','qiaoxie'],
['xiuhua','xuanfeng'],
['xiuhua','duanxing'],
['xiuhua','xiaoji'],
['xiuhua','xiaoji'],
// ['jiushi','jushou'],
// ['jiushi','kuiwei'],
['zishu','xinfu_songsang'],
['zishu','shenxing'],
]
};
3、再看package.js,同样的,就一个全局变量,window.noname_package,里面存放了,所有的武将包、卡牌包、模式包、背景图片、样式等。内容如下:
window.noname_package={
character:{
standard:'标准',
refresh:'界限突破',
shenhua:'神话再临',
xinghuoliaoyuan:'星火燎原',
yijiang:'一将成名',
sp:'SP',
extra:'神将',
mobile:'移动版',
old:'怀旧',
diy:'DIY',
tw:'外服武将',
yxs:'英雄杀',
hearth:'炉石传说',
gwent:'昆特牌',
mtg:'万智牌',
ow:'守望先锋',
swd:'轩辕剑',
gujian:'古剑奇谭',
xianjian:'仙剑奇侠传',
},
card:{
standard:'标准',
extra:'军争',
sp:'SP',
guozhan:'国战',
zhulu:'逐鹿天下',
zhenfa:'阵法',
yunchou:'运筹帷幄',
swd:'轩辕剑',
gujian:'古剑奇谭',
hearth:'炉石传说',
gwent:'昆特牌',
mtg:'万智牌',
huanlekapai:'欢乐卡牌',
},
play:{
boss:'诸神降临',
cardpile:'牌堆补充',
wuxing:'五行生克',
coin:'富甲天下',
},
mode:{
identity:'身份',
guozhan:'国战',
versus:'对决',
connect:'联机',
boss:'挑战',
doudizhu:'斗地主',
single:'单挑',
chess:'战棋',
tafang:'塔防',
stone:'炉石',
brawl:'乱斗',
},
submode:{
identity:{
normal:'身份模式',
zhong:'忠胆英杰',
purple:'3v3v2',
},
guozhan:{
normal:'国战模式',
mingjiang:'明将国战'
},
versus:{
four:'四人对抗',
three:'统率三军',
two:'欢乐成双',
jiange:'守卫剑阁',
siguo:'四国争霸',
standard:'自由对决'
},
chess:{
combat:'战棋模式',
three:'战棋统率',
leader:'战棋君主'
},
single:{
normal:'新1v1',
},
},
background:{
planetarian_bg:'星梦',
ol_bg:'龙纹',
heaven_bg:'红烧',
kyoani_bg:'京都',
key_bg:'键社',
zhulin_bg:'竹林',
shengshi_bg:'盛世',
taoyuan_bg:'桃园',
zhanhuo_bg:'战火',
huangtian_bg:'黄天',
september_bg:'九月',
yinxiang_bg:'印象',
zhanyun_bg:'战云',
beipan_bg:'背叛',
lanting_bg:'兰亭',
lingju_bg:'灵雎',
sanying_bg:'三英',
wangshi_bg:'往事',
xiongxin_bg:'雄心',
xinsha_bg:'新杀',
noname_bg:'璀璨',
wuming_bg:'无名',
},
music:{
music_phliosophy:'Philosophy of ours',
music_diaochan:'貂蝉',
music_shezhan:'舌战群儒',
music_danji:'千里走单骑',
music_jifeng:'祭风',
music_jilve:'极略',
},
font:{
xiaozhuan:'小篆',
xinwei:'新魏',
huangcao:'黄草',
yuanli:'楷体',
xingkai:'行楷',
shousha:'手杀',
},
theme:{
woodden:'木纹',
music:'音乐',
simple:'简约'
}
};
☆☆☆☆☆4.最后,让我们来看重头戏,game.js,绝大多数功能都在这个js里面完成。整个文件有50849行,是的你没看错,一个程序文件有5万多行,而且没有注释,可以想象下解读的难度。不过不怕,咱们还是一点一点来。内容太多就不贴了,先看全局。整个文件,有一个自动执行(有小括弧包含着)的函数构成,这个函数,有6个复杂的变量,并在最后调用了其中一个变量的一个子函数lib.init.init(),看来,正在的程序入口,应该就是他了。截图如下:
(中午时间,抽空写的,先到这儿吧。去吃饭了,还得准备下午的会议。下期继续解读game.js,万里长征踏上了第一步,感觉距离找到程序运行框架和需要的api越来越近了。)