using UnityEngine; namespace YooAsset { internal class LoadWebEncryptAssetBundleOperation : LoadWebAssetBundleOperation { protected enum ESteps { None, CreateRequest, CheckRequest, TryAgain, Done, } private readonly PackageBundle _bundle; private readonly DownloadFileOptions _options; private readonly IWebDecryptionServices _decryptionServices; private UnityWebDataRequestOperation _unityWebDataRequestOp; protected int _requestCount = 0; protected float _tryAgainTimer; protected int _failedTryAgain; private ESteps _steps = ESteps.None; internal LoadWebEncryptAssetBundleOperation(PackageBundle bundle, DownloadFileOptions options, IWebDecryptionServices decryptionServices) { _bundle = bundle; _options = options; _decryptionServices = decryptionServices; } internal override void InternalStart() { _steps = ESteps.CreateRequest; } internal override void InternalUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; // 创建下载器 if (_steps == ESteps.CreateRequest) { if (_decryptionServices == null) { _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = $"The {nameof(IWebDecryptionServices)} is null !"; YooLogger.Error(Error); return; } string url = GetRequestURL(); _unityWebDataRequestOp = new UnityWebDataRequestOperation(url, 0); _unityWebDataRequestOp.StartOperation(); AddChildOperation(_unityWebDataRequestOp); _steps = ESteps.CheckRequest; } // 检测下载结果 if (_steps == ESteps.CheckRequest) { _unityWebDataRequestOp.UpdateOperation(); Progress = _unityWebDataRequestOp.Progress; DownloadProgress = _unityWebDataRequestOp.DownloadProgress; DownloadedBytes = _unityWebDataRequestOp.DownloadedBytes; if (_unityWebDataRequestOp.IsDone == false) return; // 检查网络错误 if (_unityWebDataRequestOp.Status == EOperationStatus.Succeed) { AssetBundle assetBundle = LoadEncryptedAssetBundle(_unityWebDataRequestOp.Result); if (assetBundle == null) { _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = "Failed load encrypted AssetBundle !"; } else { _steps = ESteps.Done; Status = EOperationStatus.Succeed; Result = assetBundle; } } else { if (_failedTryAgain > 0) { _steps = ESteps.TryAgain; YooLogger.Warning($"Failed download : {_unityWebDataRequestOp.URL} Try again !"); } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; Error = _unityWebDataRequestOp.Error; YooLogger.Error(Error); } } } // 重新尝试下载 if (_steps == ESteps.TryAgain) { _tryAgainTimer += Time.unscaledDeltaTime; if (_tryAgainTimer > 1f) { _tryAgainTimer = 0f; _failedTryAgain--; Progress = 0f; DownloadProgress = 0f; DownloadedBytes = 0; _steps = ESteps.CreateRequest; } } } /// /// 加载加密资源文件 /// private AssetBundle LoadEncryptedAssetBundle(byte[] fileData) { var fileInfo = new WebDecryptFileInfo(); fileInfo.BundleName = _bundle.BundleName; fileInfo.FileLoadCRC = _bundle.UnityCRC; fileInfo.FileData = fileData; var decryptResult = _decryptionServices.LoadAssetBundle(fileInfo); return decryptResult.Result; } /// /// 获取网络请求地址 /// protected string GetRequestURL() { // 轮流返回请求地址 _requestCount++; if (_requestCount % 2 == 0) return _options.FallbackURL; else return _options.MainURL; } } }