HotUpdate.js
10.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
"use strict";
cc._RF.push(module, '652b3iryalEoZXjTEltvgH1', 'HotUpdate');
// script/game/HotUpdate.js
"use strict";
// var md5 = require("md5")
var EventCenter = require("EventCenter");
var g_check = false;
cc.Class({
"extends": cc.Component,
properties: {
_searchPath: "",
//搜索路径
manifestUrl: {
type: cc.Asset,
// use 'type:' to declare an object reference
"default": null // object's default value is null
},
_checkUpdate: false,
_checkUpdateNum: 5,
//检查更新次数
_updating: false,
//正在检查更新或者更新中
_isForceUpdate: false,
_loadFiles: "yybs-remote-asset",
byteProgress: cc.ProgressBar,
//字节进度
fileProgress: cc.ProgressBar,
//文件进度
info: cc.Label,
//信息显示
fileLabel: cc.Label,
//文件个数
byteLabel: cc.Label,
//字节个数
// retryBtn: cc.Button,//重置按钮
// checkBtn: cc.Button,//检查更新按钮 目前是自动得
// updateBtn: cc.Button,//更新按钮 目前是自动的
forceUpdate: cc.Layout,
//强更界面
ensureBut: cc.Button,
//确定按钮
_forceHotUpdate: ""
},
start: function start() {
// if (CC_DEBUG) {//发布debug模式apk跳过热更
// this.startGame();//隐藏当前ui//多场景时 这直接加载下一个场景
// }
if (!cc.sys.isNative) //web//跳过热更
{
this.startGame(); //隐藏当前ui//多场景时 这直接加载下一个场景
} else {
this.hotUpdateInit();
this.hotUpdateLogic(); //热更逻辑
var delay = cc.delayTime(10);
var finishedAll = cc.callFunc(this.overTimeStartGame, this);
this.node.runAction(cc.sequence(delay, finishedAll));
}
},
checkCb: function checkCb(event) {
this._checkUpdate = false; //检测更新完毕
this._updating = false; //更新中
switch (event.getEventCode()) {
case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
this.showUpDateInfo('检查更新失败');
g_check = true;
break;
case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
this.showUpDateInfo('检查更新失败');
g_check = true;
break;
case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
this.showUpDateInfo('已是最新版本');
if (this._isForceUpdate == false) {
this.startGame();
return;
}
break;
case jsb.EventAssetsManager.NEW_VERSION_FOUND:
this.showUpDateInfo('发现新版本,正在更新...');
g_check = false;
break;
default:
return;
}
if (g_check == true) {
this.checkUpdate();
} else {
this.hotUpdate();
}
},
overTimeStartGame: function overTimeStartGame() {
if (this.node.active == true && this._checkUpdate == true) {
this.startGame();
}
},
startGame: function startGame() //开始游戏
{
this.node.active = false;
cc.log("开始游戏");
EventCenter.EventCenter.GameStart.emit();
},
hotUpdateInit: function hotUpdateInit() {
var self = this;
this.ensureBut.node.on('click', function (event) {
self.ensureButCallBack();
}, this);
},
ensureButCallBack: function ensureButCallBack() //确定按钮回掉
{
// cc.sys.openURL('http://formal.share.idj66nm.com/down/link?gameId=200001&gameState=1');//强更下载地址
cc.director.end();
},
hotUpdateLogic: function hotUpdateLogic() //热更逻辑
{
this.initAssetsManager();
this.checkUpdate();
},
forceUpdateLogic: function forceUpdateLogic() //强更逻辑
{
this._isForceUpdate = true;
this.forceUpdate.node.active = true;
},
initAssetsManager: function initAssetsManager() //初始化
{
this._searchPath = (jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + this._loadFiles; //获取热更时得搜索路径
cc.log('hotUpdate searchPath =' + this._searchPath);
var self = this;
var versionCompareHandle = function versionCompareHandle(versionA, versionB) //版本对比函数(检查本地mainfest和远端mainfes时,如果返回值大于0 会自动更新)
{
cc.log("JS Custom Version Compare: version A is " + versionA + ', version B is ' + versionB);
var vA = versionA.split('.');
var vB = versionB.split('.');
if (vA.length != vB.length || vA.length < 3) return 0;
if (parseInt(vA[0]) != parseInt(vB[0])) //前两位控制大版本更新
{
//强制更新
self.forceUpdateLogic();
return 0;
}
self._forceHotUpdate = vA[0] + "" + vA[1];
var forceUpdate = cc.sys.localStorage.getItem('forceupdateyybs');
cc.log("initAssetsManager forceupdate " + forceUpdate);
self._forceHotUpdate = vB[0] + "" + vB[1];
for (var i = 0; i < vA.length; ++i) {
var a = parseInt(vA[i]);
var b = parseInt(vB[i] || 0);
if (a === b) {
continue;
}
return -1;
}
if (vB.length > vA.length) {
return -1;
}
cc.sys.localStorage.setItem('forceupdateyybs', self._forceHotUpdate);
return 0;
};
this._am = new jsb.AssetsManager(this.manifestUrl, this._searchPath, versionCompareHandle); //初始化 创建 AssetsManager
// if (!cc.sys.ENABLE_GC_FOR_NATIVE_OBJECTS)
// {
// this._am.retain();
// }
//用户文件校验接口 由于下载过程中仍然有小概率可能由于网络原因或其他网络库的问题导致下载的文件内容有问题,
//在文件下载完成后热更新管理器会调用这个接口,如果返回 true 表示文件正常,返回 false 表示文件有问题
this._am.setVerifyCallback(function (path, asset) {
var compressed = asset.compressed; // 是压缩文件 不需要检查它的md5
var expectedMD5 = asset.md5; //检索md5值。
var relativePath = asset.path; // asset.path 是相对路径 path 绝对路径.
var size = asset.size; //文件的大小,但是这个值可能不存在
if (compressed) {
return true;
} else {
return true; // //使用绝对路径来加载文件,之后计算md5值
// var data = jsb.fileUtils.getDataFromFile(path);
// var curMD5 = md5(data);
// if (curMD5 == asset.md5) {
// //md5检验通过
// return true;
// } else {
// //md5检验失败
// //this.info.string = relativePath + "文件MD5校验失败";
// cc.log("md5检验失败");
// return false;
// }
}
});
if (cc.sys.os === cc.sys.OS_ANDROID) {
//控制下载并发数量的 API 有些Android设备可能会在并发任务太多时减慢下载速度。设置适合游戏的值。
this._am.setMaxConcurrentTask(2);
}
},
checkUpdate: function checkUpdate() //检查更新
{
this._checkUpdateNum = this._checkUpdateNum - 1;
if (this._checkUpdateNum <= 0) {
//直接登陆
this.startGame();
return;
}
if (this._updating) {
this.showUpDateInfo('正在检测或者更新中,请耐心等待...');
return;
}
this._am.setEventCallback(this.checkCb.bind(this));
if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
var url = this.manifestUrl.nativeUrl;
if (cc.loader.md5Pipe) {
url = cc.loader.md5Pipe.transformURL(url);
}
cc.log('加载本地Manifest', url);
this._am.loadLocalManifest(url);
}
this._am.checkUpdate();
this._checkUpdate = true; //正在检测更新
this.showUpDateInfo('正在检测更新,请耐心等待...');
},
hotUpdate: function hotUpdate() {
if (this._am == null) {
return;
}
this._am.setEventCallback(this.updateCb.bind(this));
if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
this._am.loadLocalManifest(this.manifestUrl);
}
this._am.update();
this._updating = true;
},
updateCb: function updateCb(event) {
var needRestart = false;
var failed = false;
switch (event.getEventCode()) {
case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
cc.log('错误:没找到本地manifest文件');
failed = true;
break;
case jsb.EventAssetsManager.UPDATE_PROGRESSION:
//更新进度
this.byteProgress.progress = event.getPercent();
this.fileProgress.progress = event.getPercentByFile();
this.fileLabel.node.active = true;
this.fileLabel.string = event.getDownloadedFiles() + ' / ' + event.getTotalFiles();
this.byteLabel.string = event.getDownloadedBytes() / 1024 + ' / ' + event.getTotalBytes() / 1024;
var msg = event.getMessage();
if (msg) {// cc.log(event.getPercent()/100 + '% : ' + msg);
}
break;
case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
cc.log('错误:下载或解析MANIFEST文件失败');
failed = true;
break;
case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
this.showUpDateInfo('与服务器版本一致');
if (this._isForceUpdate == false) this.startGame();
break;
case jsb.EventAssetsManager.UPDATE_FINISHED:
this.showUpDateInfo('更新完成');
this._updating = false;
needRestart = true;
break;
case jsb.EventAssetsManager.UPDATE_FAILED:
//更新失败
this._updating = false;
failed = true;
break;
case jsb.EventAssetsManager.ERROR_UPDATING:
if (event.getMessage()) {
this.info.string = '更新' + event.getAssetId() + '时发生错误.' + event.getMessage();
} else {
this.info.string = '更新' + event.getAssetId() + '时发生错误';
}
needRestart = true;
break;
case jsb.EventAssetsManager.ERROR_DECOMPRESS:
this.showUpDateInfo('解压发生错误.' + event.getMessage());
break;
default:
break;
}
if (needRestart) {
this.restartGame();
return;
}
if (failed) {
this._updating = false;
this.checkUpdate();
}
},
onDestroy: function onDestroy() {
if (this._am) this._am.setEventCallback(null);
},
restartGame: function restartGame() //重启游戏
{
this.fileProgress.progress = 1;
this.byteProgress.progress = 1;
var searchPaths = jsb.fileUtils.getSearchPaths();
var newPaths = this._am.getLocalManifest().getSearchPaths();
Array.prototype.unshift(searchPaths, newPaths);
cc.sys.localStorage.setItem('HotUpdateSearchPaths', JSON.stringify(searchPaths));
cc.sys.localStorage.setItem('forceupdateyybs', this._forceHotUpdate);
jsb.fileUtils.setSearchPaths(searchPaths);
cc.audioEngine.stopAll();
cc.game.restart();
},
//显示更新信息
showUpDateInfo: function showUpDateInfo(strInfo) {
this.info.string = strInfo;
}
});
cc._RF.pop();