// 5.比较文件数据生成下载列表 private bool CheckDiff() { // Debug.Log("Updater.CheckDiff"); AssetIndexFile oldAssets = AssetIndexData.Instance().GetIndex(); // 本地比服务器版本还新, 跳过更新步骤 if (oldAssets.GetVersion() > _latest.GetVersion()) { return(true); } // 检查是否大版本更新 if (!VersionHelper.IsCompatible(oldAssets.GetVersion(), _latest.GetVersion())) { return(false); } // 文件比较 var allAssets = _latest.FetchAll(); _updateList = new List <AssetInfo>(allAssets.Count); _updateSize = 0; foreach (AssetInfo asset in allAssets) { if (asset == null) { continue; } FileInfo fi = new FileInfo(asset.GetWritePath()); // 检查是否匹配 AssetInfo old = oldAssets.GetAssetInfo(asset.hash); if (old == null || old.IsDiff(asset) || old.IsDiff(fi)) { _updateList.Add(asset); _updateSize += asset.size; } } return(true); }
// 6.下载所有更新文件 private IEnumerator DownloadAssets() { // Debug.Log("Updater.DownloadAssets " + _updateList.Count); Directory.CreateDirectory(GameConfig.PERSISTENT_PATH + "media"); AssetIndexFile oldAssets = AssetIndexData.Instance().GetIndex(); int accumSize = 0; _downloadedSize = 0; UpdateProgress(); string rootUrl = _updateSetting.resUrl + _latestVersion + '-' + GameConfig.PLATFORM + '/'; foreach (var asset in _updateList) { byte[] bytes = null; _currentAssetSize = asset.size; _currentAssetDownloaded = 0; string url = rootUrl + asset.GetFilename() + "?spm=" + GetRandomValue(); for (int i = 0; i < DOWNLOAD_RETRY_TIMES; i++) { WWW downloader = new WWW(url); _downloader = downloader; yield return(downloader); // 下载成功 if (downloader.error == null) { bytes = downloader.bytes; break; } yield return(new WaitForSeconds(DOWNLOAD_RETRY_DELAY)); } if (bytes == null || bytes.Length != asset.size) { if (bytes == null) { Debug.LogWarning("Updater.DownloadAssets failed " + url); } else { Debug.LogWarning("Updater.DownloadAssets invalid size of " + url); } // 下载更新包失败,弹出重试窗口 _confirmDownload = false; ShowNoticeDialog(GetText(MESSAGE_NETWORK_ERROR), BUTTON_RETRY, OnRetryCallback); yield break; } // 写入文件 File.WriteAllBytes(asset.GetWritePath(), bytes); _currentAssetSize = 0; _currentAssetDownloaded = 0; _downloader = null; _downloadedSize += asset.size; accumSize += asset.size; UpdateProgress(); // 替换索引 oldAssets.AddAssetInfo(asset); // 凑齐若干字节后写入索引文件 if (accumSize >= DOWNLOAD_ACCUM_WRITE_INDEX) { accumSize = 0; AssetIndexData.Instance().Save(); } } oldAssets.SetVersion(_latest.GetVersion()); AssetIndexData.Instance().Save(); GameConfig.VERSION = AssetIndexData.Instance().GetVersionString(); SetProgressInfo(1, GetText(MESSAGE_COMPLETE), false); _updateStatus = STATUS_COMPLETE; NotifyUpdateEnd(); }
private IEnumerator HotUpdate() { // 0.读取更新配置信息 yield return(StartCoroutine(LoadUpdateConfig(GameConfig.PERSISTENT_URL + "media/update.json"))); if (_updateConfig == null) { yield return(StartCoroutine(LoadUpdateConfig(GameConfig.DATA_URL + "media/update.json"))); if (_updateConfig == null) { // 读取失败直接关闭游戏 Debug.LogError("Invalid update config. Application halt!"); Application.Quit(); yield break; } } SetProgressInfo(0, GetText(MESSAGE_CHECKING)); // 1.加载本地文件索引 yield return(StartCoroutine(AssetIndexData.Instance().Load(this))); GameConfig.LANG = _updateConfig.lang; GameConfig.VERSION = AssetIndexData.Instance().GetVersionString(); UpdateLogo(); // 是否跳过更新 if (_skipUpdate) { _updateStatus = STATUS_COMPLETE; yield break; } // 2.读取最新更新配置文件 yield return(StartCoroutine(DownloadUpdateSetting())); if (_updateSetting == null) { // 是否跳过更新 if (_skipUpdate) { _updateStatus = STATUS_COMPLETE; yield break; } ShowNoticeDialog(GetText(MESSAGE_NETWORK_ERROR), BUTTON_RETRY, this.OnRetryCallback); yield break; } int verNow = AssetIndexData.Instance().GetVersion(); int vStatus = _updateSetting.GetStatus(verNow, GameConfig.PLATFORM); GameConfig.BETA = (vStatus == VersionStatus.STATUS_BETA); GameConfig.REVIEW = (vStatus == VersionStatus.STATUS_REVIEW || vStatus == VersionStatus.STATUS_GOV); GameConfig.SERVER_LIST_URL = _updateSetting.svrUrl + "?s=" + vStatus.ToString() + "&p=" + GameConfig.PLATFORM; GameConfig.GIFT_CODE_URL = _updateSetting.giftUrl; GameConfig.GAME_EVENT_URL = _updateSetting.eventUrl; // 通知游戏启动 EventHelper.DoEvent(EventHelper.EVENT_STARTUP, this); Debug.Log("HotUpdate: " + GameConfig.LANG + " " + GameConfig.VERSION + " " + GameConfig.PLATFORM + " BETA=" + GameConfig.BETA + " REVIEW=" + GameConfig.REVIEW); // 是否跳过更新 if (_skipUpdate) { _updateStatus = STATUS_COMPLETE; NotifyUpdateEnd(); yield break; } // 3.检查最新版本号 int verLatest = _updateSetting.GetLastVersion(verNow, GameConfig.PLATFORM); if (verLatest == 0) { // 找不到可更新的版本,跳过更新 _updateStatus = STATUS_COMPLETE; NotifyUpdateEnd(); yield break; } _latestVersion = VersionHelper.CodeToString(verLatest); // 4.下载最新的文件索引 yield return(StartCoroutine(DownloadLatestIndex())); if (_latest == null) { ShowNoticeDialog(GetText(MESSAGE_NETWORK_ERROR), BUTTON_RETRY, this.OnRetryCallback); yield break; } // 5.比较文件数据生成下载列表 if (!CheckDiff()) { // 出现大版本更新,提示重新安装最新版 ShowNoticeDialog(GetText(MESSAGE_NOT_COMPATIBLE), BUTTON_UPDATE, this.OnStoreUpdateCallback, false); yield break; } // 无需更新, 直接写入最新版本号 if (_updateList == null || _updateList.Count == 0) { AssetIndexData.Instance().GetIndex().SetVersion(_latest.GetVersion()); AssetIndexData.Instance().Save(); GameConfig.VERSION = AssetIndexData.Instance().GetVersionString(); SetProgressInfo(0, GetText(MESSAGE_COMPLETE)); // 不设置到100%,不想让玩家看到进度条在加载时又回到0闪烁 _updateStatus = STATUS_COMPLETE; NotifyUpdateEnd(); yield break; } // 如果是Wifi环境,无需弹窗确认,直接开始下载 if (Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork) { _confirmDownload = false; } // 如果更新文件小于5M,无需弹窗确认,直接开始下载 if (_updateSize <= 1024 * 1024 * 5) { _confirmDownload = false; } // 6.弹出更新确认框, 下载所有更新文件 if (_confirmDownload) { ShowNoticeDialog(GetText(MESSAGE_NEW_VERSION, FormatSize(_updateSize)), BUTTON_UPDATE, this.OnDownloadCallback); } else { OnDownloadCallback(); } }