/// <summary> /// 清空未被使用的缓存文件 /// </summary> public void ClearUnusedCacheFiles() { string cacheFolderPath = SandboxHelper.GetCacheFolderPath(); if (Directory.Exists(cacheFolderPath) == false) { return; } DirectoryInfo directoryInfo = new DirectoryInfo(cacheFolderPath); foreach (FileInfo fileInfo in directoryInfo.GetFiles()) { bool used = false; foreach (var patchBundle in LocalPatchManifest.BundleList) { if (fileInfo.Name == patchBundle.Hash) { used = true; break; } } if (used == false) { YooLogger.Log($"Delete unused cache file : {fileInfo.Name}"); File.Delete(fileInfo.FullName); } } }
/// <summary> /// 开始下载资源文件 /// 注意:只有第一次请求的参数才是有效的 /// </summary> public static DownloaderBase BeginDownload(BundleInfo bundleInfo, int failedTryAgain, int timeout = 60) { // 查询存在的下载器 if (_downloaderDic.TryGetValue(bundleInfo.Hash, out var downloader)) { return(downloader); } // 如果资源已经缓存 if (ContainsVerifyFile(bundleInfo.Hash)) { var tempDownloader = new TempDownloader(bundleInfo); return(tempDownloader); } // 创建新的下载器 { YooLogger.Log($"Beginning to download file : {bundleInfo.BundleName} URL : {bundleInfo.RemoteMainURL}"); FileUtility.CreateFileDirectory(bundleInfo.GetCacheLoadPath()); DownloaderBase newDownloader; if (bundleInfo.SizeBytes >= _breakpointResumeFileSize) { newDownloader = new HttpDownloader(bundleInfo); } else { newDownloader = new FileDownloader(bundleInfo); } newDownloader.SendRequest(failedTryAgain, timeout); _downloaderDic.Add(bundleInfo.Hash, newDownloader); return(newDownloader); } }
internal override void Update() { if (_steps == ESteps.Builder) { _simulatePatchManifestPath = EditorSimulateModeHelper.SimulateBuild(); if (string.IsNullOrEmpty(_simulatePatchManifestPath)) { _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = "Simulate build failed, see the detail info on the console window."; return; } _steps = ESteps.Load; } if (_steps == ESteps.Load) { if (File.Exists(_simulatePatchManifestPath) == false) { _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = $"Manifest file not found : {_simulatePatchManifestPath}"; return; } YooLogger.Log($"Load manifest file : {_simulatePatchManifestPath}"); string jsonContent = FileUtility.ReadFile(_simulatePatchManifestPath); var simulatePatchManifest = PatchManifest.Deserialize(jsonContent); _impl.SetSimulatePatchManifest(simulatePatchManifest); _steps = ESteps.Done; Status = EOperationStatus.Succeed; } }
/// <summary> /// 缓存验证过的文件 /// </summary> public static void CacheVerifyFile(string hash, string bundleName) { if (_cachedHashList.ContainsKey(hash) == false) { YooLogger.Log($"Cache verify file : {bundleName} Hash : {hash}"); _cachedHashList.Add(hash, bundleName); } }
/// <summary> /// 加载沙盒内的补丁清单 /// 注意:在加载本地补丁清单之前,已经验证过文件的哈希值 /// </summary> private void LoadSandboxPatchManifest(int updateResourceVersion) { YooLogger.Log("Load sandbox patch manifest file."); string filePath = PathHelper.MakePersistentLoadPath(YooAssetSettingsData.GetPatchManifestFileName(updateResourceVersion)); string jsonData = File.ReadAllText(filePath); var sandboxPatchManifest = PatchManifest.Deserialize(jsonData); _impl.SetLocalPatchManifest(sandboxPatchManifest); }
/// <summary> /// 销毁所有下载器 /// </summary> public static void DestroyAll() { foreach (var valuePair in _downloaderDic) { var downloader = valuePair.Value; downloader.Abort(); } _downloaderDic.Clear(); YooLogger.Log("DownloadSystem destroy all !"); }
/// <summary> /// 更新缓存文件 /// </summary> public static void UpdateCache() { YooLogger.Log($"Update cache data to disk : {Application.version}"); CacheData cacheData = new CacheData(); cacheData.CacheAppVersion = Application.version; string filePath = GetCacheDataFilePath(); string jsonData = JsonUtility.ToJson(cacheData); FileUtility.CreateFile(filePath, jsonData); }
/// <summary> /// 加载配置文件 /// </summary> private static void LoadSettingData() { _setting = Resources.Load <YooAssetSettings>("YooAssetSettings"); if (_setting == null) { YooLogger.Log("YooAsset use default settings."); _setting = ScriptableObject.CreateInstance <YooAssetSettings>(); } else { YooLogger.Log("YooAsset use user settings."); } }
internal override void Update() { if (_steps == ESteps.None || _steps == ESteps.Done) { return; } if (_steps == ESteps.LoadWebManifest) { string webURL = GetPatchManifestRequestURL(YooAssetSettingsData.GetPatchManifestFileName(_resourceVersion)); YooLogger.Log($"Beginning to request patch manifest : {webURL}"); _downloader = new UnityWebDataRequester(); _downloader.SendRequest(webURL, _timeout); _steps = ESteps.CheckWebManifest; } if (_steps == ESteps.CheckWebManifest) { Progress = _downloader.Progress(); if (_downloader.IsDone() == false) { return; } // Check error if (_downloader.HasError()) { _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = _downloader.GetError(); } else { // 解析补丁清单 if (ParseRemotePatchManifest(_downloader.GetText())) { _steps = ESteps.Done; Status = EOperationStatus.Succeed; } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = $"URL : {_downloader.URL} Error : remote patch manifest content is invalid"; } } _downloader.Dispose(); } }
internal override void Update() { if (_steps == ESteps.None || _steps == ESteps.Done) { return; } if (_steps == ESteps.LoadStaticVersion) { string webURL = GetStaticVersionRequestURL(YooAssetSettings.VersionFileName); YooLogger.Log($"Beginning to request static version : {webURL}"); _downloader = new UnityWebDataRequester(); _downloader.SendRequest(webURL, _timeout); _steps = ESteps.CheckStaticVersion; } if (_steps == ESteps.CheckStaticVersion) { Progress = _downloader.Progress(); if (_downloader.IsDone() == false) { return; } if (_downloader.HasError()) { _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = _downloader.GetError(); } else { if (int.TryParse(_downloader.GetText(), out int value)) { ResourceVersion = value; _steps = ESteps.Done; Status = EOperationStatus.Succeed; } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = $"URL : {_downloader.URL} Error : static version content is invalid."; } } _downloader.Dispose(); } }
/// <summary> /// 解析并保存远端请求的补丁清单 /// </summary> private bool ParseAndSaveRemotePatchManifest(int updateResourceVersion, string content) { try { var remotePatchManifest = PatchManifest.Deserialize(content); _impl.SetLocalPatchManifest(remotePatchManifest); YooLogger.Log("Save remote patch manifest file."); string savePath = PathHelper.MakePersistentLoadPath(YooAssetSettingsData.GetPatchManifestFileName(updateResourceVersion)); PatchManifest.Serialize(savePath, remotePatchManifest); return(true); } catch (Exception e) { YooLogger.Error(e.ToString()); return(false); } }
/// <summary> /// 读取缓存文件 /// 注意:如果文件不存在则创建新的缓存文件 /// </summary> public static CacheData LoadCache() { string filePath = GetCacheDataFilePath(); if (File.Exists(filePath)) { string jsonData = FileUtility.ReadFile(filePath); var cacheData = JsonUtility.FromJson <CacheData>(jsonData); YooLogger.Log($"Load cache data : {cacheData.CacheAppVersion}"); return(cacheData); } else { YooLogger.Log($"Create cache data : {Application.version}"); CacheData cacheData = new CacheData(); cacheData.CacheAppVersion = Application.version; string jsonData = JsonUtility.ToJson(cacheData); FileUtility.CreateFile(filePath, jsonData); return(cacheData); } }
private void InitVerifyingCache() { // 遍历所有文件然后验证并缓存合法文件 foreach (var patchBundle in _impl.LocalPatchManifest.BundleList) { // 忽略缓存文件 if (DownloadSystem.ContainsVerifyFile(patchBundle.Hash)) { continue; } // 忽略APP资源 // 注意:如果是APP资源并且哈希值相同,则不需要下载 if (_impl.AppPatchManifest.Bundles.TryGetValue(patchBundle.BundleName, out PatchBundle appPatchBundle)) { if (appPatchBundle.IsBuildin && appPatchBundle.Hash == patchBundle.Hash) { continue; } } // 查看文件是否存在 string filePath = SandboxHelper.MakeCacheFilePath(patchBundle.Hash); if (File.Exists(filePath) == false) { continue; } _waitingList.Add(patchBundle); } // 设置同时验证的最大数 ThreadPool.GetMaxThreads(out int workerThreads, out int ioThreads); YooLogger.Log($"Work threads : {workerThreads}, IO threads : {ioThreads}"); _verifyMaxNum = Math.Min(workerThreads, ioThreads); _verifyTotalCount = _waitingList.Count; }
internal override void Update() { if (_steps == ESteps.None || _steps == ESteps.Done) { return; } if (_steps == ESteps.LoadWebManifestHash) { string webURL = GetPatchManifestRequestURL(YooAssetSettingsData.GetPatchManifestHashFileName(_resourceVersion)); YooLogger.Log($"Beginning to request patch manifest hash : {webURL}"); _downloader1 = new UnityWebDataRequester(); _downloader1.SendRequest(webURL, _timeout); _steps = ESteps.CheckWebManifestHash; } if (_steps == ESteps.CheckWebManifestHash) { if (_downloader1.IsDone() == false) { return; } // Check error if (_downloader1.HasError()) { _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = _downloader1.GetError(); } else { string webManifestHash = _downloader1.GetText(); string cachedManifestHash = GetSandboxPatchManifestFileHash(_resourceVersion); // 如果补丁清单文件的哈希值相同 if (cachedManifestHash == webManifestHash) { YooLogger.Log($"Patch manifest file hash is not change : {webManifestHash}"); LoadSandboxPatchManifest(_resourceVersion); _steps = ESteps.InitVerifyingCache; } else { YooLogger.Log($"Patch manifest hash is change : {webManifestHash} -> {cachedManifestHash}"); _steps = ESteps.LoadWebManifest; } } _downloader1.Dispose(); } if (_steps == ESteps.LoadWebManifest) { string webURL = GetPatchManifestRequestURL(YooAssetSettingsData.GetPatchManifestFileName(_resourceVersion)); YooLogger.Log($"Beginning to request patch manifest : {webURL}"); _downloader2 = new UnityWebDataRequester(); _downloader2.SendRequest(webURL, _timeout); _steps = ESteps.CheckWebManifest; } if (_steps == ESteps.CheckWebManifest) { if (_downloader2.IsDone() == false) { return; } // Check error if (_downloader2.HasError()) { _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = _downloader2.GetError(); } else { // 解析补丁清单 if (ParseAndSaveRemotePatchManifest(_resourceVersion, _downloader2.GetText())) { _steps = ESteps.InitVerifyingCache; } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = $"URL : {_downloader2.URL} Error : remote patch manifest content is invalid"; } } _downloader2.Dispose(); } if (_steps == ESteps.InitVerifyingCache) { InitVerifyingCache(); _verifyTime = UnityEngine.Time.realtimeSinceStartup; _steps = ESteps.UpdateVerifyingCache; } if (_steps == ESteps.UpdateVerifyingCache) { Progress = GetVerifyProgress(); if (UpdateVerifyingCache()) { _steps = ESteps.Done; Status = EOperationStatus.Succeed; float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyTime; YooLogger.Log($"Verify result : Success {_verifySuccessCount}, Fail {_verifyFailCount}, Elapsed time {costTime} seconds"); } } }
internal override void Start() { YooLogger.Log($"Begine to download : {TotalDownloadCount} files and {TotalDownloadBytes} bytes"); _steps = ESteps.Check; }
public void Update() { if (IsDone()) { return; } if (_steps == ESteps.LoadStaticVersion) { YooLogger.Log($"Load application static version."); string filePath = PathHelper.MakeStreamingLoadPath(YooAssetSettings.VersionFileName); string url = PathHelper.ConvertToWWWPath(filePath); _downloader1 = new UnityWebDataRequester(); _downloader1.SendRequest(url); _steps = ESteps.CheckStaticVersion; } if (_steps == ESteps.CheckStaticVersion) { if (_downloader1.IsDone() == false) { return; } if (_downloader1.HasError()) { Error = _downloader1.GetError(); _steps = ESteps.Failed; } else { _staticVersion = int.Parse(_downloader1.GetText()); _steps = ESteps.LoadAppManifest; } _downloader1.Dispose(); } if (_steps == ESteps.LoadAppManifest) { YooLogger.Log($"Load application patch manifest."); string filePath = PathHelper.MakeStreamingLoadPath(YooAssetSettingsData.GetPatchManifestFileName(_staticVersion)); string url = PathHelper.ConvertToWWWPath(filePath); _downloader2 = new UnityWebDataRequester(); _downloader2.SendRequest(url); _steps = ESteps.CheckAppManifest; } if (_steps == ESteps.CheckAppManifest) { if (_downloader2.IsDone() == false) { return; } if (_downloader2.HasError()) { Error = _downloader2.GetError(); _steps = ESteps.Failed; } else { // 解析APP里的补丁清单 Result = PatchManifest.Deserialize(_downloader2.GetText()); _steps = ESteps.Succeed; } _downloader2.Dispose(); } }