private static void UpdateAssetMap(PatchManifest patchManifest, PatchBundle patchBundle) { // 构建主动收集的资源路径和资源包之间的映射关系。 // 注意:这里面不包括依赖的非主动收集资源。 foreach (var assetPath in patchBundle.CollectAssets) { // 添加原始路径 // 注意:我们不允许原始路径存在重名 if (patchManifest.AssetsMapping.ContainsKey(assetPath)) { throw new Exception($"Asset path have existed : {assetPath}"); } patchManifest.AssetsMapping.Add(assetPath, patchBundle); // 添加去掉后缀名的路径 if (Path.HasExtension(assetPath)) { string assetPathWithoutExtension = assetPath.RemoveExtension(); if (patchManifest.AssetsMapping.ContainsKey(assetPathWithoutExtension)) { MotionLog.Warning($"Asset path have existed : {assetPathWithoutExtension}"); } else { patchManifest.AssetsMapping.Add(assetPathWithoutExtension, patchBundle); } } } }
/// <summary> /// 反序列化 /// </summary> public static PatchManifest Deserialize(string jsonData) { PatchManifest patchManifest = JsonUtility.FromJson <PatchManifest>(jsonData); // 构建资源包集合 foreach (var patchBundle in patchManifest.BundleList) { patchManifest.Bundles.Add(patchBundle.BundleName, patchBundle); // 解析标记位 PatchBundle.ParseFlags(patchBundle.Flags, out patchBundle.IsEncrypted); // 解析依赖列表 patchBundle.Depends = GetDepends(patchManifest, patchBundle); // 构建资源映射集合 UpdateAssetMap(patchManifest, patchBundle); } // 构建变种集合 foreach (var variant in patchManifest.VariantList) { patchManifest.Variants.Add(variant.BundleName, variant); } return(patchManifest); }
private static int[] GetPatchDpendIDs(PatchManifest patchManifest, PatchBundle patchBundle) { List <int> result = new List <int>(); foreach (var bundleName in patchBundle.Depends) { int dependID = GetPatchDependID(patchManifest, bundleName); result.Add(dependID); } return(result.ToArray()); }
private WebFileRequest CreateDownloader(PatchBundle element) { // 注意:资源版本号只用于确定下载路径 string url = _patcher.GetWebDownloadURL(element.Version.ToString(), element.Hash); string savePath = PatchHelper.MakeSandboxCacheFilePath(element.Hash); FileUtility.CreateFileDirectory(savePath); // 创建下载器 MotionLog.Log($"Beginning to download web file : {url}"); WebFileRequest download = new WebFileRequest(url, savePath); download.UserData = element; download.DownLoad(); return(download); }
private WebFileRequest CreateDownloader(PatchBundle patchBundle) { // 注意:资源版本号只用于确定下载路径 string mainURL = _patcherMgr.GetPatchDownloadURL(patchBundle.Version, patchBundle.Hash); string fallbackURL = _patcherMgr.GetPatchDownloadFallbackURL(patchBundle.Version, patchBundle.Hash); string savePath = PatchHelper.MakeSandboxCacheFilePath(patchBundle.Hash); FileUtility.CreateFileDirectory(savePath); // 创建下载器 MotionLog.Log($"Beginning to download web file : {patchBundle.BundleName} URL : {mainURL}"); WebFileRequest download = WebFileSystem.GetWebFileRequest(mainURL, fallbackURL, savePath, _failedTryAgain); download.UserData = patchBundle; return(download); }
private static string[] GetDepends(PatchManifest patchManifest, PatchBundle patchBundle) { List <string> result = new List <string>(patchBundle.DependIDs.Length); foreach (var dependID in patchBundle.DependIDs) { if (dependID >= 0 && dependID < patchManifest.BundleList.Count) { var dependPatchBundle = patchManifest.BundleList[dependID]; result.Add(dependPatchBundle.BundleName); } else { throw new Exception($"Invalid depend id : {dependID} : {patchBundle.BundleName}"); } } return(result.ToArray()); }
public bool CheckContentIntegrity(PatchBundle patchBundle) { return(CheckContentIntegrity(patchBundle.Hash, patchBundle.CRC, patchBundle.SizeBytes)); }
/// <summary> /// 更新下载器 /// </summary> public void Update() { if (DownloadStates != EDownloaderStates.Loading) { return; } // 检测下载器结果 for (int i = _loaders.Count - 1; i >= 0; i--) { var loader = _loaders[i]; if (loader.IsDone() == false) { continue; } PatchBundle element = loader.UserData as PatchBundle; // 检测是否下载失败 if (loader.HasError()) { loader.ReportError(); loader.Dispose(); _loaders.RemoveAt(i); _loadFailedList.Add(element); continue; } // 验证下载文件完整性 if (_patcher.CheckContentIntegrity(element) == false) { MotionLog.Error($"Check download content integrity is failed : {element.BundleName}"); loader.Dispose(); _loaders.RemoveAt(i); _checkFailedList.Add(element); continue; } // 下载成功 loader.Dispose(); _loaders.RemoveAt(i); _succeedList.Add(element); CurrentDownloadCount++; CurrentDownloadBytes += element.SizeBytes; OnPatchFileDownloadSucceedCallback?.Invoke(TotalDownloadCount, CurrentDownloadCount, TotalDownloadBytes, CurrentDownloadBytes); } // 动态创建新的下载器到最大数量限制 // 注意:如果期间有下载失败的文件,暂停动态创建下载器 if (_downloadList.Count > 0 && _loadFailedList.Count == 0 && _checkFailedList.Count == 0) { if (_loaders.Count < _maxNumberOnLoad) { int index = _downloadList.Count - 1; WebFileRequest downloader = CreateDownloader(_downloadList[index]); _loaders.Add(downloader); _downloadList.RemoveAt(index); } } // 下载结算 if (_loaders.Count == 0) { // 更新缓存并保存 if (_succeedList.Count > 0) { _patcher.CacheDownloadPatchFiles(_succeedList); } if (_loadFailedList.Count > 0) { DownloadStates = EDownloaderStates.Failed; OnPatchFileDownloadFailedCallback?.Invoke(_loadFailedList[0].BundleName); } else if (_checkFailedList.Count > 0) { DownloadStates = EDownloaderStates.Failed; OnPatchFileCheckFailedCallback?.Invoke(_checkFailedList[0].BundleName); } else { // 结算成功 DownloadStates = EDownloaderStates.Succeed; } } }
/// <summary> /// 更新下载器 /// </summary> public void Update() { if (DownloadStates != EDownloaderStates.Loading) { return; } // 检测下载器结果 _removeList.Clear(); long downloadBytes = CurrentDownloadBytes; foreach (var loader in _downloaders) { downloadBytes += (long)loader.DownloadedBytes; if (loader.IsDone() == false) { continue; } PatchBundle patchBundle = loader.UserData as PatchBundle; // 检测是否下载失败 if (loader.HasError()) { loader.ReportError(); loader.Dispose(); _removeList.Add(loader); _loadFailedList.Add(patchBundle); continue; } // 验证下载文件完整性 if (_patcherMgr.CheckContentIntegrity(patchBundle) == false) { MotionLog.Error($"Check download content integrity is failed : {patchBundle.BundleName}"); loader.Dispose(); _removeList.Add(loader); _checkFailedList.Add(patchBundle); continue; } // 下载成功 loader.Dispose(); _removeList.Add(loader); _succeedList.Add(patchBundle); CurrentDownloadCount++; CurrentDownloadBytes += patchBundle.SizeBytes; } // 移除已经完成的下载器(无论成功或失败) foreach (var loader in _removeList) { _downloaders.Remove(loader); } // 如果下载进度发生变化 if (_lastDownloadBytes != downloadBytes || _lastDownloadCount != CurrentDownloadCount) { _lastDownloadBytes = downloadBytes; _lastDownloadCount = CurrentDownloadCount; OnDownloadProgressCallback?.Invoke(TotalDownloadCount, _lastDownloadCount, TotalDownloadBytes, _lastDownloadBytes); } // 动态创建新的下载器到最大数量限制 // 注意:如果期间有下载失败的文件,暂停动态创建下载器 if (_downloadList.Count > 0 && _loadFailedList.Count == 0 && _checkFailedList.Count == 0) { if (_downloaders.Count < _maxNumberOnLoad) { int index = _downloadList.Count - 1; WebFileRequest downloader = CreateDownloader(_downloadList[index]); _downloaders.Add(downloader); _downloadList.RemoveAt(index); } } // 下载结算 if (_downloaders.Count == 0) { // 更新缓存并保存 if (_succeedList.Count > 0) { _patcherMgr.CacheDownloadPatchFiles(_succeedList); } if (_loadFailedList.Count > 0) { DownloadStates = EDownloaderStates.Failed; OnPatchFileDownloadFailedCallback?.Invoke(_loadFailedList[0].BundleName); OnDownloadOverCallback?.Invoke(false); } else if (_checkFailedList.Count > 0) { DownloadStates = EDownloaderStates.Failed; OnPatchFileCheckFailedCallback?.Invoke(_checkFailedList[0].BundleName); OnDownloadOverCallback?.Invoke(false); } else { // 结算成功 DownloadStates = EDownloaderStates.Succeed; OnDownloadOverCallback?.Invoke(true); } } }
public bool CheckContentIntegrity(PatchBundle element) { return(CheckContentIntegrity(element.Hash, element.CRC, element.SizeBytes)); }