From 8ce8e8179202f3a3330cea7483297c53191a44c7 Mon Sep 17 00:00:00 2001 From: hevinci Date: Tue, 7 Feb 2023 18:39:08 +0800 Subject: [PATCH 1/2] update new cache system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重新设计了资源缓存系统 --- .../AssetBundleBuilder/BuildAssetInfo.cs | 2 +- .../Loader/AssetBundleFileLoader.cs | 17 +- .../Loader/AssetBundleWebLoader.cs | 15 +- .../AssetSystem/Loader/RawBundleFileLoader.cs | 6 +- Assets/YooAsset/Runtime/AssetsPackage.cs | 13 +- .../Runtime/CacheSystem/CacheFileInfo.cs | 12 + ...rifyInfo.cs.meta => CacheFileInfo.cs.meta} | 2 +- .../Runtime/CacheSystem/CacheSystem.cs | 173 ++++++----- .../Runtime/CacheSystem/EVerifyResult.cs | 13 +- .../Runtime/CacheSystem/Operations.meta | 8 + .../ClearUnusedCacheFilesOperation.cs | 71 +++++ .../ClearUnusedCacheFilesOperation.cs.meta | 0 .../Operations/PackageCachingOperation.cs | 80 +++++ .../PackageCachingOperation.cs.meta} | 2 +- .../Operations/PackageVerifyOperation.cs | 258 +++++++++++++++ .../PackageVerifyOperation.cs.meta} | 0 .../Runtime/CacheSystem/PackageCache.cs | 103 ++++++ .../Runtime/CacheSystem/PackageCache.cs.meta | 11 + .../Runtime/CacheSystem/VerifyElement.cs | 25 ++ .../Runtime/CacheSystem/VerifyElement.cs.meta | 11 + .../Runtime/CacheSystem/VerifyInfo.cs | 33 -- .../Runtime/DownloadSystem/DownloadSystem.cs | 8 +- .../Downloader/DownloaderBase.cs | 6 +- .../Downloader/FileDownloader.cs | 76 +++-- .../CheckPackageContentsOperation.cs | 150 --------- .../ClearUnusedCacheFilesOperation.cs | 104 ------- .../Operations/InitializationOperation.cs | 43 ++- .../Internal/VerifyPackageOperation.cs | 294 ------------------ .../UpdatePackageManifestOperation.cs | 26 +- .../Runtime/PatchSystem/PatchBundle.cs | 78 +++-- .../Runtime/PatchSystem/PatchManifest.cs | 4 +- .../Runtime/PatchSystem/PatchManifestTools.cs | 4 +- .../PlayMode/EditorSimulateModeImpl.cs | 6 - .../PatchSystem/PlayMode/HostPlayModeImpl.cs | 24 +- .../PlayMode/OfflinePlayModeImpl.cs | 8 +- .../Runtime/Services/IPlayModeServices.cs | 5 - .../Runtime/Settings/YooAssetSettings.cs | 4 +- .../Runtime/Settings/YooAssetSettingsData.cs | 4 +- 38 files changed, 858 insertions(+), 841 deletions(-) create mode 100644 Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs rename Assets/YooAsset/Runtime/CacheSystem/{VerifyInfo.cs.meta => CacheFileInfo.cs.meta} (83%) create mode 100644 Assets/YooAsset/Runtime/CacheSystem/Operations.meta create mode 100644 Assets/YooAsset/Runtime/CacheSystem/Operations/ClearUnusedCacheFilesOperation.cs rename Assets/YooAsset/Runtime/{PatchSystem => CacheSystem}/Operations/ClearUnusedCacheFilesOperation.cs.meta (100%) create mode 100644 Assets/YooAsset/Runtime/CacheSystem/Operations/PackageCachingOperation.cs rename Assets/YooAsset/Runtime/{PatchSystem/Operations/CheckPackageContentsOperation.cs.meta => CacheSystem/Operations/PackageCachingOperation.cs.meta} (83%) create mode 100644 Assets/YooAsset/Runtime/CacheSystem/Operations/PackageVerifyOperation.cs rename Assets/YooAsset/Runtime/{PatchSystem/Operations/Internal/VerifyPackageOperation.cs.meta => CacheSystem/Operations/PackageVerifyOperation.cs.meta} (100%) create mode 100644 Assets/YooAsset/Runtime/CacheSystem/PackageCache.cs create mode 100644 Assets/YooAsset/Runtime/CacheSystem/PackageCache.cs.meta create mode 100644 Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs create mode 100644 Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs.meta delete mode 100644 Assets/YooAsset/Runtime/CacheSystem/VerifyInfo.cs delete mode 100644 Assets/YooAsset/Runtime/PatchSystem/Operations/CheckPackageContentsOperation.cs delete mode 100644 Assets/YooAsset/Runtime/PatchSystem/Operations/ClearUnusedCacheFilesOperation.cs delete mode 100644 Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/VerifyPackageOperation.cs diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildAssetInfo.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildAssetInfo.cs index dd21a6e..e34abce 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildAssetInfo.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildAssetInfo.cs @@ -199,7 +199,7 @@ namespace YooAsset.Editor { if (IsRawAsset) { - string mainBundleName = $"{_mainBundleName}.{YooAssetSettingsData.Setting.RawFileVariant}"; + string mainBundleName = $"{_mainBundleName}.{YooAssetSettingsData.Setting.RawBundleFileVariant}"; _mainBundleName = mainBundleName.ToLower(); } else diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleFileLoader.cs b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleFileLoader.cs index 0ec9208..6fba180 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleFileLoader.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleFileLoader.cs @@ -46,7 +46,7 @@ namespace YooAsset if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote) { _steps = ESteps.Download; - FileLoadPath = MainBundleInfo.Bundle.CachedFilePath; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; } else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming) { @@ -55,7 +55,7 @@ namespace YooAsset if (loadMethod == EBundleLoadMethod.LoadFromMemory || loadMethod == EBundleLoadMethod.LoadFromStream) { _steps = ESteps.Unpack; - FileLoadPath = MainBundleInfo.Bundle.CachedFilePath; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; } else { @@ -70,7 +70,7 @@ namespace YooAsset else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache) { _steps = ESteps.LoadFile; - FileLoadPath = MainBundleInfo.Bundle.CachedFilePath; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; } else { @@ -242,14 +242,11 @@ namespace YooAsset // 在AssetBundle文件加载失败的情况下,我们需要重新验证文件的完整性! if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache) { - string cacheLoadPath = MainBundleInfo.Bundle.CachedFilePath; - if (CacheSystem.VerifyBundle(MainBundleInfo.Bundle, EVerifyLevel.High) != EVerifyResult.Succeed) + var result = CacheSystem.VerifyingRecordFile(MainBundleInfo.Bundle.PackageName, MainBundleInfo.Bundle.CacheGUID); + if (result != EVerifyResult.Succeed) { - if (File.Exists(cacheLoadPath)) - { - YooLogger.Error($"Delete the invalid cache file : {cacheLoadPath}"); - File.Delete(cacheLoadPath); - } + YooLogger.Error($"Found possibly corrupt file ! {MainBundleInfo.Bundle.CacheGUID}"); + CacheSystem.DiscardFile(MainBundleInfo.Bundle.PackageName, MainBundleInfo.Bundle.CacheGUID); } } } diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs index 5a68de7..8e2a3d6 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs @@ -47,7 +47,7 @@ namespace YooAsset if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote) { _steps = ESteps.Download; - FileLoadPath = MainBundleInfo.Bundle.CachedFilePath; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; } else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming) { @@ -57,7 +57,7 @@ namespace YooAsset else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache) { _steps = ESteps.LoadCacheFile; - FileLoadPath = MainBundleInfo.Bundle.CachedFilePath; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; } else { @@ -147,14 +147,11 @@ namespace YooAsset // 在AssetBundle文件加载失败的情况下,我们需要重新验证文件的完整性! if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache) { - string cacheLoadPath = MainBundleInfo.Bundle.CachedFilePath; - if (CacheSystem.VerifyBundle(MainBundleInfo.Bundle, EVerifyLevel.High) != EVerifyResult.Succeed) + var result = CacheSystem.VerifyingRecordFile(MainBundleInfo.Bundle.PackageName, MainBundleInfo.Bundle.CacheGUID); + if (result != EVerifyResult.Succeed) { - if (File.Exists(cacheLoadPath)) - { - YooLogger.Error($"Delete the invalid cache file : {cacheLoadPath}"); - File.Delete(cacheLoadPath); - } + YooLogger.Error($"Found possibly corrupt file ! {MainBundleInfo.Bundle.CacheGUID}"); + CacheSystem.DiscardFile(MainBundleInfo.Bundle.PackageName, MainBundleInfo.Bundle.CacheGUID); } } } diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/RawBundleFileLoader.cs b/Assets/YooAsset/Runtime/AssetSystem/Loader/RawBundleFileLoader.cs index cf6fa78..103b6eb 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Loader/RawBundleFileLoader.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/RawBundleFileLoader.cs @@ -38,13 +38,13 @@ namespace YooAsset if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote) { _steps = ESteps.Download; - FileLoadPath = MainBundleInfo.Bundle.CachedFilePath; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; } else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming) { #if UNITY_ANDROID || UNITY_WEBGL _steps = ESteps.Unpack; - FileLoadPath = MainBundleInfo.Bundle.CachedFilePath; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; #else _steps = ESteps.CheckFile; FileLoadPath = MainBundleInfo.Bundle.StreamingFilePath; @@ -53,7 +53,7 @@ namespace YooAsset else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache) { _steps = ESteps.CheckFile; - FileLoadPath = MainBundleInfo.Bundle.CachedFilePath; + FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath; } else { diff --git a/Assets/YooAsset/Runtime/AssetsPackage.cs b/Assets/YooAsset/Runtime/AssetsPackage.cs index a25b032..06f2361 100644 --- a/Assets/YooAsset/Runtime/AssetsPackage.cs +++ b/Assets/YooAsset/Runtime/AssetsPackage.cs @@ -229,15 +229,6 @@ namespace YooAsset return _playModeServices.PreDownloadPackageAsync(packageVersion, timeout); } - /// - /// 检查包裹内容的完整性 - /// - public CheckPackageContentsOperation CheckPackageContentsAsync(string packageVersion) - { - DebugCheckInitialize(); - return _playModeServices.CheckPackageContentsOperation(packageVersion); - } - /// /// 清理包裹未使用的缓存文件 /// @@ -731,12 +722,12 @@ namespace YooAsset /// /// 是否包含资源文件 /// - internal bool IsIncludeBundleFile(string fileName) + internal bool IsIncludeBundleFile(string cacheGUID) { // NOTE : 编辑器模拟模式下始终返回TRUE if (_playMode == EPlayMode.EditorSimulateMode) return true; - return _playModeServices.ActiveManifest.IsIncludeBundleFile(fileName); + return _playModeServices.ActiveManifest.IsIncludeBundleFile(cacheGUID); } /// diff --git a/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs b/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs new file mode 100644 index 0000000..8097b02 --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs @@ -0,0 +1,12 @@ +using System; +using System.IO; + +namespace YooAsset +{ + [Serializable] + internal class CacheFileInfo + { + public string FileCRC; + public long FileSize; + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/VerifyInfo.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/CacheSystem/VerifyInfo.cs.meta rename to Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs.meta index 4b66326..8d035ba 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/VerifyInfo.cs.meta +++ b/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a6296859f09655c4191594304ddf378f +guid: e4a97c06e069c1146a881fcb359f9b4b MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/CacheSystem/CacheSystem.cs b/Assets/YooAsset/Runtime/CacheSystem/CacheSystem.cs index 501cdc1..c7384ac 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/CacheSystem.cs +++ b/Assets/YooAsset/Runtime/CacheSystem/CacheSystem.cs @@ -2,19 +2,19 @@ using System.IO; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; namespace YooAsset { internal static class CacheSystem { - private readonly static Dictionary _cachedDic = new Dictionary(1000); + private readonly static Dictionary _cachedDic = new Dictionary(1000); /// /// 初始化时的验证级别 /// public static EVerifyLevel InitVerifyLevel { set; get; } = EVerifyLevel.Low; - /// /// 清空所有数据 /// @@ -25,103 +25,119 @@ namespace YooAsset /// /// 查询是否为验证文件 - /// 注意:被收录的文件完整性是绝对有效的 /// - public static bool IsCached(PatchBundle patchBundle) + public static bool IsCached(string packageName, string cacheGUID) { - string cacheKey = patchBundle.CacheKey; - if (_cachedDic.ContainsKey(cacheKey)) + var cache = GetOrCreateCache(packageName); + return cache.IsCached(cacheGUID); + } + + /// + /// 录入验证的文件 + /// + public static void RecordFile(string packageName, string cacheGUID, PackageCache.RecordWrapper wrapper) + { + var cache = GetOrCreateCache(packageName); + cache.Record(cacheGUID, wrapper); + } + + /// + /// 丢弃验证的文件(同时删除文件) + /// + public static void DiscardFile(string packageName, string cacheGUID) + { + var cache = GetOrCreateCache(packageName); + var wrapper = cache.TryGetWrapper(cacheGUID); + if (wrapper == null) + return; + + cache.Discard(cacheGUID); + + try { - string filePath = patchBundle.CachedFilePath; - if (File.Exists(filePath)) - { - return true; - } - else - { - _cachedDic.Remove(cacheKey); - YooLogger.Error($"Cache file is missing : {filePath}"); - return false; - } + string dataFilePath = wrapper.DataFilePath; + FileInfo fileInfo = new FileInfo(dataFilePath); + if (fileInfo.Exists) + fileInfo.Directory.Delete(true); } - else + catch (Exception e) { - return false; + YooLogger.Error($"Failed to delete cache file ! {e.Message}"); } } /// - /// 缓存补丁包文件 + /// 验证缓存文件(子线程内操作) /// - public static void CacheBundle(PatchBundle patchBundle) + public static EVerifyResult VerifyingCacheFile(VerifyElement element, EVerifyLevel verifyLevel) { - string cacheKey = patchBundle.CacheKey; - if (_cachedDic.ContainsKey(cacheKey) == false) + try { - string filePath = patchBundle.CachedFilePath; - YooLogger.Log($"Cache verify file : {filePath}"); - _cachedDic.Add(cacheKey, patchBundle); + string infoFilePath = element.InfoFilePath; + if (File.Exists(infoFilePath) == false) + return EVerifyResult.InfoFileNotExisted; + + // 解析信息文件获取验证数据 + string jsonContent = FileUtility.ReadAllText(infoFilePath); + CacheFileInfo fileInfo = UnityEngine.JsonUtility.FromJson(jsonContent); + element.DataFileCRC = fileInfo.FileCRC; + element.DataFileSize = fileInfo.FileSize; } - } - - /// - /// 验证补丁包文件 - /// - public static EVerifyResult VerifyBundle(PatchBundle patchBundle, EVerifyLevel verifyLevel) - { - return VerifyContentInternal(patchBundle.CachedFilePath, patchBundle.FileSize, patchBundle.FileCRC, verifyLevel); - } - - /// - /// 验证并缓存本地文件 - /// - public static EVerifyResult VerifyAndCacheLocalBundleFile(PatchBundle patchBundle, EVerifyLevel verifyLevel) - { - var verifyResult = VerifyContentInternal(patchBundle.CachedFilePath, patchBundle.FileSize, patchBundle.FileCRC, verifyLevel); - if (verifyResult == EVerifyResult.Succeed) - CacheBundle(patchBundle); - return verifyResult; - } - - /// - /// 验证并缓存下载文件 - /// - public static EVerifyResult VerifyAndCacheDownloadBundleFile(string tempFilePath, PatchBundle patchBundle, EVerifyLevel verifyLevel) - { - var verifyResult = VerifyContentInternal(tempFilePath, patchBundle.FileSize, patchBundle.FileCRC, verifyLevel); - if (verifyResult == EVerifyResult.Succeed) + catch (Exception) { - try - { - string destFilePath = patchBundle.CachedFilePath; - if (File.Exists(destFilePath)) - File.Delete(destFilePath); + return EVerifyResult.Exception; + } - FileInfo fileInfo = new FileInfo(tempFilePath); - fileInfo.MoveTo(destFilePath); - } - catch (Exception) - { - verifyResult = EVerifyResult.FileMoveFailed; - } + return VerifyingInternal(element.DataFilePath, element.DataFileSize, element.DataFileCRC, verifyLevel); + } - if (verifyResult == EVerifyResult.Succeed) + /// + /// 验证下载文件 + /// + public static EVerifyResult VerifyingTempFile(PatchBundle patchBundle, EVerifyLevel verifyLevel) + { + return VerifyingInternal(patchBundle.TempDataFilePath, patchBundle.FileSize, patchBundle.FileCRC, verifyLevel); + } + + /// + /// 验证记录文件 + /// + public static EVerifyResult VerifyingRecordFile(string packageName, string cacheGUID) + { + var cache = GetOrCreateCache(packageName); + var wrapper = cache.TryGetWrapper(cacheGUID); + if (wrapper == null) + return EVerifyResult.CacheNotFound; + + EVerifyResult result = VerifyingInternal(wrapper.DataFilePath, wrapper.DataFileSize, wrapper.DataFileCRC, EVerifyLevel.High); + return result; + } + + /// + /// 获取未被使用的缓存文件 + /// + public static List GetUnusedCacheGUIDs(AssetsPackage package) + { + var cache = GetOrCreateCache(package.PackageName); + var keys = cache.GetAllKeys(); + List result = new List(keys.Count); + foreach (var cacheGUID in keys) + { + if (package.IsIncludeBundleFile(cacheGUID) == false) { - CacheBundle(patchBundle); + result.Add(cacheGUID); } } - return verifyResult; + return result; } - /// - /// 验证文件完整性 - /// - private static EVerifyResult VerifyContentInternal(string filePath, long fileSize, string fileCRC, EVerifyLevel verifyLevel) + + private static EVerifyResult VerifyingInternal(string filePath, long fileSize, string fileCRC, EVerifyLevel verifyLevel) { try { if (File.Exists(filePath) == false) - return EVerifyResult.FileNotExisted; + return EVerifyResult.DataFileNotExisted; // 先验证文件大小 long size = FileUtility.GetFileSize(filePath); @@ -149,5 +165,14 @@ namespace YooAsset return EVerifyResult.Exception; } } + private static PackageCache GetOrCreateCache(string packageName) + { + if (_cachedDic.TryGetValue(packageName, out PackageCache cache) == false) + { + cache = new PackageCache(packageName); + _cachedDic.Add(packageName, cache); + } + return cache; + } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs b/Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs index 8179f08..a1dd0a0 100644 --- a/Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs +++ b/Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs @@ -7,14 +7,19 @@ namespace YooAsset internal enum EVerifyResult { /// - /// 文件不存在 + /// 未找到缓存信息 /// - FileNotExisted = -5, + CacheNotFound = -6, /// - /// 文件移动失败(重命名失败) + /// 信息文件不存在 /// - FileMoveFailed = -4, + InfoFileNotExisted = -5, + + /// + /// 数据文件不存在 + /// + DataFileNotExisted = -4, /// /// 文件内容不足(小于正常大小) diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operations.meta b/Assets/YooAsset/Runtime/CacheSystem/Operations.meta new file mode 100644 index 0000000..9b6ba5b --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/Operations.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d29a9623b2b346e439b7a7e37fafa781 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operations/ClearUnusedCacheFilesOperation.cs b/Assets/YooAsset/Runtime/CacheSystem/Operations/ClearUnusedCacheFilesOperation.cs new file mode 100644 index 0000000..1fe3bdd --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/Operations/ClearUnusedCacheFilesOperation.cs @@ -0,0 +1,71 @@ +using System.Collections; +using System.Collections.Generic; +using System.IO; + +namespace YooAsset +{ + /// + /// 清理本地包裹未使用的缓存文件 + /// + public sealed class ClearUnusedCacheFilesOperation : AsyncOperationBase + { + private enum ESteps + { + None, + GetUnusedCacheFiles, + ClearUnusedCacheFiles, + Done, + } + + private readonly AssetsPackage _package; + private List _unusedCacheGUIDs; + private int _unusedFileTotalCount = 0; + private ESteps _steps = ESteps.None; + + internal ClearUnusedCacheFilesOperation(AssetsPackage package) + { + _package = package; + } + internal override void Start() + { + _steps = ESteps.GetUnusedCacheFiles; + } + internal override void Update() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.GetUnusedCacheFiles) + { + _unusedCacheGUIDs = CacheSystem.GetUnusedCacheGUIDs(_package); + _unusedFileTotalCount = _unusedCacheGUIDs.Count; + YooLogger.Log($"Found unused cache file count : {_unusedFileTotalCount}"); + _steps = ESteps.ClearUnusedCacheFiles; + } + + if (_steps == ESteps.ClearUnusedCacheFiles) + { + for (int i = _unusedCacheGUIDs.Count - 1; i >= 0; i--) + { + string cacheGUID = _unusedCacheGUIDs[i]; + CacheSystem.DiscardFile(_package.PackageName, cacheGUID); + _unusedCacheGUIDs.RemoveAt(i); + + if (OperationSystem.IsBusy) + break; + } + + if (_unusedFileTotalCount == 0) + Progress = 1.0f; + else + Progress = 1.0f - (_unusedCacheGUIDs.Count / _unusedFileTotalCount); + + if (_unusedCacheGUIDs.Count == 0) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/ClearUnusedCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/Operations/ClearUnusedCacheFilesOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/ClearUnusedCacheFilesOperation.cs.meta rename to Assets/YooAsset/Runtime/CacheSystem/Operations/ClearUnusedCacheFilesOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operations/PackageCachingOperation.cs b/Assets/YooAsset/Runtime/CacheSystem/Operations/PackageCachingOperation.cs new file mode 100644 index 0000000..844ed5e --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/Operations/PackageCachingOperation.cs @@ -0,0 +1,80 @@ +using System; +using System.IO; +using System.Collections; +using System.Collections.Generic; + +namespace YooAsset +{ + internal class PackageCachingOperation : AsyncOperationBase + { + private enum ESteps + { + None, + GetCacheFiles, + VerifyCacheFiles, + Done, + } + + private readonly string _packageName; + private PackageVerifyOperation _packageVerifyOp; + private ESteps _steps = ESteps.None; + + public PackageCachingOperation(string packageName) + { + _packageName = packageName; + } + internal override void Start() + { + _steps = ESteps.GetCacheFiles; + } + internal override void Update() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.GetCacheFiles) + { + var elements = GetVerifyElements(); + _packageVerifyOp = PackageVerifyOperation.CreateOperation(elements); + OperationSystem.StartOperation(_packageVerifyOp); + _steps = ESteps.VerifyCacheFiles; + } + + if (_steps == ESteps.VerifyCacheFiles) + { + Progress = _packageVerifyOp.Progress; + if (_packageVerifyOp.IsDone == false) + return; + + // 注意:总是返回成功 + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + + private List GetVerifyElements() + { + string cacheFolderPath = PersistentHelper.GetCacheFolderPath(_packageName); + if (Directory.Exists(cacheFolderPath) == false) + return new List(); + + DirectoryInfo rootDirectory = new DirectoryInfo(cacheFolderPath); + DirectoryInfo[] fileFolders = rootDirectory.GetDirectories(); + List result = new List(fileFolders.Length); + foreach (var fileFoder in fileFolders) + { + string cacheGUID = fileFoder.Name; + if (CacheSystem.IsCached(_packageName, cacheGUID)) + continue; + + string fileRootPath = fileFoder.FullName; + string dataFilePath = $"{fileRootPath}/{ YooAssetSettings.CacheBundleDataFileName}"; + string infoFilePath = $"{fileRootPath}/{ YooAssetSettings.CacheBundleInfoFileName}"; + VerifyElement element = new VerifyElement(_packageName, cacheGUID, fileRootPath, dataFilePath, infoFilePath); + result.Add(element); + } + + return result; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/CheckPackageContentsOperation.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/Operations/PackageCachingOperation.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/CheckPackageContentsOperation.cs.meta rename to Assets/YooAsset/Runtime/CacheSystem/Operations/PackageCachingOperation.cs.meta index b128bc4..e7c542e 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/Operations/CheckPackageContentsOperation.cs.meta +++ b/Assets/YooAsset/Runtime/CacheSystem/Operations/PackageCachingOperation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 3d400b2548d79ca42bec7370f5d66b78 +guid: 4ff95e7516dbfa148b4fe16eaab783fb MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operations/PackageVerifyOperation.cs b/Assets/YooAsset/Runtime/CacheSystem/Operations/PackageVerifyOperation.cs new file mode 100644 index 0000000..3bdcfa7 --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/Operations/PackageVerifyOperation.cs @@ -0,0 +1,258 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Threading; + +namespace YooAsset +{ + internal abstract class PackageVerifyOperation : AsyncOperationBase + { + public static PackageVerifyOperation CreateOperation(List elements) + { +#if UNITY_WEBGL + var operation = new PackageVerifyWithoutThreadOperation(elements); +#else + var operation = new PackageVerifyWithThreadOperation(elements); +#endif + return operation; + } + } + + /// + /// 本地缓存文件验证(线程版) + /// + internal class PackageVerifyWithThreadOperation : PackageVerifyOperation + { + private enum ESteps + { + None, + InitVerify, + UpdateVerify, + Done, + } + + private readonly ThreadSyncContext _syncContext = new ThreadSyncContext(); + private List _waitingList; + private List _verifyingList; + private int _verifyMaxNum; + private int _verifyTotalCount; + private float _verifyStartTime; + private int _succeedCount; + private int _failedCount; + private ESteps _steps = ESteps.None; + + public PackageVerifyWithThreadOperation(List elements) + { + _waitingList = elements; + } + internal override void Start() + { + _steps = ESteps.InitVerify; + _verifyStartTime = UnityEngine.Time.realtimeSinceStartup; + } + internal override void Update() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.InitVerify) + { + int fileCount = _waitingList.Count; + + // 设置同时验证的最大数 + ThreadPool.GetMaxThreads(out int workerThreads, out int ioThreads); + YooLogger.Log($"Work threads : {workerThreads}, IO threads : {ioThreads}"); + _verifyMaxNum = Math.Min(workerThreads, ioThreads); + _verifyTotalCount = fileCount; + if (_verifyMaxNum < 1) + _verifyMaxNum = 1; + + _verifyingList = new List(_verifyMaxNum); + _steps = ESteps.UpdateVerify; + } + + if (_steps == ESteps.UpdateVerify) + { + _syncContext.Update(); + + Progress = GetProgress(); + if (_waitingList.Count == 0 && _verifyingList.Count == 0) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime; + YooLogger.Log($"Package verify elapsed time {costTime:f1} seconds"); + } + + for (int i = _waitingList.Count - 1; i >= 0; i--) + { + if (OperationSystem.IsBusy) + break; + + if (_verifyingList.Count >= _verifyMaxNum) + break; + + var element = _waitingList[i]; + if (BeginVerifyFileWithThread(element)) + { + _waitingList.RemoveAt(i); + _verifyingList.Add(element); + } + else + { + YooLogger.Warning("The thread pool is failed queued."); + break; + } + } + } + } + + private float GetProgress() + { + if (_verifyTotalCount == 0) + return 1f; + return (float)(_succeedCount + _failedCount) / _verifyTotalCount; + } + private bool BeginVerifyFileWithThread(VerifyElement element) + { + return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element); + } + private void VerifyInThread(object obj) + { + VerifyElement element = (VerifyElement)obj; + element.Result = CacheSystem.VerifyingCacheFile(element, CacheSystem.InitVerifyLevel); + _syncContext.Post(VerifyCallback, element); + } + private void VerifyCallback(object obj) + { + VerifyElement element = (VerifyElement)obj; + _verifyingList.Remove(element); + + if (element.Result == EVerifyResult.Succeed) + { + _succeedCount++; + var wrapper = new PackageCache.RecordWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize); + CacheSystem.RecordFile(element.PackageName, element.CacheGUID, wrapper); + } + else + { + _failedCount++; + + // 删除验证失败的缓存文件 + if (Directory.Exists(element.FileRootPath)) + { + YooLogger.Warning($"Failed verify file and delete files : {element.FileRootPath}"); + Directory.Delete(element.FileRootPath, true); + } + } + } + } + + /// + /// 本地缓存文件验证(非线程版) + /// + internal class PackageVerifyWithoutThreadOperation : PackageVerifyOperation + { + private enum ESteps + { + None, + InitVerify, + UpdateVerify, + Done, + } + + private List _waitingList; + private List _verifyingList; + private int _verifyMaxNum; + private int _verifyTotalCount; + private float _verifyStartTime; + private int _succeedCount; + private int _failedCount; + private ESteps _steps = ESteps.None; + + public PackageVerifyWithoutThreadOperation(List elements) + { + _waitingList = elements; + } + internal override void Start() + { + _steps = ESteps.InitVerify; + _verifyStartTime = UnityEngine.Time.realtimeSinceStartup; + } + internal override void Update() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.InitVerify) + { + int fileCount = _waitingList.Count; + + // 设置同时验证的最大数 + _verifyMaxNum = fileCount; + _verifyTotalCount = fileCount; + + _verifyingList = new List(_verifyMaxNum); + _steps = ESteps.UpdateVerify; + } + + if (_steps == ESteps.UpdateVerify) + { + Progress = GetProgress(); + if (_waitingList.Count == 0 && _verifyingList.Count == 0) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime; + YooLogger.Log($"Package verify elapsed time {costTime:f1} seconds"); + } + + for (int i = _waitingList.Count - 1; i >= 0; i--) + { + if (OperationSystem.IsBusy) + break; + + if (_verifyingList.Count >= _verifyMaxNum) + break; + + var element = _waitingList[i]; + BeginVerifyFileWithoutThread(element); + _waitingList.RemoveAt(i); + _verifyingList.Add(element); + } + + // 主线程内验证,可以清空列表 + _verifyingList.Clear(); + } + } + + private float GetProgress() + { + if (_verifyTotalCount == 0) + return 1f; + return (float)(_succeedCount + _failedCount) / _verifyTotalCount; + } + private void BeginVerifyFileWithoutThread(VerifyElement element) + { + element.Result = CacheSystem.VerifyingCacheFile(element, CacheSystem.InitVerifyLevel); + if (element.Result == EVerifyResult.Succeed) + { + _succeedCount++; + var wrapper = new PackageCache.RecordWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize); + CacheSystem.RecordFile(element.PackageName, element.CacheGUID, wrapper); + } + else + { + _failedCount++; + + // 删除验证失败的缓存文件 + if (Directory.Exists(element.FileRootPath)) + { + YooLogger.Warning($"Failed verify file and delete files : {element.FileRootPath}"); + Directory.Delete(element.FileRootPath, true); + } + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/VerifyPackageOperation.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/Operations/PackageVerifyOperation.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/VerifyPackageOperation.cs.meta rename to Assets/YooAsset/Runtime/CacheSystem/Operations/PackageVerifyOperation.cs.meta diff --git a/Assets/YooAsset/Runtime/CacheSystem/PackageCache.cs b/Assets/YooAsset/Runtime/CacheSystem/PackageCache.cs new file mode 100644 index 0000000..be42a41 --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/PackageCache.cs @@ -0,0 +1,103 @@ +using System; +using System.IO; +using System.Collections; +using System.Collections.Generic; + +namespace YooAsset +{ + internal class PackageCache + { + internal class RecordWrapper + { + public string InfoFilePath { private set; get; } + public string DataFilePath { private set; get; } + public string DataFileCRC { private set; get; } + public long DataFileSize { private set; get; } + + public RecordWrapper(string infoFilePath, string dataFilePath, string dataFileCRC, long dataFileSize) + { + InfoFilePath = infoFilePath; + DataFilePath = dataFilePath; + DataFileCRC = dataFileCRC; + DataFileSize = dataFileSize; + } + } + + private readonly Dictionary _wrappers = new Dictionary(); + + /// + /// 包裹名称 + /// + public string PackageName { private set; get; } + + + public PackageCache(string packageName) + { + PackageName = packageName; + } + + /// + /// 清空所有数据 + /// + public void ClearAll() + { + _wrappers.Clear(); + } + + /// + /// 查询缓存记录 + /// + public bool IsCached(string cacheGUID) + { + return _wrappers.ContainsKey(cacheGUID); + } + + /// + /// 记录验证结果 + /// + public void Record(string cacheGUID, RecordWrapper wrapper) + { + if (_wrappers.ContainsKey(cacheGUID) == false) + { + _wrappers.Add(cacheGUID, wrapper); + } + else + { + throw new Exception("Should never get here !"); + } + } + + /// + /// 丢弃验证结果 + /// + public void Discard(string cacheGUID) + { + if (_wrappers.ContainsKey(cacheGUID)) + { + _wrappers.Remove(cacheGUID); + } + } + + /// + /// 获取记录对象 + /// + public RecordWrapper TryGetWrapper(string cacheGUID) + { + if (_wrappers.TryGetValue(cacheGUID, out RecordWrapper value)) + return value; + else + return null; + } + + internal List GetAllKeys() + { + List keys = new List(_wrappers.Keys.Count); + var keyCollection = _wrappers.Keys; + foreach (var key in keyCollection) + { + keys.Add(key); + } + return keys; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/PackageCache.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/PackageCache.cs.meta new file mode 100644 index 0000000..54c9bad --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/PackageCache.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 08f3e92fdbd5d56459d8882be1f54f60 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs b/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs new file mode 100644 index 0000000..493cec1 --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs @@ -0,0 +1,25 @@ + +namespace YooAsset +{ + internal class VerifyElement + { + public string PackageName { private set; get; } + public string CacheGUID { private set; get; } + public string FileRootPath { private set; get; } + public string DataFilePath { private set; get; } + public string InfoFilePath { private set; get; } + + public EVerifyResult Result; + public string DataFileCRC; + public long DataFileSize; + + public VerifyElement(string packageName, string cacheGUID, string fileRootPath, string dataFilePath, string infoFilePath) + { + PackageName = packageName; + CacheGUID = cacheGUID; + FileRootPath = fileRootPath; + DataFilePath = dataFilePath; + InfoFilePath = infoFilePath; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs.meta new file mode 100644 index 0000000..8cb15ad --- /dev/null +++ b/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5a4b96484bd701f4289b2f74c38abaa8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/CacheSystem/VerifyInfo.cs b/Assets/YooAsset/Runtime/CacheSystem/VerifyInfo.cs deleted file mode 100644 index c958fbb..0000000 --- a/Assets/YooAsset/Runtime/CacheSystem/VerifyInfo.cs +++ /dev/null @@ -1,33 +0,0 @@ - -namespace YooAsset -{ - internal class VerifyInfo - { - /// - /// 验证的资源文件是否为内置资源 - /// - public bool IsBuildinFile { private set; get; } - - /// - /// 验证的资源包实例 - /// - public PatchBundle VerifyBundle { private set; get; } - - /// - /// 验证的文件路径 - /// - public string VerifyFilePath { private set; get; } - - /// - /// 验证结果 - /// - public EVerifyResult Result; - - public VerifyInfo(bool isBuildinFile, PatchBundle verifyBundle) - { - IsBuildinFile = isBuildinFile; - VerifyBundle = verifyBundle; - VerifyFilePath = verifyBundle.CachedFilePath; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystem.cs b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystem.cs index 9459c41..83321d7 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystem.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystem.cs @@ -77,13 +77,13 @@ namespace YooAsset public static DownloaderBase BeginDownload(BundleInfo bundleInfo, int failedTryAgain, int timeout = 60) { // 查询存在的下载器 - if (_downloaderDic.TryGetValue(bundleInfo.Bundle.CachedFilePath, out var downloader)) + if (_downloaderDic.TryGetValue(bundleInfo.Bundle.CachedDataFilePath, out var downloader)) { return downloader; } // 如果资源已经缓存 - if (CacheSystem.IsCached(bundleInfo.Bundle)) + if (CacheSystem.IsCached(bundleInfo.Bundle.PackageName, bundleInfo.Bundle.CacheGUID)) { var tempDownloader = new TempDownloader(bundleInfo); return tempDownloader; @@ -92,11 +92,11 @@ namespace YooAsset // 创建新的下载器 { YooLogger.Log($"Beginning to download file : {bundleInfo.Bundle.FileName} URL : {bundleInfo.RemoteMainURL}"); - FileUtility.CreateFileDirectory(bundleInfo.Bundle.CachedFilePath); + FileUtility.CreateFileDirectory(bundleInfo.Bundle.CachedDataFilePath); bool breakDownload = bundleInfo.Bundle.FileSize >= BreakpointResumeFileSize; DownloaderBase newDownloader = new FileDownloader(bundleInfo, breakDownload); newDownloader.SendRequest(failedTryAgain, timeout); - _downloaderDic.Add(bundleInfo.Bundle.CachedFilePath, newDownloader); + _downloaderDic.Add(bundleInfo.Bundle.CachedDataFilePath, newDownloader); return newDownloader; } } diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs index 188d408..8bb039d 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs @@ -6,13 +6,13 @@ namespace YooAsset protected enum ESteps { None, - CheckLocalFile, CheckTempFile, PrepareDownload, CreateResumeDownloader, CreateGeneralDownloader, CheckDownload, - VerifyDownload, + VerifyingFile, + CachingFile, TryAgain, Succeed, Failed, @@ -60,7 +60,7 @@ namespace YooAsset { _failedTryAgain = failedTryAgain; _timeout = timeout; - _steps = ESteps.CheckLocalFile; + _steps = ESteps.CheckTempFile; } } public abstract void Update(); diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs index 20b282e..9fab6be 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs @@ -25,7 +25,7 @@ namespace YooAsset public FileDownloader(BundleInfo bundleInfo, bool breakResume) : base(bundleInfo) { _breakResume = breakResume; - _tempFilePath = bundleInfo.Bundle.CachedFilePath + ".temp"; + _tempFilePath = bundleInfo.Bundle.TempDataFilePath; } public override void Update() { @@ -34,29 +34,13 @@ namespace YooAsset if (IsDone()) return; - // 检测本地正式文件 - if (_steps == ESteps.CheckLocalFile) - { - var verifyResult = CacheSystem.VerifyAndCacheLocalBundleFile(_bundleInfo.Bundle, CacheSystem.InitVerifyLevel); - if (verifyResult == EVerifyResult.Succeed) - { - _steps = ESteps.Succeed; - } - else - { - if (File.Exists(_bundleInfo.Bundle.CachedFilePath)) - File.Delete(_bundleInfo.Bundle.CachedFilePath); - _steps = ESteps.CheckTempFile; - } - } - // 检测本地临时文件 if (_steps == ESteps.CheckTempFile) { - var verifyResult = CacheSystem.VerifyAndCacheDownloadBundleFile(_tempFilePath, _bundleInfo.Bundle, EVerifyLevel.High); + var verifyResult = CacheSystem.VerifyingTempFile(_bundleInfo.Bundle, EVerifyLevel.High); if (verifyResult == EVerifyResult.Succeed) { - _steps = ESteps.Succeed; + _steps = ESteps.CachingFile; } else { @@ -94,9 +78,7 @@ namespace YooAsset if (_steps == ESteps.CreateGeneralDownloader) { if (File.Exists(_tempFilePath)) - { File.Delete(_tempFilePath); - } _webRequest = new UnityWebRequest(_requestURL, UnityWebRequest.kHttpVerbGET); DownloadHandlerFile handler = new DownloadHandlerFile(_tempFilePath); @@ -206,7 +188,7 @@ namespace YooAsset } else { - _steps = ESteps.VerifyDownload; + _steps = ESteps.VerifyingFile; } // 释放下载器 @@ -214,23 +196,55 @@ namespace YooAsset } // 验证下载文件 - if (_steps == ESteps.VerifyDownload) + if (_steps == ESteps.VerifyingFile) { - var verifyResult = CacheSystem.VerifyAndCacheDownloadBundleFile(_tempFilePath, _bundleInfo.Bundle, EVerifyLevel.High); + var verifyResult = CacheSystem.VerifyingTempFile(_bundleInfo.Bundle, EVerifyLevel.High); if (verifyResult == EVerifyResult.Succeed) { + _steps = ESteps.CachingFile; + } + else + { + _lastError = $"Failed to verifying file : {_bundleInfo.Bundle.FileName}, ErrorCode : {verifyResult}"; + + // 注意:验证失败后删除文件 + if (File.Exists(_tempFilePath)) + File.Delete(_tempFilePath); + + _steps = ESteps.TryAgain; + } + } + + // 缓存下载文件 + if (_steps == ESteps.CachingFile) + { + try + { + string destFilePath = _bundleInfo.Bundle.CachedDataFilePath; + if (File.Exists(destFilePath)) + File.Delete(destFilePath); + + FileInfo fileInfo = new FileInfo(_tempFilePath); + fileInfo.MoveTo(destFilePath); + + // 写入信息文件记录验证数据 + CacheFileInfo cacheInfo = new CacheFileInfo(); + cacheInfo.FileCRC = _bundleInfo.Bundle.FileCRC; + cacheInfo.FileSize = _bundleInfo.Bundle.FileSize; + string jsonContent = UnityEngine.JsonUtility.ToJson(cacheInfo); + FileUtility.CreateFile(_bundleInfo.Bundle.CachedInfoFilePath, jsonContent); + + // 记录缓存文件 + var wrapper = new PackageCache.RecordWrapper(_bundleInfo.Bundle.CachedInfoFilePath, _bundleInfo.Bundle.CachedDataFilePath, _bundleInfo.Bundle.FileCRC, _bundleInfo.Bundle.FileSize); + CacheSystem.RecordFile(_bundleInfo.Bundle.PackageName, _bundleInfo.Bundle.CacheGUID, wrapper); + _lastError = string.Empty; _lastCode = 0; _steps = ESteps.Succeed; } - else + catch (Exception e) { - _lastError = $"Verify bundle content failed : {_bundleInfo.Bundle.FileName}"; - - // 验证失败后删除文件 - if (File.Exists(_tempFilePath)) - File.Delete(_tempFilePath); - + _lastError = e.Message; _steps = ESteps.TryAgain; } } diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/CheckPackageContentsOperation.cs b/Assets/YooAsset/Runtime/PatchSystem/Operations/CheckPackageContentsOperation.cs deleted file mode 100644 index f2e58a6..0000000 --- a/Assets/YooAsset/Runtime/PatchSystem/Operations/CheckPackageContentsOperation.cs +++ /dev/null @@ -1,150 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using System.IO; -using UnityEngine; - -namespace YooAsset -{ - /// - /// 检查包裹内容的完整性 - /// - public abstract class CheckPackageContentsOperation : AsyncOperationBase - { - } - - internal sealed class EditorSimulateModeCheckPackageContentsOperation : CheckPackageContentsOperation - { - internal EditorSimulateModeCheckPackageContentsOperation() - { - } - internal override void Start() - { - Status = EOperationStatus.Succeed; - } - internal override void Update() - { - } - } - internal sealed class OfflinePlayModeCheckPackageContentsOperation : CheckPackageContentsOperation - { - internal OfflinePlayModeCheckPackageContentsOperation() - { - } - internal override void Start() - { - Status = EOperationStatus.Succeed; - } - internal override void Update() - { - } - } - internal sealed class HostPlayModeCheckPackageContentsOperation : CheckPackageContentsOperation - { - private enum ESteps - { - None, - CheckActiveManifest, - LoadCacheManifest, - VerifyPackage, - Done, - } - - private readonly HostPlayModeImpl _impl; - private readonly string _packageName; - private readonly string _packageVersion; - private LoadCacheManifestOperation _loadCacheManifestOp; - private VerifyPackageOperation _verifyOperation; - private PatchManifest _verifyManifest; - private ESteps _steps = ESteps.None; - - internal HostPlayModeCheckPackageContentsOperation(HostPlayModeImpl impl, string packageName, string packageVersion) - { - _impl = impl; - _packageName = packageName; - _packageVersion = packageVersion; - } - internal override void Start() - { - _steps = ESteps.CheckActiveManifest; - } - internal override void Update() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.CheckActiveManifest) - { - // 检测当前激活的清单对象 - if (_impl.ActiveManifest != null && _impl.ActiveManifest.PackageVersion == _packageVersion) - { - _verifyManifest = _impl.ActiveManifest; - _steps = ESteps.VerifyPackage; - } - else - { - _steps = ESteps.LoadCacheManifest; - } - } - - if (_steps == ESteps.LoadCacheManifest) - { - if (_loadCacheManifestOp == null) - { - _loadCacheManifestOp = new LoadCacheManifestOperation(_packageName, _packageVersion); - OperationSystem.StartOperation(_loadCacheManifestOp); - } - - if (_loadCacheManifestOp.IsDone == false) - return; - - if (_loadCacheManifestOp.Status == EOperationStatus.Succeed) - { - _verifyManifest = _loadCacheManifestOp.Manifest; - _steps = ESteps.VerifyPackage; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _loadCacheManifestOp.Error; - } - } - - if (_steps == ESteps.VerifyPackage) - { - if (_verifyOperation == null) - { - _verifyOperation = VerifyPackageOperation.CreateOperation(_verifyManifest, _impl); - OperationSystem.StartOperation(_verifyOperation); - } - - Progress = _verifyOperation.Progress; - if (_verifyOperation.IsDone == false) - return; - - bool verifySucceed = true; - foreach (var verifyInfo in _verifyOperation.VerifyFailList) - { - // 注意:跳过内置资源文件 - if (verifyInfo.IsBuildinFile) - continue; - - verifySucceed = false; - YooLogger.Warning($"Failed verify file : {verifyInfo.VerifyFilePath}"); - } - - if (verifySucceed) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"The package resource {_packageName} content has verify failed file !"; - } - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/ClearUnusedCacheFilesOperation.cs b/Assets/YooAsset/Runtime/PatchSystem/Operations/ClearUnusedCacheFilesOperation.cs deleted file mode 100644 index 2255bdf..0000000 --- a/Assets/YooAsset/Runtime/PatchSystem/Operations/ClearUnusedCacheFilesOperation.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using System.IO; - -namespace YooAsset -{ - /// - /// 清理本地包裹未使用的缓存文件 - /// - public sealed class ClearUnusedCacheFilesOperation : AsyncOperationBase - { - private enum ESteps - { - None, - GetUnusedCacheFiles, - ClearUnusedCacheFiles, - Done, - } - - private readonly AssetsPackage _package; - private List _unusedCacheFilePaths; - private int _unusedFileTotalCount = 0; - private ESteps _steps = ESteps.None; - - internal ClearUnusedCacheFilesOperation(AssetsPackage package) - { - _package = package; - } - internal override void Start() - { - _steps = ESteps.GetUnusedCacheFiles; - } - internal override void Update() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.GetUnusedCacheFiles) - { - _unusedCacheFilePaths = GetUnusedCacheFilePaths(); - _unusedFileTotalCount = _unusedCacheFilePaths.Count; - YooLogger.Log($"Found unused cache file count : {_unusedFileTotalCount}"); - _steps = ESteps.ClearUnusedCacheFiles; - } - - if (_steps == ESteps.ClearUnusedCacheFiles) - { - for (int i = _unusedCacheFilePaths.Count - 1; i >= 0; i--) - { - string filePath = _unusedCacheFilePaths[i]; - if (File.Exists(filePath)) - { - try - { - File.Delete(filePath); - YooLogger.Log($"Delete unused cache file : {filePath}"); - } - catch (System.Exception e) - { - YooLogger.Warning($"Failed delete cache file : {filePath} ! {e.Message}"); - } - } - _unusedCacheFilePaths.RemoveAt(i); - - if (OperationSystem.IsBusy) - break; - } - - if (_unusedFileTotalCount == 0) - Progress = 1.0f; - else - Progress = 1.0f - (_unusedCacheFilePaths.Count / _unusedFileTotalCount); - - if (_unusedCacheFilePaths.Count == 0) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - } - } - - /// - /// 获取未被使用的缓存文件路径集合 - /// - private List GetUnusedCacheFilePaths() - { - string cacheFolderPath = PersistentHelper.GetCacheFolderPath(_package.PackageName); - if (Directory.Exists(cacheFolderPath) == false) - return new List(); - - DirectoryInfo directoryInfo = new DirectoryInfo(cacheFolderPath); - FileInfo[] fileInfos = directoryInfo.GetFiles(); - List result = new List(fileInfos.Length); - foreach (FileInfo fileInfo in fileInfos) - { - if (_package.IsIncludeBundleFile(fileInfo.Name) == false) - { - result.Add(fileInfo.FullName); - } - } - return result; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/InitializationOperation.cs b/Assets/YooAsset/Runtime/PatchSystem/Operations/InitializationOperation.cs index a2d9fdd..ba63581 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/Operations/InitializationOperation.cs +++ b/Assets/YooAsset/Runtime/PatchSystem/Operations/InitializationOperation.cs @@ -79,7 +79,7 @@ namespace YooAsset None, QueryBuildinPackageVersion, LoadBuildinManifest, - VerifyPackage, + PackageCaching, Done, } @@ -87,7 +87,7 @@ namespace YooAsset private readonly string _packageName; private QueryBuildinPackageVersionOperation _queryBuildinPackageVersionOp; private LoadBuildinManifestOperation _loadBuildinManifestOp; - private VerifyPackageOperation _verifyOperation; + private PackageCachingOperation _cachingOperation; private ESteps _steps = ESteps.None; internal OfflinePlayModeInitializationOperation(OfflinePlayModeImpl impl, string packageName) @@ -143,7 +143,7 @@ namespace YooAsset { PackageVersion = _loadBuildinManifestOp.Manifest.PackageVersion; _impl.ActiveManifest = _loadBuildinManifestOp.Manifest; - _steps = ESteps.VerifyPackage; + _steps = ESteps.PackageCaching; } else { @@ -153,16 +153,16 @@ namespace YooAsset } } - if (_steps == ESteps.VerifyPackage) + if (_steps == ESteps.PackageCaching) { - if (_verifyOperation == null) + if (_cachingOperation == null) { - _verifyOperation = VerifyPackageOperation.CreateOperation(_impl.ActiveManifest, _impl); - OperationSystem.StartOperation(_verifyOperation); + _cachingOperation = new PackageCachingOperation(_packageName); + OperationSystem.StartOperation(_cachingOperation); } - Progress = _verifyOperation.Progress; - if (_verifyOperation.IsDone) + Progress = _cachingOperation.Progress; + if (_cachingOperation.IsDone) { _steps = ESteps.Done; Status = EOperationStatus.Succeed; @@ -186,7 +186,7 @@ namespace YooAsset QueryBuildinPackageVersion, UnpackBuildinManifest, LoadBuildinManifest, - VerifyPackage, + PackageCaching, Done, } @@ -197,7 +197,7 @@ namespace YooAsset private UnpackBuildinManifestOperation _unpackBuildinManifestOp; private LoadBuildinManifestOperation _loadBuildinManifestOp; private LoadCacheManifestOperation _loadCacheManifestOp; - private VerifyPackageOperation _verifyOperation; + private PackageCachingOperation _cachingOperation; private ESteps _steps = ESteps.None; internal HostPlayModeInitializationOperation(HostPlayModeImpl impl, string packageName) @@ -265,7 +265,7 @@ namespace YooAsset { PackageVersion = _loadCacheManifestOp.Manifest.PackageVersion; _impl.ActiveManifest = _loadCacheManifestOp.Manifest; - _steps = ESteps.VerifyPackage; + _steps = ESteps.PackageCaching; } else { @@ -284,15 +284,14 @@ namespace YooAsset if (_queryBuildinPackageVersionOp.IsDone == false) return; - // 注意:为了兼容MOD模式,初始化动态新增的包裹的时候,如果内置清单不存在也不需要报错! if (_queryBuildinPackageVersionOp.Status == EOperationStatus.Succeed) { _steps = ESteps.UnpackBuildinManifest; } else { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; + // 注意:为了兼容MOD模式,初始化动态新增的包裹的时候,如果内置清单不存在也不需要报错! + _steps = ESteps.PackageCaching; string error = _queryBuildinPackageVersionOp.Error; YooLogger.Log($"Failed to load buildin package version file : {error}"); } @@ -337,7 +336,7 @@ namespace YooAsset { PackageVersion = _loadBuildinManifestOp.Manifest.PackageVersion; _impl.ActiveManifest = _loadBuildinManifestOp.Manifest; - _steps = ESteps.VerifyPackage; + _steps = ESteps.PackageCaching; } else { @@ -347,16 +346,16 @@ namespace YooAsset } } - if (_steps == ESteps.VerifyPackage) + if (_steps == ESteps.PackageCaching) { - if (_verifyOperation == null) + if (_cachingOperation == null) { - _verifyOperation = VerifyPackageOperation.CreateOperation(_impl.ActiveManifest, _impl); - OperationSystem.StartOperation(_verifyOperation); + _cachingOperation = new PackageCachingOperation(_packageName); + OperationSystem.StartOperation(_cachingOperation); } - Progress = _verifyOperation.Progress; - if (_verifyOperation.IsDone) + Progress = _cachingOperation.Progress; + if (_cachingOperation.IsDone) { _steps = ESteps.Done; Status = EOperationStatus.Succeed; diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/VerifyPackageOperation.cs b/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/VerifyPackageOperation.cs deleted file mode 100644 index 9f1af87..0000000 --- a/Assets/YooAsset/Runtime/PatchSystem/Operations/Internal/VerifyPackageOperation.cs +++ /dev/null @@ -1,294 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Threading; - -namespace YooAsset -{ - internal abstract class VerifyPackageOperation : AsyncOperationBase - { - public List VerifySuccessList { protected set; get; } - public List VerifyFailList { protected set; get; } - - public static VerifyPackageOperation CreateOperation(PatchManifest manifest, IPlayModeServices playModeServices) - { -#if UNITY_WEBGL - VerifyPackageOperation operation = new VerifyPackageWithoutThreadOperation(manifest, playModeServices); -#else - VerifyPackageOperation operation = new VerifyPackageWithThreadOperation(manifest, playModeServices); -#endif - return operation; - } - } - - /// - /// 本地缓存文件验证(线程版) - /// - internal class VerifyPackageWithThreadOperation : VerifyPackageOperation - { - private enum ESteps - { - None, - InitVerify, - PrepareVerify, - UpdateVerify, - Done, - } - - private readonly PatchManifest _manifest; - private readonly IPlayModeServices _playModeServices; - private readonly ThreadSyncContext _syncContext = new ThreadSyncContext(); - private List _waitingList; - private List _verifyingList; - private int _verifyMaxNum; - private int _verifyTotalCount; - private float _verifyStartTime; - private ESteps _steps = ESteps.None; - - public VerifyPackageWithThreadOperation(PatchManifest manifest, IPlayModeServices playModeServices) - { - _manifest = manifest; - _playModeServices = playModeServices; - } - internal override void Start() - { - _steps = ESteps.InitVerify; - _verifyStartTime = UnityEngine.Time.realtimeSinceStartup; - } - internal override void Update() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.InitVerify) - { - int bundleCount = _manifest.BundleList.Count; - VerifySuccessList = new List(bundleCount); - VerifyFailList = new List(bundleCount); - - // 设置同时验证的最大数 - ThreadPool.GetMaxThreads(out int workerThreads, out int ioThreads); - YooLogger.Log($"Work threads : {workerThreads}, IO threads : {ioThreads}"); - _verifyMaxNum = Math.Min(workerThreads, ioThreads); - _verifyTotalCount = bundleCount; - if (_verifyMaxNum < 1) - _verifyMaxNum = 1; - - _waitingList = new List(bundleCount); - _verifyingList = new List(_verifyMaxNum); - _steps = ESteps.PrepareVerify; - } - - if (_steps == ESteps.PrepareVerify) - { - foreach (var patchBundle in _manifest.BundleList) - { - if (CacheSystem.IsCached(patchBundle)) - continue; - - bool isBuildinFile = _playModeServices.IsBuildinPatchBundle(patchBundle); - VerifyInfo verifyInfo = new VerifyInfo(isBuildinFile, patchBundle); - _waitingList.Add(verifyInfo); - } - _steps = ESteps.UpdateVerify; - } - - if (_steps == ESteps.UpdateVerify) - { - _syncContext.Update(); - - Progress = GetVerifierProgress(); - if (_waitingList.Count == 0 && _verifyingList.Count == 0) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime; - YooLogger.Log($"Verify elapsed time {costTime:f1} seconds"); - } - - for (int i = _waitingList.Count - 1; i >= 0; i--) - { - if (OperationSystem.IsBusy) - break; - - if (_verifyingList.Count >= _verifyMaxNum) - break; - - var verifyIno = _waitingList[i]; - if (VerifyFileWithThread(verifyIno)) - { - _waitingList.RemoveAt(i); - _verifyingList.Add(verifyIno); - } - else - { - YooLogger.Warning("The thread pool is failed queued."); - break; - } - } - } - } - - private float GetVerifierProgress() - { - if (_verifyTotalCount == 0) - return 1f; - return (float)(VerifySuccessList.Count + VerifyFailList.Count) / _verifyTotalCount; - } - private bool VerifyFileWithThread(VerifyInfo verifyInfo) - { - return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), verifyInfo); - } - private void VerifyInThread(object infoObj) - { - VerifyInfo verifyInfo = (VerifyInfo)infoObj; - verifyInfo.Result = CacheSystem.VerifyBundle(verifyInfo.VerifyBundle, CacheSystem.InitVerifyLevel); - _syncContext.Post(VerifyCallback, verifyInfo); - } - private void VerifyCallback(object obj) - { - VerifyInfo verifyIno = (VerifyInfo)obj; - if (verifyIno.Result == EVerifyResult.Succeed) - { - VerifySuccessList.Add(verifyIno); - CacheSystem.CacheBundle(verifyIno.VerifyBundle); - } - else - { - VerifyFailList.Add(verifyIno); - - // 删除验证失败的缓存文件 - if (File.Exists(verifyIno.VerifyBundle.CachedFilePath)) - { - YooLogger.Warning($"Delete verify failed bundle file : {verifyIno.VerifyBundle.CachedFilePath}"); - File.Delete(verifyIno.VerifyBundle.CachedFilePath); - } - } - _verifyingList.Remove(verifyIno); - } - } - - /// - /// 本地缓存文件验证(非线程版) - /// - internal class VerifyPackageWithoutThreadOperation : VerifyPackageOperation - { - private enum ESteps - { - None, - InitVerify, - PrepareVerify, - UpdateVerify, - Done, - } - - private readonly PatchManifest _manifest; - private readonly IPlayModeServices _playModeServices; - private List _waitingList; - private List _verifyingList; - private int _verifyMaxNum; - private int _verifyTotalCount; - private float _verifyStartTime; - private ESteps _steps = ESteps.None; - - public VerifyPackageWithoutThreadOperation(PatchManifest manifest, IPlayModeServices playModeServices) - { - _manifest = manifest; - _playModeServices = playModeServices; - } - internal override void Start() - { - _steps = ESteps.InitVerify; - _verifyStartTime = UnityEngine.Time.realtimeSinceStartup; - } - internal override void Update() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.InitVerify) - { - int bundleCount = _manifest.BundleList.Count; - VerifySuccessList = new List(bundleCount); - VerifyFailList = new List(bundleCount); - - // 设置同时验证的最大数 - _verifyMaxNum = bundleCount; - _verifyTotalCount = bundleCount; - - _waitingList = new List(bundleCount); - _verifyingList = new List(_verifyMaxNum); - _steps = ESteps.PrepareVerify; - } - - if (_steps == ESteps.PrepareVerify) - { - foreach (var patchBundle in _manifest.BundleList) - { - if (CacheSystem.IsCached(patchBundle)) - continue; - - bool isBuildinFile = _playModeServices.IsBuildinPatchBundle(patchBundle); - VerifyInfo verifyInfo = new VerifyInfo(isBuildinFile, patchBundle); - _waitingList.Add(verifyInfo); - } - _steps = ESteps.UpdateVerify; - } - - if (_steps == ESteps.UpdateVerify) - { - Progress = GetVerifierProgress(); - if (_waitingList.Count == 0 && _verifyingList.Count == 0) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime; - YooLogger.Log($"Verify elapsed time {costTime:f1} seconds"); - } - - for (int i = _waitingList.Count - 1; i >= 0; i--) - { - if (OperationSystem.IsBusy) - break; - - if (_verifyingList.Count >= _verifyMaxNum) - break; - - var verifyIno = _waitingList[i]; - VerifyFileWithoutThread(verifyIno); - _waitingList.RemoveAt(i); - _verifyingList.Add(verifyIno); - } - - _verifyingList.Clear(); - } - } - - private float GetVerifierProgress() - { - if (_verifyTotalCount == 0) - return 1f; - return (float)(VerifySuccessList.Count + VerifyFailList.Count) / _verifyTotalCount; - } - private void VerifyFileWithoutThread(VerifyInfo verifyIno) - { - var verifyResult = CacheSystem.VerifyAndCacheLocalBundleFile(verifyIno.VerifyBundle, CacheSystem.InitVerifyLevel); - if (verifyResult == EVerifyResult.Succeed) - { - VerifySuccessList.Add(verifyIno); - } - else - { - VerifyFailList.Add(verifyIno); - - // 删除验证失败的缓存文件 - if (File.Exists(verifyIno.VerifyBundle.CachedFilePath)) - { - YooLogger.Warning($"Delete verify failed bundle file : {verifyIno.VerifyBundle.CachedFilePath}"); - File.Delete(verifyIno.VerifyBundle.CachedFilePath); - } - } - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/Operations/UpdatePackageManifestOperation.cs b/Assets/YooAsset/Runtime/PatchSystem/Operations/UpdatePackageManifestOperation.cs index 48654e1..4704eea 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/Operations/UpdatePackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/PatchSystem/Operations/UpdatePackageManifestOperation.cs @@ -47,7 +47,7 @@ namespace YooAsset /// /// 联机模式的更新清单操作 - /// 注意:优先加载沙盒里缓存的清单文件,如果有变化就更新远端清单文件,并保存到本地。 + /// 注意:优先加载沙盒里缓存的清单文件,如果缓存没找到就下载远端清单文件,并保存到本地。 /// internal sealed class HostPlayModeUpdatePackageManifestOperation : UpdatePackageManifestOperation { @@ -59,7 +59,6 @@ namespace YooAsset DownloadManifest, LoadCacheManifest, CheckDeserializeManifest, - VerifyPackage, Done, } @@ -70,7 +69,6 @@ namespace YooAsset private LoadCacheManifestOperation _tryLoadCacheManifestOp; private LoadCacheManifestOperation _loadCacheManifestOp; private DownloadManifestOperation _downloadManifestOp; - private VerifyPackageOperation _verifyOperation; private ESteps _steps = ESteps.None; @@ -118,7 +116,8 @@ namespace YooAsset if (_tryLoadCacheManifestOp.Status == EOperationStatus.Succeed) { _impl.ActiveManifest = _tryLoadCacheManifestOp.Manifest; - _steps = ESteps.VerifyPackage; + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; } else { @@ -163,7 +162,8 @@ namespace YooAsset if (_loadCacheManifestOp.Status == EOperationStatus.Succeed) { _impl.ActiveManifest = _loadCacheManifestOp.Manifest; - _steps = ESteps.VerifyPackage; + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; } else { @@ -172,22 +172,6 @@ namespace YooAsset Error = _loadCacheManifestOp.Error; } } - - if (_steps == ESteps.VerifyPackage) - { - if (_verifyOperation == null) - { - _verifyOperation = VerifyPackageOperation.CreateOperation(_impl.ActiveManifest, _impl); - OperationSystem.StartOperation(_verifyOperation); - } - - Progress = _verifyOperation.Progress; - if (_verifyOperation.IsDone) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - } } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/PatchSystem/PatchBundle.cs b/Assets/YooAsset/Runtime/PatchSystem/PatchBundle.cs index 4b6b7de..fb017fe 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/PatchBundle.cs +++ b/Assets/YooAsset/Runtime/PatchSystem/PatchBundle.cs @@ -45,22 +45,63 @@ namespace YooAsset /// /// 所属的包裹名称 /// - private string _packageName; + public string PackageName { private set; get; } /// - /// 缓存文件路径 + /// 缓存GUID /// - private string _cachedFilePath; - public string CachedFilePath + public string CacheGUID + { + get { return FileHash; } + } + + /// + /// 缓存的数据文件路径 + /// + private string _cachedDataFilePath; + public string CachedDataFilePath { get { - if (string.IsNullOrEmpty(_cachedFilePath) == false) - return _cachedFilePath; + if (string.IsNullOrEmpty(_cachedDataFilePath) == false) + return _cachedDataFilePath; - string cacheRoot = PersistentHelper.GetCacheFolderPath(_packageName); - _cachedFilePath = $"{cacheRoot}/{FileName}"; - return _cachedFilePath; + string cacheRoot = PersistentHelper.GetCacheFolderPath(PackageName); + _cachedDataFilePath = $"{cacheRoot}/{CacheGUID}/{YooAssetSettings.CacheBundleDataFileName}"; + return _cachedDataFilePath; + } + } + + /// + /// 缓存的信息文件路径 + /// + private string _cachedInfoFilePath; + public string CachedInfoFilePath + { + get + { + if (string.IsNullOrEmpty(_cachedInfoFilePath) == false) + return _cachedInfoFilePath; + + string cacheRoot = PersistentHelper.GetCacheFolderPath(PackageName); + _cachedInfoFilePath = $"{cacheRoot}/{CacheGUID}/{YooAssetSettings.CacheBundleInfoFileName}"; + return _cachedInfoFilePath; + } + } + + /// + /// 临时的数据文件路径 + /// + private string _tempDataFilePath; + public string TempDataFilePath + { + get + { + if (string.IsNullOrEmpty(_tempDataFilePath) == false) + return _tempDataFilePath; + + _tempDataFilePath = $"{CachedDataFilePath}.temp"; + return _tempDataFilePath; } } @@ -81,7 +122,7 @@ namespace YooAsset } /// - /// 文件名称 + /// 文件名称(远端文件名和内置文件名) /// private string _fileName; public string FileName @@ -94,20 +135,6 @@ namespace YooAsset } } - /// - /// 缓存查询Key - /// - private string _cacheKey; - public string CacheKey - { - get - { - if (string.IsNullOrEmpty(_cacheKey)) - throw new Exception("Should never get here !"); - return _cacheKey; - } - } - public PatchBundle() { @@ -118,8 +145,7 @@ namespace YooAsset /// public void ParseBundle(string packageName, int nameStype) { - _packageName = packageName; - _cacheKey = $"{packageName}-{FileHash}"; + PackageName = packageName; _fileName = PatchManifestTools.CreateBundleFileName(nameStype, BundleName, FileHash, IsRawFile); } diff --git a/Assets/YooAsset/Runtime/PatchSystem/PatchManifest.cs b/Assets/YooAsset/Runtime/PatchSystem/PatchManifest.cs index 44ce4d5..d892b54 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/PatchManifest.cs +++ b/Assets/YooAsset/Runtime/PatchSystem/PatchManifest.cs @@ -239,11 +239,11 @@ namespace YooAsset /// /// 是否包含资源文件 /// - public bool IsIncludeBundleFile(string fileName) + public bool IsIncludeBundleFile(string cacheGUID) { foreach (var patchBundle in BundleList) { - if (patchBundle.FileName == fileName) + if (patchBundle.CacheGUID == cacheGUID) return true; } return false; diff --git a/Assets/YooAsset/Runtime/PatchSystem/PatchManifestTools.cs b/Assets/YooAsset/Runtime/PatchSystem/PatchManifestTools.cs index 35790fa..9aa38ee 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/PatchManifestTools.cs +++ b/Assets/YooAsset/Runtime/PatchSystem/PatchManifestTools.cs @@ -159,13 +159,13 @@ namespace YooAsset { if (nameStyle == 1) //HashName { - string fileExtension = isRawFile ? YooAssetSettingsData.Setting.RawFileVariant : YooAssetSettingsData.Setting.AssetBundleFileVariant; + string fileExtension = isRawFile ? YooAssetSettingsData.Setting.RawBundleFileVariant : YooAssetSettingsData.Setting.AssetBundleFileVariant; return StringUtility.Format("{0}.{1}", fileHash, fileExtension); } else if (nameStyle == 4) //BundleName_HashName { string fileName = bundleName.Remove(bundleName.LastIndexOf('.')); - string fileExtension = isRawFile ? YooAssetSettingsData.Setting.RawFileVariant : YooAssetSettingsData.Setting.AssetBundleFileVariant; + string fileExtension = isRawFile ? YooAssetSettingsData.Setting.RawBundleFileVariant : YooAssetSettingsData.Setting.AssetBundleFileVariant; return StringUtility.Format("{0}_{1}.{2}", fileName, fileHash, fileExtension); } else diff --git a/Assets/YooAsset/Runtime/PatchSystem/PlayMode/EditorSimulateModeImpl.cs b/Assets/YooAsset/Runtime/PatchSystem/PlayMode/EditorSimulateModeImpl.cs index 72ff0ce..27e239f 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/PlayMode/EditorSimulateModeImpl.cs +++ b/Assets/YooAsset/Runtime/PatchSystem/PlayMode/EditorSimulateModeImpl.cs @@ -56,12 +56,6 @@ namespace YooAsset OperationSystem.StartOperation(operation); return operation; } - CheckPackageContentsOperation IPlayModeServices.CheckPackageContentsOperation(string packageVersion) - { - var operation = new EditorSimulateModeCheckPackageContentsOperation(); - OperationSystem.StartOperation(operation); - return operation; - } PatchDownloaderOperation IPlayModeServices.CreatePatchDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout) { diff --git a/Assets/YooAsset/Runtime/PatchSystem/PlayMode/HostPlayModeImpl.cs b/Assets/YooAsset/Runtime/PatchSystem/PlayMode/HostPlayModeImpl.cs index 85f19fa..53ecf73 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/PlayMode/HostPlayModeImpl.cs +++ b/Assets/YooAsset/Runtime/PatchSystem/PlayMode/HostPlayModeImpl.cs @@ -95,7 +95,11 @@ namespace YooAsset { return _queryServices.QueryStreamingAssets(patchBundle.FileName); } - + public bool IsCachedPatchBundle(PatchBundle patchBundle) + { + return CacheSystem.IsCached(patchBundle.PackageName, patchBundle.CacheGUID); + } + UpdatePackageVersionOperation IPlayModeServices.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout) { var operation = new HostPlayModeUpdatePackageVersionOperation(this, _packageName, appendTimeTicks, timeout); @@ -114,12 +118,6 @@ namespace YooAsset OperationSystem.StartOperation(operation); return operation; } - CheckPackageContentsOperation IPlayModeServices.CheckPackageContentsOperation(string packageVersion) - { - var operation = new HostPlayModeCheckPackageContentsOperation(this, _packageName, packageVersion); - OperationSystem.StartOperation(operation); - return operation; - } PatchDownloaderOperation IPlayModeServices.CreatePatchDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout) { @@ -133,7 +131,7 @@ namespace YooAsset foreach (var patchBundle in patchManifest.BundleList) { // 忽略缓存文件 - if (CacheSystem.IsCached(patchBundle)) + if (IsCachedPatchBundle(patchBundle)) continue; // 忽略APP资源 @@ -158,7 +156,7 @@ namespace YooAsset foreach (var patchBundle in patchManifest.BundleList) { // 忽略缓存文件 - if (CacheSystem.IsCached(patchBundle)) + if (IsCachedPatchBundle(patchBundle)) continue; // 忽略APP资源 @@ -219,7 +217,7 @@ namespace YooAsset foreach (var patchBundle in checkList) { // 忽略缓存文件 - if (CacheSystem.IsCached(patchBundle)) + if (IsCachedPatchBundle(patchBundle)) continue; // 忽略APP资源 @@ -244,7 +242,7 @@ namespace YooAsset foreach (var patchBundle in patchManifest.BundleList) { // 忽略缓存文件 - if (CacheSystem.IsCached(patchBundle)) + if (IsCachedPatchBundle(patchBundle)) continue; if (IsBuildinPatchBundle(patchBundle)) @@ -268,7 +266,7 @@ namespace YooAsset foreach (var patchBundle in patchManifest.BundleList) { // 忽略缓存文件 - if (CacheSystem.IsCached(patchBundle)) + if (IsCachedPatchBundle(patchBundle)) continue; // 查询DLC资源 @@ -292,7 +290,7 @@ namespace YooAsset throw new Exception("Should never get here !"); // 查询沙盒资源 - if (CacheSystem.IsCached(patchBundle)) + if (IsCachedPatchBundle(patchBundle)) { BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromCache); return bundleInfo; diff --git a/Assets/YooAsset/Runtime/PatchSystem/PlayMode/OfflinePlayModeImpl.cs b/Assets/YooAsset/Runtime/PatchSystem/PlayMode/OfflinePlayModeImpl.cs index c5a9a91..a89c751 100644 --- a/Assets/YooAsset/Runtime/PatchSystem/PlayMode/OfflinePlayModeImpl.cs +++ b/Assets/YooAsset/Runtime/PatchSystem/PlayMode/OfflinePlayModeImpl.cs @@ -56,12 +56,6 @@ namespace YooAsset OperationSystem.StartOperation(operation); return operation; } - CheckPackageContentsOperation IPlayModeServices.CheckPackageContentsOperation(string packageVersion) - { - var operation = new OfflinePlayModeCheckPackageContentsOperation(); - OperationSystem.StartOperation(operation); - return operation; - } PatchDownloaderOperation IPlayModeServices.CreatePatchDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout) { @@ -93,7 +87,7 @@ namespace YooAsset throw new Exception("Should never get here !"); // 查询沙盒资源 - if (CacheSystem.IsCached(patchBundle)) + if (CacheSystem.IsCached(patchBundle.PackageName, patchBundle.CacheGUID)) { BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromCache); return bundleInfo; diff --git a/Assets/YooAsset/Runtime/Services/IPlayModeServices.cs b/Assets/YooAsset/Runtime/Services/IPlayModeServices.cs index 9a73a21..161567c 100644 --- a/Assets/YooAsset/Runtime/Services/IPlayModeServices.cs +++ b/Assets/YooAsset/Runtime/Services/IPlayModeServices.cs @@ -28,11 +28,6 @@ namespace YooAsset /// PreDownloadPackageOperation PreDownloadPackageAsync(string packageVersion, int timeout); - /// - /// 检查包裹内容的完整性 - /// - CheckPackageContentsOperation CheckPackageContentsOperation(string packageVersion); - // 下载相关 PatchDownloaderOperation CreatePatchDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout); PatchDownloaderOperation CreatePatchDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout); diff --git a/Assets/YooAsset/Runtime/Settings/YooAssetSettings.cs b/Assets/YooAsset/Runtime/Settings/YooAssetSettings.cs index 31cecfe..3dbcdb1 100644 --- a/Assets/YooAsset/Runtime/Settings/YooAssetSettings.cs +++ b/Assets/YooAsset/Runtime/Settings/YooAssetSettings.cs @@ -8,12 +8,12 @@ namespace YooAsset /// /// AssetBundle文件的后缀名 /// - public string BundleFileVariant = "bundle"; + public string AssetBundleFileVariant = "bundle"; /// /// 原生文件的后缀名 /// - public string RawFileVariant = "rawfile"; + public string RawBundleFileVariant = "rawfile"; /// /// 清单文件名称 diff --git a/Assets/YooAsset/Runtime/Settings/YooAssetSettingsData.cs b/Assets/YooAsset/Runtime/Settings/YooAssetSettingsData.cs index 874fefc..05cbf2a 100644 --- a/Assets/YooAsset/Runtime/Settings/YooAssetSettingsData.cs +++ b/Assets/YooAsset/Runtime/Settings/YooAssetSettingsData.cs @@ -79,9 +79,9 @@ namespace YooAsset { string shareBundleName; if (uniqueBundleName) - shareBundleName = $"{packageName.ToLower()}_{YooAssetSettings.UnityShadersBundleName}.{Setting.BundleFileVariant}"; + shareBundleName = $"{packageName.ToLower()}_{YooAssetSettings.UnityShadersBundleName}.{Setting.AssetBundleFileVariant}"; else - shareBundleName = $"{YooAssetSettings.UnityShadersBundleName}.{Setting.BundleFileVariant}"; + shareBundleName = $"{YooAssetSettings.UnityShadersBundleName}.{Setting.AssetBundleFileVariant}"; return shareBundleName.ToLower(); } } From 261276492208a02a3c9725399b1da5bc4ac8ad33 Mon Sep 17 00:00:00 2001 From: hevinci Date: Tue, 7 Feb 2023 18:39:42 +0800 Subject: [PATCH 2/2] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a3a9d8f..5815144 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,9 @@ QQ群:**963240451** [代码贡献](./Docs/CodeStyle.md) ## 友情链接 -[ET Framework](https://github.com/wqaetly/ET/tree/et7_fgui_yooasset_luban_huatuo): ET 7.0 + FGUI + luban + huatuo + YooAsset + NKGMoba + UniTask,并提供常用的编辑器工具。 +[ET Framework](https://github.com/wqaetly/ET/tree/et7_fgui_yooasset_luban_huatuo): ET 7.0 + FGUI + luban + huatuo + YooAsset + NKGMoba + UniTask,并提供常用的编辑器工具。 + +[ETPro](https://github.com/526077247/ETPro) ET6+YooAsset+HybridCLR + [YooAssetEx](https://gitee.com/liu_zhongxiu/yoo-asset-ex/tree/master): YooAsset Odin扩展工具,用于支持Unity2017和Unity2018版本。