using System.IO; namespace YooAsset { internal class LoadCacheManifestOperation : AsyncOperationBase { private enum ESteps { None, QueryCachePackageHash, VerifyFileHash, LoadCacheManifest, CheckDeserializeManifest, Done, } private readonly string _packageName; private readonly string _packageVersion; private QueryCachePackageHashOperation _queryCachePackageHashOp; private DeserializeManifestOperation _deserializer; private string _manifestFilePath; private ESteps _steps = ESteps.None; /// /// 加载的清单实例 /// public PackageManifest Manifest { private set; get; } public LoadCacheManifestOperation(string packageName, string packageVersion) { _packageName = packageName; _packageVersion = packageVersion; } internal override void Start() { _steps = ESteps.QueryCachePackageHash; } internal override void Update() { if (_steps == ESteps.None || _steps == ESteps.Done) return; if (_steps == ESteps.QueryCachePackageHash) { if (_queryCachePackageHashOp == null) { _queryCachePackageHashOp = new QueryCachePackageHashOperation(_packageName, _packageVersion); OperationSystem.StartOperation(_queryCachePackageHashOp); } if (_queryCachePackageHashOp.IsDone == false) return; if (_queryCachePackageHashOp.Status == EOperationStatus.Succeed) { _steps = ESteps.VerifyFileHash; } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = _queryCachePackageHashOp.Error; ClearCacheFile(); } } if (_steps == ESteps.VerifyFileHash) { _manifestFilePath = PersistentTools.GetPersistent(_packageName).GetSandboxPackageManifestFilePath(_packageVersion); if (File.Exists(_manifestFilePath) == false) { _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = $"Not found cache manifest file : {_manifestFilePath}"; ClearCacheFile(); return; } string fileHash = HashUtility.FileMD5(_manifestFilePath); if (fileHash != _queryCachePackageHashOp.PackageHash) { _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = "Failed to verify cache manifest file hash !"; ClearCacheFile(); } else { _steps = ESteps.LoadCacheManifest; } } if (_steps == ESteps.LoadCacheManifest) { byte[] bytesData = File.ReadAllBytes(_manifestFilePath); _deserializer = new DeserializeManifestOperation(bytesData); OperationSystem.StartOperation(_deserializer); _steps = ESteps.CheckDeserializeManifest; } if (_steps == ESteps.CheckDeserializeManifest) { Progress = _deserializer.Progress; if (_deserializer.IsDone == false) return; if (_deserializer.Status == EOperationStatus.Succeed) { Manifest = _deserializer.Manifest; _steps = ESteps.Done; Status = EOperationStatus.Succeed; } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = _deserializer.Error; ClearCacheFile(); } } } private void ClearCacheFile() { // 注意:如果加载沙盒内的清单报错,为了避免流程被卡住,主动把损坏的文件删除。 if (File.Exists(_manifestFilePath)) { YooLogger.Warning($"Failed to load cache manifest file : {Error}"); YooLogger.Warning($"Invalid cache manifest file have been removed : {_manifestFilePath}"); File.Delete(_manifestFilePath); } string hashFilePath = PersistentTools.GetPersistent(_packageName).GetSandboxPackageHashFilePath(_packageVersion); if (File.Exists(hashFilePath)) { File.Delete(hashFilePath); } } } }