diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/AssetBundleResult.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/AssetBundleResult.cs index 587674ff..9d30d07e 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/AssetBundleResult.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/AssetBundleResult.cs @@ -36,14 +36,6 @@ namespace YooAsset { return _fileSystem.GetBundleFilePath(_packageBundle); } - public override byte[] ReadBundleFileData() - { - return _fileSystem.ReadBundleFileData(_packageBundle); - } - public override string ReadBundleFileText() - { - return _fileSystem.ReadBundleFileText(_packageBundle); - } public override FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo) { diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadAssetOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadAssetOperation.cs index 433187eb..9b4f5a7d 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadAssetOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/AssetBundleLoadAssetOperation.cs @@ -93,11 +93,11 @@ namespace YooAsset error = $"Failed to load asset : {_assetInfo.AssetPath} AssetType : null AssetBundle : {_packageBundle.BundleName}"; else error = $"Failed to load asset : {_assetInfo.AssetPath} AssetType : {_assetInfo.AssetType} AssetBundle : {_packageBundle.BundleName}"; - YooLogger.Error(error); _steps = ESteps.Done; - Error = error; Status = EOperationStatus.Failed; + Error = error; + YooLogger.Error(Error); } else { diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadAssetBundleOperation.cs new file mode 100644 index 00000000..a6d2648a --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadAssetBundleOperation.cs @@ -0,0 +1,408 @@ +using System; +using System.IO; +using UnityEngine; + +namespace YooAsset +{ + /// + /// 默认的 AssetBundle 加载操作(非加密) + /// 通用实现,适用于 BuiltinFileSystem 和 CacheFileSystem + /// + public class DefaultLoadAssetBundleOperation : LoadAssetBundleOperation + { + private enum ESteps + { + None, + LoadAssetBundle, + CheckResult, + Done, + } + + private AssetBundleCreateRequest _createRequest; + private ESteps _steps = ESteps.None; + + public DefaultLoadAssetBundleOperation(LoadAssetBundleOptions opionts) : base(opionts) { } + internal override void InternalStart() + { + _steps = ESteps.LoadAssetBundle; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadAssetBundle) + { + if (IsWaitingForAsyncComplete) + Result = AssetBundle.LoadFromFile(_options.FileLoadPath); + else + _createRequest = AssetBundle.LoadFromFileAsync(_options.FileLoadPath); + + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.CheckResult) + { + if (_createRequest != null) + { + if (IsWaitingForAsyncComplete) + { + // 强制挂起主线程(注意:该操作会很耗时) + YooLogger.Warning("Suspend the main thread to load unity bundle."); + Result = _createRequest.assetBundle; + } + else + { + if (_createRequest.isDone == false) + return; + Result = _createRequest.assetBundle; + } + } + + if (Result == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load asset bundle file : {_options.Bundle.BundleName}"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } + internal override void InternalWaitForAsyncComplete() + { + RunBatchExecution(); + } + + public override AssetBundle LoadFromMemory() + { + byte[] fileData = FileUtility.ReadAllBytes(_options.FileLoadPath); + if (fileData == null || fileData.Length == 0) + return null; + + return AssetBundle.LoadFromMemory(fileData); + } + } + + /// + /// 默认的 AssetBundle 加载操作(加密) + /// 通用实现,适用于 BuiltinFileSystem 和 CacheFileSystem + /// + public abstract class DefaultLoadAssetBundleFromOffsetOperation : LoadAssetBundleOperation + { + private enum ESteps + { + None, + LoadAssetBundle, + CheckResult, + Done, + } + + private AssetBundleCreateRequest _createRequest; + private ESteps _steps = ESteps.None; + + public DefaultLoadAssetBundleFromOffsetOperation(LoadAssetBundleOptions options) : base(options) { } + internal override void InternalStart() + { + _steps = ESteps.LoadAssetBundle; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadAssetBundle) + { + ulong offset = GetFileOffset(); + if (IsWaitingForAsyncComplete) + Result = AssetBundle.LoadFromFile(_options.FileLoadPath, 0, offset); + else + _createRequest = AssetBundle.LoadFromFileAsync(_options.FileLoadPath, 0, offset); + + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.CheckResult) + { + if (_createRequest != null) + { + if (IsWaitingForAsyncComplete) + { + // 强制挂起主线程(注意:该操作会很耗时) + YooLogger.Warning("Suspend the main thread to load unity bundle."); + Result = _createRequest.assetBundle; + } + else + { + if (_createRequest.isDone == false) + return; + Result = _createRequest.assetBundle; + } + } + + if (Result == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load asset bundle file : {_options.Bundle.BundleName}"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } + internal override void InternalWaitForAsyncComplete() + { + RunBatchExecution(); + } + + /// + /// 获取偏移值 + /// + protected abstract uint GetFileOffset(); + + public override AssetBundle LoadFromMemory() + { + int offset = (int)GetFileOffset(); + byte[] fileData = File.ReadAllBytes(_options.FileLoadPath); + if (fileData == null || fileData.Length <= offset) + return null; + + // 跳过偏移量 + byte[] bundleData = new byte[fileData.Length - offset]; + Buffer.BlockCopy(fileData, offset, bundleData, 0, bundleData.Length); + + return AssetBundle.LoadFromMemory(bundleData); + } + } + + /// + /// 默认的 AssetBundle 加载操作(加密) + /// 通用实现,适用于 CacheFileSystem + /// + public abstract class DefaultLoadAssetBundleFromMemoryOperation : LoadAssetBundleOperation + { + private enum ESteps + { + None, + CheckPlatform, + LoadAssetBundle, + CheckResult, + Done, + } + + private AssetBundleCreateRequest _createRequest; + private ESteps _steps = ESteps.None; + + public DefaultLoadAssetBundleFromMemoryOperation(LoadAssetBundleOptions options) : base(options) { } + internal override void InternalStart() + { + _steps = ESteps.CheckPlatform; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CheckPlatform) + { +#if UNITY_ANDROID + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Android platform not support read builtin file."; +#else + _steps = ESteps.LoadAssetBundle; +#endif + } + + if (_steps == ESteps.LoadAssetBundle) + { + byte[] fileData = File.ReadAllBytes(_options.FileLoadPath); + byte[] rawData = DecryptData(fileData); + if (rawData == null || rawData.Length == 0) + { + _steps = ESteps.None; + Status = EOperationStatus.Failed; + Error = "Decrypted raw data is null or empty."; + return; + } + + if (IsWaitingForAsyncComplete) + Result = AssetBundle.LoadFromMemory(rawData); + else + _createRequest = AssetBundle.LoadFromMemoryAsync(rawData); + + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.CheckResult) + { + if (_createRequest != null) + { + if (IsWaitingForAsyncComplete) + { + // 强制挂起主线程(注意:该操作会很耗时) + YooLogger.Warning("Suspend the main thread to load unity bundle."); + Result = _createRequest.assetBundle; + } + else + { + if (_createRequest.isDone == false) + return; + Result = _createRequest.assetBundle; + } + } + + if (Result == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load asset bundle file : {_options.Bundle.BundleName}"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } + internal override void InternalWaitForAsyncComplete() + { + RunBatchExecution(); + } + + /// + /// 文件数据解密 + /// + protected abstract byte[] DecryptData(byte[] data); + + public override AssetBundle LoadFromMemory() + { + byte[] fileData = File.ReadAllBytes(_options.FileLoadPath); + byte[] rawData = DecryptData(fileData); + if (rawData == null || rawData.Length == 0) + return null; + + return AssetBundle.LoadFromMemory(rawData); + } + } + + /// + /// 默认的 AssetBundle 加载操作(加密) + /// 通用实现,适用于 CacheFileSystem + /// + public abstract class DefaultLoadAssetBundleFromStreamOperation : LoadAssetBundleOperation + { + private enum ESteps + { + None, + CheckPlatform, + LoadAssetBundle, + CheckResult, + Done, + } + + private AssetBundleCreateRequest _createRequest; + private ESteps _steps = ESteps.None; + + public DefaultLoadAssetBundleFromStreamOperation(LoadAssetBundleOptions options) : base(options) { } + internal override void InternalStart() + { + _steps = ESteps.CheckPlatform; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CheckPlatform) + { +#if UNITY_ANDROID + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Android platform not support read builtin file."; +#else + _steps = ESteps.LoadAssetBundle; +#endif + } + + if (_steps == ESteps.LoadAssetBundle) + { + ManagedStream = CreateManagedFileStream(); + uint bufferSize = GetManagedReadBufferSize(); + + if (IsWaitingForAsyncComplete) + Result = AssetBundle.LoadFromStream(ManagedStream, 0, bufferSize); + else + _createRequest = AssetBundle.LoadFromStreamAsync(ManagedStream, 0, bufferSize); + + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.CheckResult) + { + if (_createRequest != null) + { + if (IsWaitingForAsyncComplete) + { + // 强制挂起主线程(注意:该操作会很耗时) + YooLogger.Warning("Suspend the main thread to load unity bundle."); + Result = _createRequest.assetBundle; + } + else + { + if (_createRequest.isDone == false) + return; + Result = _createRequest.assetBundle; + } + } + + if (Result == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load asset bundle file : {_options.Bundle.BundleName}"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } + internal override void InternalWaitForAsyncComplete() + { + RunBatchExecution(); + } + + /// + /// 获取文件流 + /// + protected abstract FileStream CreateManagedFileStream(); + + /// + /// 获取缓冲池大小 + /// + protected abstract uint GetManagedReadBufferSize(); + + /// + /// 文件数据解密 + /// + protected abstract byte[] DecryptData(byte[] data); + + public override AssetBundle LoadFromMemory() + { + byte[] fileData = File.ReadAllBytes(_options.FileLoadPath); + byte[] rawData = DecryptData(fileData); + if (rawData == null || rawData.Length == 0) + return null; + + return AssetBundle.LoadFromMemory(rawData); + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebNormalAssetBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadAssetBundleOperation.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebNormalAssetBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadAssetBundleOperation.cs.meta index 08958f56..64719f4f 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebNormalAssetBundleOperation.cs.meta +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadAssetBundleOperation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 3b82b4b846083d34b958320b584d8d9b +guid: 067ac2067f265624bac214127575d7d5 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadWebAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadWebAssetBundleOperation.cs new file mode 100644 index 00000000..8057f1a2 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadWebAssetBundleOperation.cs @@ -0,0 +1,249 @@ +using UnityEngine; + +namespace YooAsset +{ + /// + /// 默认的 AssetBundle 加载操作(非加密) + /// 通用实现,适用于 WebRemoteFileSystem 和 WebServerFileSystem + /// + public class DefaultLoadWebAssetBundleOperation : LoadWebAssetBundleOperation + { + private enum ESteps + { + None, + CreateRequest, + CheckRequest, + TryAgain, + Done, + } + + private IDownloadAssetBundleRequest _downloadAssetBundleRequest; + private ESteps _steps = ESteps.None; + + private int _requestCount = 0; + private float _tryAgainTimer = 0; + private int _failedTryAgain; + + public DefaultLoadWebAssetBundleOperation(LoadWebAssetBundleOptions opionts) : base(opionts) + { + _failedTryAgain = opionts.FailedTryAgain; + } + internal override void InternalStart() + { + _steps = ESteps.CreateRequest; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + // 创建下载器 + if (_steps == ESteps.CreateRequest) + { + string url = GetRequestURL(); + var args = new DownloadAssetBundleRequestArgs(url, 0, _options.WatchdogTimeout, _options.DisableUnityWebCache, _options.Bundle.FileHash, _options.Bundle.UnityCRC); + _downloadAssetBundleRequest = _options.DownloadBackend.CreateAssetBundleRequest(args); + _downloadAssetBundleRequest.SendRequest(); + _steps = ESteps.CheckRequest; + } + + // 检测下载结果 + if (_steps == ESteps.CheckRequest) + { + Progress = _downloadAssetBundleRequest.DownloadProgress; + DownloadedBytes = _downloadAssetBundleRequest.DownloadedBytes; + DownloadProgress = _downloadAssetBundleRequest.DownloadProgress; + if (_downloadAssetBundleRequest.IsDone == false) + return; + + if (_downloadAssetBundleRequest.Status == EDownloadRequestStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + Result = _downloadAssetBundleRequest.Result; + } + else + { + if (_failedTryAgain > 0) + { + _steps = ESteps.TryAgain; + YooLogger.Warning($"Failed download : {_downloadAssetBundleRequest.URL} Try again."); + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _downloadAssetBundleRequest.Error; + YooLogger.Error(Error); + } + } + + // 最终释放请求器 + _downloadAssetBundleRequest.Dispose(); + } + + // 重新尝试下载 + if (_steps == ESteps.TryAgain) + { + _tryAgainTimer += Time.unscaledDeltaTime; + if (_tryAgainTimer > 1f) + { + _tryAgainTimer = 0f; + _failedTryAgain--; + Progress = 0f; + DownloadProgress = 0f; + DownloadedBytes = 0; + _steps = ESteps.CreateRequest; + } + } + } + + /// + /// 获取网络请求地址 + /// + protected string GetRequestURL() + { + // 轮流返回请求地址 + _requestCount++; + if (_requestCount % 2 == 0) + return _options.FallbackURL; + else + return _options.MainURL; + } + } + + /// + /// 默认的 AssetBundle 加载操作(加密) + /// 通用实现,适用于 WebRemoteFileSystem 和 WebServerFileSystem + /// + public abstract class DefaultLoadWebAssetBundleFromMemoryOperation : LoadWebAssetBundleOperation + { + private enum ESteps + { + None, + CreateRequest, + CheckRequest, + TryAgain, + Done, + } + + private IDownloadBytesRequest _downloadBytesRequest; + private ESteps _steps = ESteps.None; + + private int _requestCount = 0; + private float _tryAgainTimer = 0; + private int _failedTryAgain; + + public DefaultLoadWebAssetBundleFromMemoryOperation(LoadWebAssetBundleOptions opionts) : base(opionts) + { + _failedTryAgain = opionts.FailedTryAgain; + } + internal override void InternalStart() + { + _steps = ESteps.CreateRequest; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + // 创建下载器 + if (_steps == ESteps.CreateRequest) + { + string url = GetRequestURL(); + var args = new DownloadDataRequestArgs(url, 0, _options.WatchdogTimeout); + _downloadBytesRequest = _options.DownloadBackend.CreateBytesRequest(args); + _downloadBytesRequest.SendRequest(); + _steps = ESteps.CheckRequest; + } + + // 检测下载结果 + if (_steps == ESteps.CheckRequest) + { + Progress = _downloadBytesRequest.DownloadProgress; + DownloadProgress = _downloadBytesRequest.DownloadProgress; + DownloadedBytes = _downloadBytesRequest.DownloadedBytes; + if (_downloadBytesRequest.IsDone == false) + return; + + // 检查网络错误 + if (_downloadBytesRequest.Status == EDownloadRequestStatus.Succeed) + { + var rawData = Decryption(_downloadBytesRequest.Result); + if (rawData == null || rawData.Length == 0) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "AssetBundle raw data is null or empty."; + } + else + { + AssetBundle assetBundle = AssetBundle.LoadFromMemory(rawData); + if (assetBundle == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed load encrypted AssetBundle: {_options.Bundle.BundleName}"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + Result = assetBundle; + } + } + } + else + { + if (_failedTryAgain > 0) + { + _steps = ESteps.TryAgain; + YooLogger.Warning($"Failed download : {_downloadBytesRequest.URL} Try again."); + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _downloadBytesRequest.Error; + YooLogger.Error(Error); + } + } + + // 最终释放请求器 + _downloadBytesRequest.Dispose(); + } + + // 重新尝试下载 + if (_steps == ESteps.TryAgain) + { + _tryAgainTimer += Time.unscaledDeltaTime; + if (_tryAgainTimer > 1f) + { + _tryAgainTimer = 0f; + _failedTryAgain--; + Progress = 0f; + DownloadProgress = 0f; + DownloadedBytes = 0; + _steps = ESteps.CreateRequest; + } + } + } + + /// + /// 文件数据解密 + /// + protected abstract byte[] Decryption(byte[] data); + + /// 获取网络请求地址 + /// + protected string GetRequestURL() + { + // 轮流返回请求地址 + _requestCount++; + if (_requestCount % 2 == 0) + return _options.FallbackURL; + else + return _options.MainURL; + } + } +} diff --git a/Assets/YooAsset/Runtime/Services/IBundleDecryptionServices.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadWebAssetBundleOperation.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/Services/IBundleDecryptionServices.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadWebAssetBundleOperation.cs.meta index ea5b4e0d..50c254b1 100644 --- a/Assets/YooAsset/Runtime/Services/IBundleDecryptionServices.cs.meta +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/DefaultLoadWebAssetBundleOperation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 3444518ef1b082a46a9855fef4f69c86 +guid: 05b4aa37709184a408090202f98b93d3 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOperation.cs new file mode 100644 index 00000000..5985d143 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOperation.cs @@ -0,0 +1,68 @@ +using System.IO; +using UnityEngine; + +namespace YooAsset +{ + /// + /// 加载 AssetBundle 的 Operation 工厂委托 + /// + public delegate LoadAssetBundleOperation LoadAssetBundleOperationFactory(bool bundleEncrypted, LoadAssetBundleOptions options); + + /// + /// 加载 AssetBundle 的抽象基类 + /// 用户可继承此类实现自定义加载逻辑(如加密解密) + /// + public abstract class LoadAssetBundleOperation : AsyncOperationBase + { + protected readonly LoadAssetBundleOptions _options; + + /// + /// 加载结果:AssetBundle 对象 + /// + public AssetBundle Result { get; protected set; } + + /// + /// 托管流对象(如果使用流加载) + /// 注意:流对象在资源包对象释放的时候会自动释放 + /// + public Stream ManagedStream { get; protected set; } + + public LoadAssetBundleOperation(LoadAssetBundleOptions options) + { + _options = options; + } + + /// + /// 后备加载方法:从内存加载 AssetBundle + /// 当主加载方式失败时,FileSystem 会调用此方法作为后备机制 + /// + /// 加载成功返回 AssetBundle 对象,失败返回 null + public abstract AssetBundle LoadFromMemory(); + } + + /// + /// 立即完成(失败)的 AssetBundle 加载操作 + /// 用途:当 Factory 判定某种场景不支持(例如默认实现不支持加密包)时,返回该 Operation + /// + public sealed class LoadAssetBundleCompleteOperation : LoadAssetBundleOperation + { + private readonly string _error; + + public LoadAssetBundleCompleteOperation(string error, LoadAssetBundleOptions options) : base(options) + { + _error = error; + } + internal override void InternalStart() + { + Status = EOperationStatus.Failed; + Error = _error; + } + internal override void InternalUpdate() + { + } + public override AssetBundle LoadFromMemory() + { + return null; + } + } +} diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebEncryptAssetBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOperation.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebEncryptAssetBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOperation.cs.meta index 7615ae03..f0483f47 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebEncryptAssetBundleOperation.cs.meta +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOperation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 2f88823353464474faf7b020a76f9b2d +guid: 32e01cb4600c49f42b8ec19be8f0fb22 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOptions.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOptions.cs new file mode 100644 index 00000000..a90807cc --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOptions.cs @@ -0,0 +1,19 @@ + +namespace YooAsset +{ + /// + /// 加载 AssetBundle 的上下文信息 + /// + public struct LoadAssetBundleOptions + { + /// + /// 文件加载路径 + /// + internal string FileLoadPath { get; set; } + + /// + /// 资源包信息 + /// + internal PackageBundle Bundle { get; set; } + } +} diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileOffsetEncryption.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOptions.cs.meta similarity index 83% rename from Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileOffsetEncryption.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOptions.cs.meta index 5f30658f..7cac3dfc 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileOffsetEncryption.cs.meta +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadAssetBundleOptions.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 174e56f3a30d7fd4e80bde43ba267631 +guid: b866c4ec2f032aa4eb0d4f9094273100 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOperation.cs new file mode 100644 index 00000000..10ef0441 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOperation.cs @@ -0,0 +1,60 @@ +using UnityEngine; + +namespace YooAsset +{ + /// + /// 加载 AssetBundle 的 Operation 工厂委托 + /// + public delegate LoadWebAssetBundleOperation LoadWebAssetBundleOperationFactory(bool bundleEncrypted, LoadWebAssetBundleOptions options); + + /// + /// 加载 AssetBundle 的抽象基类 + /// 用户可继承此类实现自定义加载逻辑(如加密解密) + /// + public abstract class LoadWebAssetBundleOperation : AsyncOperationBase + { + protected readonly LoadWebAssetBundleOptions _options; + + /// + /// 加载结果:AssetBundle 对象 + /// + public AssetBundle Result { get; protected set; } + + /// + /// 下载进度 + /// + public float DownloadProgress { protected set; get; } + + /// + /// 下载大小 + /// + public long DownloadedBytes { protected set; get; } + + public LoadWebAssetBundleOperation(LoadWebAssetBundleOptions options) + { + _options = options; + } + } + + /// + /// 立即完成(失败)的 AssetBundle 加载操作 + /// 用途:当 Factory 判定某种场景不支持(例如默认实现不支持加密包)时,返回该 Operation + /// + public sealed class LoadWebAssetBundleCompleteOperation : LoadWebAssetBundleOperation + { + private readonly string _error; + + public LoadWebAssetBundleCompleteOperation(string error, LoadWebAssetBundleOptions options) : base(options) + { + _error = error; + } + internal override void InternalStart() + { + Status = EOperationStatus.Failed; + Error = _error; + } + internal override void InternalUpdate() + { + } + } +} diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebAssetBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOperation.cs.meta similarity index 83% rename from Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebAssetBundleOperation.cs.meta rename to Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOperation.cs.meta index 70966c59..179d0179 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebAssetBundleOperation.cs.meta +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOperation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 0f65d2f6038b95246b7a09cec4055b3a +guid: f0fd9af541471154d9fc968abd450d31 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOptions.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOptions.cs new file mode 100644 index 00000000..1c3af9ac --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOptions.cs @@ -0,0 +1,44 @@ + +namespace YooAsset +{ + /// + /// 加载 AssetBundle 的上下文信息 + /// + public struct LoadWebAssetBundleOptions + { + /// + /// 资源包信息 + /// + internal PackageBundle Bundle { get; set; } + + /// + /// 失败后重试次数 + /// + internal int FailedTryAgain { get; set; } + + /// + /// 看门狗超时时间 + /// + internal int WatchdogTimeout { get; set; } + + /// + /// 下载后台接口 + /// + internal IDownloadBackend DownloadBackend { get; set; } + + /// + /// 禁用Unity的网络缓存 + /// + internal bool DisableUnityWebCache { get; set; } + + /// + /// 主资源地址 + /// + internal string MainURL { get; set; } + + /// + /// 备用资源地址 + /// + internal string FallbackURL { get; set; } + } +} diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOptions.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOptions.cs.meta new file mode 100644 index 00000000..615d1299 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/AssetBundleResult/Operation/LoadWebAssetBundleOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4c79e03ac8bcbef4aa0e2eede5bf63fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/BundleResult.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/BundleResult.cs index 9b3e2a1e..cc54bff6 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/BundleResult.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/BundleResult.cs @@ -10,20 +10,10 @@ namespace YooAsset public abstract void UnloadBundleFile(); /// - /// 获取资源包文件的路径 + /// 获取资源包文件的本地路径 /// public abstract string GetBundleFilePath(); - /// - /// 读取资源包文件的二进制数据 - /// - public abstract byte[] ReadBundleFileData(); - - /// - /// 读取资源包文件的文本数据 - /// - public abstract string ReadBundleFileText(); - /// /// 加载资源包内的资源对象 diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/DefaultLoadRawBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/DefaultLoadRawBundleOperation.cs new file mode 100644 index 00000000..78dc4a0b --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/DefaultLoadRawBundleOperation.cs @@ -0,0 +1,141 @@ +using System.IO; + +namespace YooAsset +{ + /// + /// 默认的 RawBundle 加载操作(非加密) + /// 通用实现,适用于 BuiltinFileSystem 和 CacheFileSystem + /// + public class DefaultLoadRawBundleOperation : LoadRawBundleOperation + { + private enum ESteps + { + None, + CheckPlatform, + LoadRawBundle, + Done + } + + private ESteps _steps = ESteps.None; + + public DefaultLoadRawBundleOperation(LoadRawBundleOptions options) : base(options) { } + internal override void InternalStart() + { + _steps = ESteps.CheckPlatform; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CheckPlatform) + { +#if UNITY_ANDROID + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Android platform not support read builtin file."; +#else + _steps = ESteps.LoadRawBundle; +#endif + } + + if (_steps == ESteps.LoadRawBundle) + { + string filePath = _options.FileLoadPath; + if (File.Exists(filePath)) + { + byte[] data = File.ReadAllBytes(filePath); + Result = new RawBundle(data); + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Can not found raw bundle file : {filePath}"; + } + } + } + internal override void InternalWaitForAsyncComplete() + { + RunBatchExecution(); + } + } + + /// + /// 默认的 RawBundle 加载操作(加密) + /// 通用实现,适用于 CacheFileSystem + /// + public abstract class DefaultLoadRawBundleFromMemoryOperation : LoadRawBundleOperation + { + private enum ESteps + { + None, + CheckPlatform, + LoadRawBundle, + Done + } + + private ESteps _steps = ESteps.None; + + public DefaultLoadRawBundleFromMemoryOperation(LoadRawBundleOptions options) : base(options) { } + internal override void InternalStart() + { + _steps = ESteps.CheckPlatform; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CheckPlatform) + { +#if UNITY_ANDROID + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Android platform not support read builtin file."; +#else + _steps = ESteps.LoadRawBundle; +#endif + } + + if (_steps == ESteps.LoadRawBundle) + { + string filePath = _options.FileLoadPath; + if (File.Exists(filePath)) + { + byte[] fileData = File.ReadAllBytes(filePath); + byte[] rawData = DecryptData(fileData); + if (rawData == null || rawData.Length == 0) + { + _steps = ESteps.None; + Status = EOperationStatus.Failed; + Error = "Decrypted raw data is null or empty."; + } + else + { + Result = new RawBundle(rawData); + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Can not found raw bundle file : {filePath}"; + } + } + } + internal override void InternalWaitForAsyncComplete() + { + RunBatchExecution(); + } + + /// + /// 文件数据解密 + /// + protected abstract byte[] DecryptData(byte[] data); + } +} diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/DefaultLoadRawBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/DefaultLoadRawBundleOperation.cs.meta new file mode 100644 index 00000000..94400673 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/DefaultLoadRawBundleOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cc25b8eb3bf83474f942e36bf7b3210d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOperation.cs new file mode 100644 index 00000000..e804abcb --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOperation.cs @@ -0,0 +1,50 @@ +using System.Text; + +namespace YooAsset +{ + /// + /// 加载 RawBundle 的 Operation 工厂委托 + /// + public delegate LoadRawBundleOperation LoadRawBundleOperationFactory(bool bundleEncrypted, LoadRawBundleOptions options); + + /// + /// 加载 RawBundle 的抽象基类 + /// 用户可继承此类实现自定义加载逻辑(如加密解密) + /// + public abstract class LoadRawBundleOperation : AsyncOperationBase + { + protected readonly LoadRawBundleOptions _options; + + /// + /// 加载结果:RawBundle 对象 + /// + public RawBundle Result { get; protected set; } + + public LoadRawBundleOperation(LoadRawBundleOptions options) + { + _options = options; + } + } + + /// + /// 立即完成(失败)的 RawBundle 加载操作 + /// 用途:当 Factory 判定某种场景不支持(例如默认实现不支持加密包)时,返回该 Operation + /// + public sealed class LoadRawBundleCompleteOperation : LoadRawBundleOperation + { + private readonly string _error; + + public LoadRawBundleCompleteOperation(string error, LoadRawBundleOptions options) : base(options) + { + _error = error; + } + internal override void InternalStart() + { + Status = EOperationStatus.Failed; + Error = _error; + } + internal override void InternalUpdate() + { + } + } +} diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOperation.cs.meta new file mode 100644 index 00000000..48b4ee28 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 445c03f3efb27eb4c91ce4b387997ac7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOptions.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOptions.cs new file mode 100644 index 00000000..00c8e31f --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOptions.cs @@ -0,0 +1,19 @@ + +namespace YooAsset +{ + /// + /// 加载 RawBundle 的上下文信息 + /// + public struct LoadRawBundleOptions + { + /// + /// 文件加载路径 + /// + internal string FileLoadPath { get; set; } + + /// + /// 资源包信息 + /// + internal PackageBundle Bundle { get; set; } + } +} diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOptions.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOptions.cs.meta new file mode 100644 index 00000000..b6ed2181 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/LoadRawBundleFileOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8637bbd2c5bb97d428e45a76466af9c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadAssetOperation.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadAssetOperation.cs index 5fb1e189..3f96e8f6 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadAssetOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/Operation/RawBundleLoadAssetOperation.cs @@ -3,13 +3,55 @@ namespace YooAsset { internal class RawBundleLoadAssetOperation : FSLoadAssetOperation { + protected enum ESteps + { + None, + LoadObject, + CheckResult, + Done, + } + + private readonly PackageBundle _packageBundle; + private readonly RawBundle _rawBundle; + private readonly AssetInfo _assetInfo; + private ESteps _steps = ESteps.None; + + public RawBundleLoadAssetOperation(PackageBundle packageBundle, RawBundle rawBundle, AssetInfo assetInfo) + { + _packageBundle = packageBundle; + _rawBundle = rawBundle; + _assetInfo = assetInfo; + } internal override void InternalStart() { - Error = $"{nameof(RawBundleLoadAssetOperation)} not support load asset."; - Status = EOperationStatus.Failed; + _steps = ESteps.LoadObject; } internal override void InternalUpdate() { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadObject) + { + Result = _rawBundle.LoadRawFileObject(); + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.CheckResult) + { + if (Result == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Failed to load raw file object : {_assetInfo.AssetPath}"; + YooLogger.Error(Error); + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundle.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundle.cs new file mode 100644 index 00000000..24be7bc5 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundle.cs @@ -0,0 +1,27 @@ + +namespace YooAsset +{ + public class RawBundle + { + private byte[] _data; + + public RawBundle(byte[] data) + { + _data = data; + } + + /// + /// 加载原生文件对象 + /// + public RawFileObject LoadRawFileObject() + { + var rawFileObject = new RawFileObject(_data); + return rawFileObject; + } + + public void Unload() + { + _data = null; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundle.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundle.cs.meta new file mode 100644 index 00000000..06ee5659 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundle.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c5157b3021ed3074192933520404544d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundleResult.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundleResult.cs index 6a42ddc2..dfce426b 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundleResult.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawBundleResult.cs @@ -6,32 +6,30 @@ namespace YooAsset { private readonly IFileSystem _fileSystem; private readonly PackageBundle _packageBundle; + private readonly RawBundle _rawBundle; - public RawBundleResult(IFileSystem fileSystem, PackageBundle packageBundle) + public RawBundleResult(IFileSystem fileSystem, PackageBundle packageBundle, RawBundle rawBundle) { _fileSystem = fileSystem; _packageBundle = packageBundle; + _rawBundle = rawBundle; } public override void UnloadBundleFile() { + if (_rawBundle != null) + { + _rawBundle.Unload(); + } } public override string GetBundleFilePath() { return _fileSystem.GetBundleFilePath(_packageBundle); } - public override byte[] ReadBundleFileData() - { - return _fileSystem.ReadBundleFileData(_packageBundle); - } - public override string ReadBundleFileText() - { - return _fileSystem.ReadBundleFileText(_packageBundle); - } public override FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo) { - var operation = new RawBundleLoadAssetOperation(); + var operation = new RawBundleLoadAssetOperation(_packageBundle, _rawBundle, assetInfo); return operation; } public override FSLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo) diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawFileObject.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawFileObject.cs new file mode 100644 index 00000000..03de9c16 --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawFileObject.cs @@ -0,0 +1,38 @@ +using System.Text; + +namespace YooAsset +{ + /// + /// 原生文件对象 + /// + public class RawFileObject : UnityEngine.Object + { + private readonly byte[] _fileData; + private string _fileText; + + public byte[] Data + { + get + { + return _fileData; + } + } + public string Text + { + get + { + if (Data == null || Data.Length == 0) + return null; + + if (string.IsNullOrEmpty(_fileText)) + _fileText = Encoding.UTF8.GetString(Data); + return _fileText; + } + } + + public RawFileObject(byte[] data) + { + _fileData = data; + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawFileObject.cs.meta b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawFileObject.cs.meta new file mode 100644 index 00000000..7b1ffdeb --- /dev/null +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/RawBundleResult/RawFileObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ffa40d12948b6c74e95a1cd42c3c3b7e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/VirtualBundleResult.cs b/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/VirtualBundleResult.cs index 3ed31901..66c77e90 100644 --- a/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/VirtualBundleResult.cs +++ b/Assets/YooAsset/Runtime/FileSystem/BundleResult/VirtualBundleResult/VirtualBundleResult.cs @@ -20,14 +20,6 @@ namespace YooAsset { return _fileSystem.GetBundleFilePath(_packageBundle); } - public override byte[] ReadBundleFileData() - { - return _fileSystem.ReadBundleFileData(_packageBundle); - } - public override string ReadBundleFileText() - { - return _fileSystem.ReadBundleFileText(_packageBundle); - } public override FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo) { diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystemParameters.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystemParameters.cs index 950d61a1..881c763c 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystemParameters.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystemParameters.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; namespace YooAsset @@ -81,13 +81,11 @@ namespace YooAsset /// /// 创建默认的内置文件系统参数 /// - /// 加密文件解密服务类 /// 文件系统的根目录 - public static FileSystemParameters CreateDefaultBuildinFileSystemParameters(IBundleDecryptionServices decryptionServices = null, string packageRoot = null) + public static FileSystemParameters CreateDefaultBuildinFileSystemParameters(string packageRoot = null) { string fileSystemClass = typeof(BuiltinFileSystem).FullName; var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot); - fileSystemParams.AddParameter(FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES, decryptionServices); return fileSystemParams; } @@ -95,14 +93,12 @@ namespace YooAsset /// 创建默认的缓存文件系统参数 /// /// 远端资源地址查询服务类 - /// 加密文件解密服务类 /// 文件系统的根目录 - public static FileSystemParameters CreateDefaultCacheFileSystemParameters(IRemoteServices remoteServices, IBundleDecryptionServices decryptionServices = null, string packageRoot = null) + public static FileSystemParameters CreateDefaultCacheFileSystemParameters(IRemoteServices remoteServices, string packageRoot = null) { string fileSystemClass = typeof(CacheFileSystem).FullName; var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot); fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices); - fileSystemParams.AddParameter(FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES, decryptionServices); return fileSystemParams; } @@ -111,11 +107,10 @@ namespace YooAsset /// /// 加密文件解密服务类 /// 禁用Unity的网络缓存 - public static FileSystemParameters CreateDefaultWebServerFileSystemParameters(IWebBundleDecryptionServices decryptionServices = null, bool disableUnityWebCache = false) + public static FileSystemParameters CreateDefaultWebServerFileSystemParameters(bool disableUnityWebCache = false) { string fileSystemClass = typeof(WebServerFileSystem).FullName; var fileSystemParams = new FileSystemParameters(fileSystemClass, null); - fileSystemParams.AddParameter(FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES, decryptionServices); fileSystemParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, disableUnityWebCache); return fileSystemParams; } @@ -126,12 +121,11 @@ namespace YooAsset /// 远端资源地址查询服务类 /// 加密文件解密服务类 /// 禁用Unity的网络缓存 - public static FileSystemParameters CreateDefaultWebRemoteFileSystemParameters(IRemoteServices remoteServices, IWebBundleDecryptionServices decryptionServices = null, bool disableUnityWebCache = false) + public static FileSystemParameters CreateDefaultWebRemoteFileSystemParameters(IRemoteServices remoteServices, bool disableUnityWebCache = false) { string fileSystemClass = typeof(WebRemoteFileSystem).FullName; var fileSystemParams = new FileSystemParameters(fileSystemClass, null); fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices); - fileSystemParams.AddParameter(FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES, decryptionServices); fileSystemParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, disableUnityWebCache); return fileSystemParams; } diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystemParametersConstants.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystemParametersConstants.cs index 3926348f..4009f23c 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystemParametersConstants.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystemParametersConstants.cs @@ -1,4 +1,4 @@ - + namespace YooAsset { public class FileSystemParametersDefine @@ -23,10 +23,15 @@ namespace YooAsset /// public const string REMOTE_SERVICES = "REMOTE_SERVICES"; - /// - /// 解密服务接口的实例类 + /// + /// 加载 AssetBundle 的 Operation 工厂委托 /// - public const string BUNDLE_DECRYPTION_SERVICES = "BUNDLE_DECRYPTION_SERVICES"; + public const string LOAD_ASSETBUNDLE_OPERATION_FACTORY = "LOAD_ASSETBUNDLE_OPERATION_FACTORY"; + + /// + /// 加载 RawBundle 的 Operation 工厂委托 + /// + public const string LOAD_RAWBUNDLE_OPERATION_FACTORY = "LOAD_RAWBUNDLE_OPERATION_FACTORY"; /// /// 资源清单服务类 @@ -74,7 +79,7 @@ namespace YooAsset public const string DOWNLOAD_MAX_REQUEST_PER_FRAME = "DOWNLOAD_MAX_REQUEST_PER_FRAME"; /// - /// 下载任务的看门狗机制监控时间 + /// 下载任务的看门狗机制超时时间 /// public const string DOWNLOAD_WATCH_DOG_TIME = "DOWNLOAD_WATCH_DOG_TIME"; diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileSystem.cs index 9eb7fa84..38a312a2 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/BuiltinFileSystem.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Collections.Generic; using UnityEngine; @@ -105,9 +105,14 @@ namespace YooAsset public string UnpackFileSystemRoot { private set; get; } /// - /// 自定义参数:解密服务接口的实例类 + /// 自定义参数:加载 AssetBundle 的工厂委托 /// - public IBundleDecryptionServices BundleDecryptionServices { private set; get; } + public LoadAssetBundleOperationFactory LoadAssetBundleFactory { private set; get; } + + /// + /// 自定义参数:加载 RawBundle 的工厂委托 + /// + public LoadRawBundleOperationFactory LoadRawBundleFactory { private set; get; } /// /// 自定义参数:资源清单服务类 @@ -225,9 +230,13 @@ namespace YooAsset { UnpackFileSystemRoot = (string)value; } - else if (name == FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES) + else if (name == FileSystemParametersDefine.LOAD_ASSETBUNDLE_OPERATION_FACTORY) { - BundleDecryptionServices = (IBundleDecryptionServices)value; + LoadAssetBundleFactory = (LoadAssetBundleOperationFactory)value; + } + else if (name == FileSystemParametersDefine.LOAD_RAWBUNDLE_OPERATION_FACTORY) + { + LoadRawBundleFactory = (LoadRawBundleOperationFactory)value; } else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES) { @@ -255,6 +264,14 @@ namespace YooAsset if (DownloadBackend == null) DownloadBackend = new UnityWebRequestBackend(WebRequestCreator); + // 创建默认的 AssetBundle 加载工厂 + if (LoadAssetBundleFactory == null) + LoadAssetBundleFactory = DefaultLoadAssetBundleOperationFactory; + + // 创建默认的 RawBundle 加载工厂 + if (LoadRawBundleFactory == null) + LoadRawBundleFactory = DefaultLoadRawBundleOperationFactory; + // 创建解压文件系统 var remoteServices = new UnpackRemoteService(_packageRoot); _unpackFileSystem = new UnpackFileSystem(); @@ -265,7 +282,8 @@ namespace YooAsset _unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, FileVerifyLevel); _unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_MAX_CONCURRENCY, FileVerifyMaxConcurrency); _unpackFileSystem.SetParameter(FileSystemParametersDefine.APPEND_FILE_EXTENSION, AppendFileExtension); - _unpackFileSystem.SetParameter(FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES, BundleDecryptionServices); + _unpackFileSystem.SetParameter(FileSystemParametersDefine.LOAD_ASSETBUNDLE_OPERATION_FACTORY, LoadAssetBundleFactory); + _unpackFileSystem.SetParameter(FileSystemParametersDefine.LOAD_RAWBUNDLE_OPERATION_FACTORY, LoadRawBundleFactory); _unpackFileSystem.SetParameter(FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES, CopyLocalFileServices); _unpackFileSystem.OnCreate(packageName, UnpackFileSystemRoot); } @@ -315,88 +333,15 @@ namespace YooAsset { return false; } - public virtual string GetBundleFilePath(PackageBundle bundle) { if (IsUnpackBundleFile(bundle)) + { return _unpackFileSystem.GetBundleFilePath(bundle); + } return GetBuiltinFileLoadPath(bundle); } - public virtual byte[] ReadBundleFileData(PackageBundle bundle) - { - if (IsUnpackBundleFile(bundle)) - return _unpackFileSystem.ReadBundleFileData(bundle); - - if (Exists(bundle) == false) - return null; - -#if UNITY_ANDROID - //TODO : 安卓平台内置文件属于APK压缩包内的文件。 - YooLogger.Error($"Android platform not support read buildin bundle file data."); - return null; -#else - if (bundle.Encrypted) - { - if (DecryptionServices == null) - { - YooLogger.Error($"The {nameof(IDecryptionServices)} is null."); - return null; - } - - string filePath = GetBuildinFileLoadPath(bundle); - var fileInfo = new DecryptFileInfo() - { - BundleName = bundle.BundleName, - FileLoadCRC = bundle.UnityCRC, - FileLoadPath = filePath, - }; - return DecryptionServices.ReadFileData(fileInfo); - } - else - { - string filePath = GetBuildinFileLoadPath(bundle); - return FileUtility.ReadAllBytes(filePath); - } -#endif - } - public virtual string ReadBundleFileText(PackageBundle bundle) - { - if (IsUnpackBundleFile(bundle)) - return _unpackFileSystem.ReadBundleFileText(bundle); - - if (Exists(bundle) == false) - return null; - -#if UNITY_ANDROID - //TODO : 安卓平台内置文件属于APK压缩包内的文件。 - YooLogger.Error($"Android platform not support read buildin bundle file text."); - return null; -#else - if (bundle.Encrypted) - { - if (DecryptionServices == null) - { - YooLogger.Error($"The {nameof(IDecryptionServices)} is null."); - return null; - } - - string filePath = GetBuildinFileLoadPath(bundle); - var fileInfo = new DecryptFileInfo() - { - BundleName = bundle.BundleName, - FileLoadCRC = bundle.UnityCRC, - FileLoadPath = filePath, - }; - return DecryptionServices.ReadFileText(fileInfo); - } - else - { - string filePath = GetBuildinFileLoadPath(bundle); - return FileUtility.ReadAllText(filePath); - } -#endif - } /// /// 是否属于解压资源包文件 @@ -420,6 +365,30 @@ namespace YooAsset } #region 内部方法 + private LoadAssetBundleOperation DefaultLoadAssetBundleOperationFactory(bool bundleEncrypted, LoadAssetBundleOptions options) + { + if (bundleEncrypted) + { + string error = $"{nameof(DefaultLoadAssetBundleOperation)} cannot load encrypted bundle. Please provide a custom {nameof(LoadAssetBundleOperationFactory)}."; + return new LoadAssetBundleCompleteOperation(error, options); + } + else + { + return new DefaultLoadAssetBundleOperation(options); + } + } + private LoadRawBundleOperation DefaultLoadRawBundleOperationFactory(bool bundleEncrypted, LoadRawBundleOptions options) + { + if (bundleEncrypted) + { + string error = $"{nameof(DefaultLoadRawBundleOperation)} cannot load encrypted bundle. Please provide a custom {nameof(LoadRawBundleOperationFactory)}."; + return new LoadRawBundleCompleteOperation(error, options); + } + else + { + return new DefaultLoadRawBundleOperation(options); + } + } protected string GetDefaultBuiltinPackageRoot(string packageName) { string rootDirectory = YooAssetSettingsData.GetYooDefaultBuildinRoot(); @@ -476,36 +445,6 @@ namespace YooAsset { return _unpackFileSystem.InitializeAsync(); } - - /// - /// 加载加密的资源文件 - /// - public BundleDecryptionSyncResult LoadEncryptedBundleSync(PackageBundle bundle) - { - string filePath = GetBuiltinFileLoadPath(bundle); - var bundleInfo = new BundleDecryptionContext() - { - BundleName = bundle.BundleName, - FileLoadCRC = bundle.UnityCRC, - FileLoadPath = filePath, - }; - return BundleDecryptionServices.LoadAssetBundleSync(bundleInfo); - } - - /// - /// 加载加密的资源文件 - /// - public BundleDecryptionAsyncResult LoadEncryptedBundleAsync(PackageBundle bundle) - { - string filePath = GetBuiltinFileLoadPath(bundle); - var bundleInfo = new BundleDecryptionContext() - { - BundleName = bundle.BundleName, - FileLoadCRC = bundle.UnityCRC, - FileLoadPath = filePath, - }; - return BundleDecryptionServices.LoadAssetBundleAsync(bundleInfo); - } #endregion } } diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSLoadBundleOperation.cs index 1b3ab00e..37670f3b 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSLoadBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/BuiltinFileSystem/Operation/BFSLoadBundleOperation.cs @@ -1,26 +1,24 @@ -using System.IO; +using System.IO; using UnityEngine; namespace YooAsset { /// - /// 加载AssetBundle文件 + /// 加载 AssetBundle 文件 /// internal class BFSLoadAssetBundleOperation : FSLoadBundleOperation { private enum ESteps { None, - LoadAssetBundle, + LoadBuiltinAssetBundle, CheckResult, Done, } private readonly BuiltinFileSystem _fileSystem; private readonly PackageBundle _bundle; - private AssetBundleCreateRequest _createRequest; - private AssetBundle _assetBundle; - private Stream _managedStream; + private LoadAssetBundleOperation _loadAssetBundleOp; private ESteps _steps = ESteps.None; @@ -33,99 +31,55 @@ namespace YooAsset { DownloadProgress = 1f; DownloadedBytes = _bundle.FileSize; - _steps = ESteps.LoadAssetBundle; + _steps = ESteps.LoadBuiltinAssetBundle; } internal override void InternalUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.LoadAssetBundle) + if (_steps == ESteps.LoadBuiltinAssetBundle) { - if (_bundle.Encrypted) - { - if (_fileSystem.BundleDecryptionServices == null) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"The {nameof(IBundleDecryptionServices)} is null."; - YooLogger.Error(Error); - return; - } - } - - if (IsWaitingForAsyncComplete) - { - if (_bundle.Encrypted) - { - var decryptResult = _fileSystem.LoadEncryptedBundleSync(_bundle); - _assetBundle = decryptResult.Result; - _managedStream = decryptResult.ManagedStream; - } - else - { - string filePath = _fileSystem.GetBuiltinFileLoadPath(_bundle); - _assetBundle = AssetBundle.LoadFromFile(filePath); - } - } - else - { - if (_bundle.Encrypted) - { - var decryptResult = _fileSystem.LoadEncryptedBundleAsync(_bundle); - _createRequest = decryptResult.CreateRequest; - _managedStream = decryptResult.ManagedStream; - } - else - { - string filePath = _fileSystem.GetBuiltinFileLoadPath(_bundle); - _createRequest = AssetBundle.LoadFromFileAsync(filePath); - } - } - + var options = new LoadAssetBundleOptions(); + options.FileLoadPath = _fileSystem.GetBuiltinFileLoadPath(_bundle); + options.Bundle = _bundle; + _loadAssetBundleOp = _fileSystem.LoadAssetBundleFactory.Invoke(_bundle.Encrypted, options); + _loadAssetBundleOp.StartOperation(); + AddChildOperation(_loadAssetBundleOp); _steps = ESteps.CheckResult; } if (_steps == ESteps.CheckResult) { - if (_createRequest != null) - { - if (IsWaitingForAsyncComplete) - { - // 强制挂起主线程(注意:该操作会很耗时) - YooLogger.Warning("Suspend the main thread to load unity bundle."); - _assetBundle = _createRequest.assetBundle; - } - else - { - if (_createRequest.isDone == false) - return; - _assetBundle = _createRequest.assetBundle; - } - } + if (IsWaitingForAsyncComplete) + _loadAssetBundleOp.WaitForAsyncComplete(); - if (_assetBundle == null) + _loadAssetBundleOp.UpdateOperation(); + if (_loadAssetBundleOp.IsDone == false) + return; + + if (_loadAssetBundleOp.Status == EOperationStatus.Succeed) { - if (_bundle.Encrypted) + if (_loadAssetBundleOp.Result == null) { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Failed to load encrypted buildin asset bundle file : {_bundle.BundleName}"; + Error = "Loaded builtin asset bundle is null."; YooLogger.Error(Error); } else { _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Failed to load buildin asset bundle file : {_bundle.BundleName}"; - YooLogger.Error(Error); + Result = new AssetBundleResult(_fileSystem, _bundle, _loadAssetBundleOp.Result, _loadAssetBundleOp.ManagedStream); + Status = EOperationStatus.Succeed; } } else { _steps = ESteps.Done; - Result = new AssetBundleResult(_fileSystem, _bundle, _assetBundle, _managedStream); - Status = EOperationStatus.Succeed; + Status = EOperationStatus.Failed; + Error = _loadAssetBundleOp.Error; + YooLogger.Error(Error); } } } @@ -136,7 +90,7 @@ namespace YooAsset } /// - /// 加载原生文件 + /// 加载 RawBundle 文件 /// internal class BFSLoadRawBundleOperation : FSLoadBundleOperation { @@ -144,11 +98,13 @@ namespace YooAsset { None, LoadBuiltinRawBundle, + CheckResult, Done, } private readonly BuiltinFileSystem _fileSystem; private readonly PackageBundle _bundle; + private LoadRawBundleOperation _loadRawBundleOp; private ESteps _steps = ESteps.None; @@ -170,29 +126,47 @@ namespace YooAsset if (_steps == ESteps.LoadBuiltinRawBundle) { - string filePath = _fileSystem.GetBuiltinFileLoadPath(_bundle); + var options = new LoadRawBundleOptions(); + options.FileLoadPath = _fileSystem.GetBuiltinFileLoadPath(_bundle); + options.Bundle = _bundle; + _loadRawBundleOp = _fileSystem.LoadRawBundleFactory.Invoke(_bundle.Encrypted, options); + _loadRawBundleOp.StartOperation(); + AddChildOperation(_loadRawBundleOp); + _steps = ESteps.CheckResult; + } -#if UNITY_ANDROID - //TODO : 安卓平台内置文件属于APK压缩包内的文件。 - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Can not load android buildin raw bundle file : {filePath}"; - YooLogger.Error(Error); -#else - if (File.Exists(filePath)) + if (_steps == ESteps.CheckResult) + { + if (IsWaitingForAsyncComplete) + _loadRawBundleOp.WaitForAsyncComplete(); + + _loadRawBundleOp.UpdateOperation(); + if (_loadRawBundleOp.IsDone == false) + return; + + if (_loadRawBundleOp.Status == EOperationStatus.Succeed) { - _steps = ESteps.Done; - Result = new RawBundleResult(_fileSystem, _bundle); - Status = EOperationStatus.Succeed; + if (_loadRawBundleOp.Result == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Loaded builtin raw bundle is null."; + YooLogger.Error(Error); + } + else + { + _steps = ESteps.Done; + Result = new RawBundleResult(_fileSystem, _bundle, _loadRawBundleOp.Result); + Status = EOperationStatus.Succeed; + } } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Can not found buildin raw bundle file : {filePath}"; + Error = _loadRawBundleOp.Error; YooLogger.Error(Error); } -#endif } } internal override void InternalWaitForAsyncComplete() diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/CacheFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/CacheFileSystem.cs index 8f164a79..979cd93c 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/CacheFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/CacheFileSystem.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Collections.Generic; using System.Linq; @@ -112,9 +112,9 @@ namespace YooAsset public int DownloadMaxRequestPerFrame { private set; get; } = 5; /// - /// 自定义参数:下载任务的看门狗机制监控时间 + /// 自定义参数:下载任务的看门狗机制超时时间 /// - public int DownloadWatchDogTime { private set; get; } = 0; + public int DownloadWatchDogTimeout { private set; get; } = 0; /// /// 自定义参数:启用断点续传的最小尺寸 @@ -127,9 +127,14 @@ namespace YooAsset public List ResumeDownloadResponseCodes { private set; get; } = null; /// - /// 自定义参数:解密服务接口的实例类 + /// 自定义参数:加载 AssetBundle 的工厂委托 /// - public IBundleDecryptionServices BundleDecryptionServices { private set; get; } + public LoadAssetBundleOperationFactory LoadAssetBundleFactory { private set; get; } + + /// + /// 自定义参数:加载 RawBundle 的工厂委托 + /// + public LoadRawBundleOperationFactory LoadRawBundleFactory { private set; get; } /// /// 自定义参数:资源清单服务类 @@ -307,7 +312,7 @@ namespace YooAsset else if (name == FileSystemParametersDefine.DOWNLOAD_WATCH_DOG_TIME) { int convertValue = Convert.ToInt32(value); - DownloadWatchDogTime = Mathf.Clamp(convertValue, 0, int.MaxValue); + DownloadWatchDogTimeout = Mathf.Clamp(convertValue, 0, int.MaxValue); } else if (name == FileSystemParametersDefine.RESUME_DOWNLOAD_MINMUM_SIZE) { @@ -317,9 +322,13 @@ namespace YooAsset { ResumeDownloadResponseCodes = (List)value; } - else if (name == FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES) + else if (name == FileSystemParametersDefine.LOAD_ASSETBUNDLE_OPERATION_FACTORY) { - BundleDecryptionServices = (IBundleDecryptionServices)value; + LoadAssetBundleFactory = (LoadAssetBundleOperationFactory)value; + } + else if (name == FileSystemParametersDefine.LOAD_RAWBUNDLE_OPERATION_FACTORY) + { + LoadRawBundleFactory = (LoadRawBundleOperationFactory)value; } else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES) { @@ -350,6 +359,14 @@ namespace YooAsset // 创建默认的下载后台接口 if (DownloadBackend == null) DownloadBackend = new UnityWebRequestBackend(WebRequestCreator); + + // 创建默认的 AssetBundle 加载工厂 + if (LoadAssetBundleFactory == null) + LoadAssetBundleFactory = DefaultLoadAssetBundleOperationFactory; + + // 创建默认的 RawBundle 加载工厂 + if (LoadRawBundleFactory == null) + LoadRawBundleFactory = DefaultLoadRawBundleOperationFactory; } public virtual void OnDestroy() { @@ -393,74 +410,17 @@ namespace YooAsset return Exists(bundle) == false; } - public virtual string GetBundleFilePath(PackageBundle bundle) { return GetCacheBundleFileLoadPath(bundle); } - public virtual byte[] ReadBundleFileData(PackageBundle bundle) - { - if (Exists(bundle) == false) - return null; - - if (bundle.Encrypted) - { - if (BundleDecryptionServices == null) - { - YooLogger.Error($"The {nameof(IBundleDecryptionServices)} is null."); - return null; - } - - string filePath = GetCacheBundleFileLoadPath(bundle); - var bundleInfo = new BundleDecryptionContext() - { - BundleName = bundle.BundleName, - FileLoadCRC = bundle.UnityCRC, - FileLoadPath = filePath, - }; - return BundleDecryptionServices.ReadFileData(bundleInfo); - } - else - { - string filePath = GetCacheBundleFileLoadPath(bundle); - return FileUtility.ReadAllBytes(filePath); - } - } - public virtual string ReadBundleFileText(PackageBundle bundle) - { - if (Exists(bundle) == false) - return null; - - if (bundle.Encrypted) - { - if (BundleDecryptionServices == null) - { - YooLogger.Error($"The {nameof(IBundleDecryptionServices)} is null."); - return null; - } - - string filePath = GetCacheBundleFileLoadPath(bundle); - var bundleInfo = new BundleDecryptionContext() - { - BundleName = bundle.BundleName, - FileLoadCRC = bundle.UnityCRC, - FileLoadPath = filePath, - }; - return BundleDecryptionServices.ReadFileText(bundleInfo); - } - else - { - string filePath = GetCacheBundleFileLoadPath(bundle); - return FileUtility.ReadAllText(filePath); - } - } #region 缓存相关 public List GetAllCachedBundleGUIDs() { return _records.Keys.ToList(); } - public FileCacheEntry GetRecordFileElement(PackageBundle bundle) + public FileCacheEntry GetRecordFileEntry(PackageBundle bundle) { if (_records.TryGetValue(bundle.BundleGUID, out FileCacheEntry element)) return element; @@ -504,7 +464,7 @@ namespace YooAsset { return _records.ContainsKey(bundleGUID); } - public bool RecordBundleFile(string bundleGUID, FileCacheEntry element) + public bool RecordBundleFile(string bundleGUID, FileCacheEntry entry) { if (_records.ContainsKey(bundleGUID)) { @@ -512,7 +472,7 @@ namespace YooAsset return false; } - _records.Add(bundleGUID, element); + _records.Add(bundleGUID, entry); return true; } @@ -594,6 +554,30 @@ namespace YooAsset #endregion #region 内部方法 + private LoadAssetBundleOperation DefaultLoadAssetBundleOperationFactory(bool bundleEncrypted, LoadAssetBundleOptions options) + { + if (bundleEncrypted) + { + string error = $"{nameof(DefaultLoadAssetBundleOperation)} cannot load encrypted bundle. Please provide a custom {nameof(LoadAssetBundleOperationFactory)}."; + return new LoadAssetBundleCompleteOperation(error, options); + } + else + { + return new DefaultLoadAssetBundleOperation(options); + } + } + private LoadRawBundleOperation DefaultLoadRawBundleOperationFactory(bool bundleEncrypted, LoadRawBundleOptions options) + { + if (bundleEncrypted) + { + string error = $"{nameof(DefaultLoadRawBundleOperation)} cannot load encrypted bundle. Please provide a custom {nameof(LoadRawBundleOperationFactory)}."; + return new LoadRawBundleCompleteOperation(error, options); + } + else + { + return new DefaultLoadRawBundleOperation(options); + } + } public string GetDefaultCachePackageRoot(string packageName) { string rootDirectory = YooAssetSettingsData.GetYooDefaultCacheRoot(); @@ -647,51 +631,6 @@ namespace YooAsset Directory.Delete(_cacheManifestFilesRoot, true); } } - - /// - /// 加载加密资源文件 - /// - public BundleDecryptionSyncResult LoadEncryptedBundleSync(PackageBundle bundle) - { - string filePath = GetCacheBundleFileLoadPath(bundle); - var bundleInfo = new BundleDecryptionContext() - { - BundleName = bundle.BundleName, - FileLoadCRC = bundle.UnityCRC, - FileLoadPath = filePath, - }; - return BundleDecryptionServices.LoadAssetBundleSync(bundleInfo); - } - - /// - /// 加载加密资源文件 - /// - public BundleDecryptionAsyncResult LoadEncryptedBundleAsync(PackageBundle bundle) - { - string filePath = GetCacheBundleFileLoadPath(bundle); - var bundleInfo = new BundleDecryptionContext() - { - BundleName = bundle.BundleName, - FileLoadCRC = bundle.UnityCRC, - FileLoadPath = filePath, - }; - return BundleDecryptionServices.LoadAssetBundleAsync(bundleInfo); - } - - /// - /// 加载加密资源文件 - /// - public BundleDecryptionSyncResult LoadEncryptedBundleFallback(PackageBundle bundle) - { - string filePath = GetCacheBundleFileLoadPath(bundle); - var bundleInfo = new BundleDecryptionContext() - { - BundleName = bundle.BundleName, - FileLoadCRC = bundle.UnityCRC, - FileLoadPath = filePath, - }; - return BundleDecryptionServices.LoadAssetBundleFallback(bundleInfo); - } #endregion } } diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/FileCacheEntry.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/FileCacheEntry.cs index 3a3cb516..3b028a19 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/FileCacheEntry.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/FileCacheEntry.cs @@ -18,6 +18,14 @@ namespace YooAsset DataFileSize = dataFileSize; } + /// + /// 修正内容 + /// + public void Modify(string dataFilePath) + { + DataFilePath = dataFilePath; + } + /// /// 删除记录文件 /// diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSLoadBundleOperation.cs index 9d5c1d14..6660db52 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSLoadBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/CFSLoadBundleOperation.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using UnityEngine; @@ -12,17 +12,16 @@ namespace YooAsset CheckExist, DownloadFile, AbortDownload, - LoadAssetBundle, + LoadCacheAssetBundle, CheckResult, + TryFallback, Done, } protected readonly CacheFileSystem _fileSystem; protected readonly PackageBundle _bundle; protected FSDownloadFileOperation _downloadFileOp; - protected AssetBundleCreateRequest _createRequest; - private AssetBundle _assetBundle; - private Stream _managedStream; + protected LoadAssetBundleOperation _loadAssetBundleOp; protected ESteps _steps = ESteps.None; @@ -46,7 +45,7 @@ namespace YooAsset { DownloadProgress = 1f; DownloadedBytes = _bundle.FileSize; - _steps = ESteps.LoadAssetBundle; + _steps = ESteps.LoadCacheAssetBundle; } else { @@ -96,7 +95,7 @@ namespace YooAsset if (_downloadFileOp.Status == EOperationStatus.Succeed) { - _steps = ESteps.LoadAssetBundle; + _steps = ESteps.LoadCacheAssetBundle; } else { @@ -123,140 +122,92 @@ namespace YooAsset Error = "Abort download file."; } - if (_steps == ESteps.LoadAssetBundle) + if (_steps == ESteps.LoadCacheAssetBundle) { - if (_bundle.Encrypted) - { - if (_fileSystem.BundleDecryptionServices == null) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"The {nameof(IBundleDecryptionServices)} is null."; - YooLogger.Error(Error); - return; - } - } - - if (IsWaitingForAsyncComplete) - { - if (_bundle.Encrypted) - { - var decryptResult = _fileSystem.LoadEncryptedBundleSync(_bundle); - _assetBundle = decryptResult.Result; - _managedStream = decryptResult.ManagedStream; - } - else - { - string filePath = _fileSystem.GetCacheBundleFileLoadPath(_bundle); - _assetBundle = AssetBundle.LoadFromFile(filePath); - } - } - else - { - if (_bundle.Encrypted) - { - var decryptResult = _fileSystem.LoadEncryptedBundleAsync(_bundle); - _createRequest = decryptResult.CreateRequest; - _managedStream = decryptResult.ManagedStream; - } - else - { - string filePath = _fileSystem.GetCacheBundleFileLoadPath(_bundle); - _createRequest = AssetBundle.LoadFromFileAsync(filePath); - } - } - + var options = new LoadAssetBundleOptions(); + options.FileLoadPath = _fileSystem.GetCacheBundleFileLoadPath(_bundle); + options.Bundle = _bundle; + _loadAssetBundleOp = _fileSystem.LoadAssetBundleFactory.Invoke(_bundle.Encrypted, options); + _loadAssetBundleOp.StartOperation(); + AddChildOperation(_loadAssetBundleOp); _steps = ESteps.CheckResult; } if (_steps == ESteps.CheckResult) { - if (_createRequest != null) + if (IsWaitingForAsyncComplete) + _loadAssetBundleOp.WaitForAsyncComplete(); + + _loadAssetBundleOp.UpdateOperation(); + if (_loadAssetBundleOp.IsDone == false) + return; + + if (_loadAssetBundleOp.Status == EOperationStatus.Succeed) { - if (IsWaitingForAsyncComplete) + if (_loadAssetBundleOp.Result == null) { - // 强制挂起主线程(注意:该操作会很耗时) - YooLogger.Warning("Suspend the main thread to load unity bundle."); - _assetBundle = _createRequest.assetBundle; + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Loaded cache asset bundle is null."; + YooLogger.Error(Error); } else { - if (_createRequest.isDone == false) - return; - _assetBundle = _createRequest.assetBundle; + _steps = ESteps.Done; + Result = new AssetBundleResult(_fileSystem, _bundle, _loadAssetBundleOp.Result, _loadAssetBundleOp.ManagedStream); + Status = EOperationStatus.Succeed; } } - - if (_assetBundle != null) + else { - _steps = ESteps.Done; - Result = new AssetBundleResult(_fileSystem, _bundle, _assetBundle, _managedStream); - Status = EOperationStatus.Succeed; - return; + if (_loadAssetBundleOp is LoadAssetBundleCompleteOperation) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadAssetBundleOp.Error; + YooLogger.Error(Error); + } + else + { + // 加载失败,尝试后备加载 + _steps = ESteps.TryFallback; + } } + } + if (_steps == ESteps.TryFallback) + { // 注意:当缓存文件的校验等级为Low的时候,并不能保证缓存文件的完整性。 // 说明:在AssetBundle文件加载失败的情况下,我们需要重新验证文件的完整性! EFileVerifyResult verifyResult = _fileSystem.VerifyCacheFile(_bundle); if (verifyResult == EFileVerifyResult.Succeed) { - if (_bundle.Encrypted) - { - var decryptResult = _fileSystem.LoadEncryptedBundleFallback(_bundle); - _assetBundle = decryptResult.Result; - if (_assetBundle != null) - { - _steps = ESteps.Done; - Result = new AssetBundleResult(_fileSystem, _bundle, _assetBundle, _managedStream); - Status = EOperationStatus.Succeed; - return; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Failed to load encrypted asset bundle file : {_bundle.BundleName}"; - YooLogger.Error(Error); - return; - } - } - + // 调用后备加载方法 // 注意:在安卓移动平台,华为和三星真机上有极小概率加载资源包失败。 // 说明:大多数情况在首次安装下载资源到沙盒内,游戏过程中切换到后台再回到游戏内有很大概率触发! - string filePath = _fileSystem.GetCacheBundleFileLoadPath(_bundle); - byte[] fileData = FileUtility.ReadAllBytes(filePath); - if (fileData != null && fileData.Length > 0) + AssetBundle assetBundle = _loadAssetBundleOp.LoadFromMemory(); + if (assetBundle != null) { - _assetBundle = AssetBundle.LoadFromMemory(fileData); - if (_assetBundle == null) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = $"Failed to load asset bundle from memory : {_bundle.BundleName}"; - YooLogger.Error(Error); - } - else - { - _steps = ESteps.Done; - Result = new AssetBundleResult(_fileSystem, _bundle, _assetBundle, null); - Status = EOperationStatus.Succeed; - } + _steps = ESteps.Done; + Result = new AssetBundleResult(_fileSystem, _bundle, assetBundle, null); + Status = EOperationStatus.Succeed; } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Failed to read asset bundle file bytes : {_bundle.BundleName}"; + Error = $"Failed to load asset bundle from memory : {_bundle.BundleName}"; YooLogger.Error(Error); } } else { + // 文件损坏,删除缓存 _steps = ESteps.Done; - _fileSystem.DeleteCacheBundleFile(_bundle.BundleGUID); Status = EOperationStatus.Failed; Error = $"Find corrupted asset bundle file and delete : {_bundle.BundleName}"; YooLogger.Error(Error); + _fileSystem.DeleteCacheBundleFile(_bundle.BundleGUID); } } } @@ -275,12 +226,14 @@ namespace YooAsset DownloadFile, AbortDownload, LoadCacheRawBundle, + CheckResult, Done, } protected readonly CacheFileSystem _fileSystem; protected readonly PackageBundle _bundle; protected FSDownloadFileOperation _downloadFileOp; + protected LoadRawBundleOperation _loadRawBundleOp; protected ESteps _steps = ESteps.None; @@ -309,15 +262,16 @@ namespace YooAsset { try { - var recordFileElement = _fileSystem.GetRecordFileElement(_bundle); - File.Move(recordFileElement.DataFilePath, filePath); + var entry = _fileSystem.GetRecordFileEntry(_bundle); + File.Move(entry.DataFilePath, filePath); + entry.Modify(filePath); _steps = ESteps.LoadCacheRawBundle; } catch (Exception ex) { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Faild rename raw data file : {ex.Message}"; + Error = $"Faild rename cached data file : {ex.Message}"; } } else @@ -394,18 +348,45 @@ namespace YooAsset if (_steps == ESteps.LoadCacheRawBundle) { - string filePath = _fileSystem.GetCacheBundleFileLoadPath(_bundle); - if (File.Exists(filePath)) + var options = new LoadRawBundleOptions(); + options.FileLoadPath = _fileSystem.GetCacheBundleFileLoadPath(_bundle); + options.Bundle = _bundle; + _loadRawBundleOp = _fileSystem.LoadRawBundleFactory.Invoke(_bundle.Encrypted, options); + _loadRawBundleOp.StartOperation(); + AddChildOperation(_loadRawBundleOp); + _steps = ESteps.CheckResult; + } + + if (_steps == ESteps.CheckResult) + { + if (IsWaitingForAsyncComplete) + _loadRawBundleOp.WaitForAsyncComplete(); + + _loadRawBundleOp.UpdateOperation(); + if (_loadRawBundleOp.IsDone == false) + return; + + if (_loadRawBundleOp.Status == EOperationStatus.Succeed) { - _steps = ESteps.Done; - Result = new RawBundleResult(_fileSystem, _bundle); - Status = EOperationStatus.Succeed; + if (_loadRawBundleOp.Result == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Loaded cache raw bundle is null."; + YooLogger.Error(Error); + } + else + { + _steps = ESteps.Done; + Result = new RawBundleResult(_fileSystem, _bundle, _loadRawBundleOp.Result); + Status = EOperationStatus.Succeed; + } } else { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"Can not found cache raw bundle file : {filePath}"; + Error = _loadRawBundleOp.Error; YooLogger.Error(Error); } } diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs index 17df9299..3c8ce0ee 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs @@ -57,7 +57,7 @@ namespace YooAsset string savePath = _fileSystem.GetCachePackageHashFilePath(_packageVersion); string fileName = YooAssetSettingsData.GetPackageHashFileName(_fileSystem.PackageName, _packageVersion); string webURL = GetWebRequestURL(fileName); - int watchdogTime = _fileSystem.DownloadWatchDogTime; + int watchdogTime = _fileSystem.DownloadWatchDogTimeout; var args = new DownloadFileRequestArgs(webURL, savePath, _timeout, watchdogTime); _webFileRequestOp = _fileSystem.DownloadBackend.CreateFileRequest(args); _webFileRequestOp.SendRequest(); diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs index dc963cbb..1cf6e524 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs @@ -57,7 +57,7 @@ namespace YooAsset string savePath = _fileSystem.GetCachePackageManifestFilePath(_packageVersion); string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_fileSystem.PackageName, _packageVersion); string webURL = GetDownloadRequestURL(fileName); - int watchdogTime = _fileSystem.DownloadWatchDogTime; + int watchdogTime = _fileSystem.DownloadWatchDogTimeout; var args = new DownloadFileRequestArgs(webURL, savePath, _timeout, watchdogTime); _webFileRequestOp = _fileSystem.DownloadBackend.CreateFileRequest(args); _webFileRequestOp.SendRequest(); diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/RequestRemotePackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/RequestRemotePackageVersionOperation.cs index 36505f19..5a032bb1 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/RequestRemotePackageVersionOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/RequestRemotePackageVersionOperation.cs @@ -45,7 +45,7 @@ namespace YooAsset { string fileName = YooAssetSettingsData.GetPackageVersionFileName(_fileSystem.PackageName); string url = GetWebRequestURL(fileName); - int watchDogTime = _fileSystem.DownloadWatchDogTime; + int watchDogTime = _fileSystem.DownloadWatchDogTimeout; var args = new DownloadDataRequestArgs(url, _timeout, watchDogTime); _webTextRequestOp = _fileSystem.DownloadBackend.CreateTextRequest(args); _webTextRequestOp.SendRequest(); diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs index dd3c484e..45552246 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheLocalFileOperation.cs @@ -87,7 +87,7 @@ namespace YooAsset // 创建下载请求 if (_steps == ESteps.CreateRequest) { - int watchdogTime = _fileSystem.DownloadWatchDogTime; + int watchdogTime = _fileSystem.DownloadWatchDogTimeout; int timeout = 0; //注意:文件下载不做超时检测 var args = new DownloadFileRequestArgs(URL, _tempFilePath, timeout, watchdogTime); _request = _fileSystem.DownloadBackend.CreateFileRequest(args); diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs index 235c15f9..de14d494 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/CacheFileSystem/Operation/internal/Scheduler/DownloadAndCacheRemoteFileOperation.cs @@ -171,7 +171,7 @@ namespace YooAsset } } - int watchdogTime = _fileSystem.DownloadWatchDogTime; + int watchdogTime = _fileSystem.DownloadWatchDogTimeout; int timeout = 0; //注意:文件下载不做超时检测 bool appendToFile = true; bool removeFileOnAbort = false; @@ -185,7 +185,7 @@ namespace YooAsset if (File.Exists(_tempFilePath)) File.Delete(_tempFilePath); - int watchdogTime = _fileSystem.DownloadWatchDogTime; + int watchdogTime = _fileSystem.DownloadWatchDogTimeout; int timeout = 0; //注意:文件下载不做超时检测 var args = new DownloadFileRequestArgs(URL, _tempFilePath, timeout, watchdogTime); return _fileSystem.DownloadBackend.CreateFileRequest(args); diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/EditorFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/EditorFileSystem.cs index 1c751fdb..7a8b686e 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/EditorFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/EditorFileSystem/EditorFileSystem.cs @@ -208,7 +208,6 @@ namespace YooAsset { return false; } - public virtual string GetBundleFilePath(PackageBundle bundle) { if (bundle.IncludeMainAssets.Count == 0) @@ -217,22 +216,6 @@ namespace YooAsset var pacakgeAsset = bundle.IncludeMainAssets[0]; return pacakgeAsset.AssetPath; } - public virtual byte[] ReadBundleFileData(PackageBundle bundle) - { - if (bundle.IncludeMainAssets.Count == 0) - return null; - - var pacakgeAsset = bundle.IncludeMainAssets[0]; - return FileUtility.ReadAllBytes(pacakgeAsset.AssetPath); - } - public virtual string ReadBundleFileText(PackageBundle bundle) - { - if (bundle.IncludeMainAssets.Count == 0) - return null; - - var pacakgeAsset = bundle.IncludeMainAssets[0]; - return FileUtility.ReadAllText(pacakgeAsset.AssetPath); - } #region 内部方法 public void RecordDownloadFile(PackageBundle bundle) diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebAssetBundleOperation.cs deleted file mode 100644 index 5662cc2b..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebAssetBundleOperation.cs +++ /dev/null @@ -1,22 +0,0 @@ -using UnityEngine; - -namespace YooAsset -{ - internal abstract class LoadWebAssetBundleOperation : AsyncOperationBase - { - /// - /// AssetBundle对象 - /// - public AssetBundle Result; - - /// - /// 下载进度 - /// - public float DownloadProgress { protected set; get; } = 0; - - /// - /// 下载大小 - /// - public long DownloadedBytes { protected set; get; } = 0; - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebEncryptAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebEncryptAssetBundleOperation.cs deleted file mode 100644 index ae95252d..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebEncryptAssetBundleOperation.cs +++ /dev/null @@ -1,146 +0,0 @@ -using UnityEngine; - -namespace YooAsset -{ - internal class LoadWebEncryptAssetBundleOperation : LoadWebAssetBundleOperation - { - protected enum ESteps - { - None, - CreateRequest, - CheckRequest, - TryAgain, - Done, - } - - private readonly DownloadFileOptions _options; - private readonly IWebBundleDecryptionServices _decryptionServices; - private readonly IDownloadBackend _downloadBackend; - private IDownloadBytesRequest _unityWebDataRequestOp; - - private int _requestCount = 0; - private float _tryAgainTimer = 0; - private int _failedTryAgain; - private ESteps _steps = ESteps.None; - - internal LoadWebEncryptAssetBundleOperation(DownloadFileOptions options, IWebBundleDecryptionServices decryptionServices, IDownloadBackend downloadBackend) - { - _options = options; - _failedTryAgain = options.FailedTryAgain; - _decryptionServices = decryptionServices; - _downloadBackend = downloadBackend; - } - 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(IWebBundleDecryptionServices)} is null."; - YooLogger.Error(Error); - return; - } - - string url = GetRequestURL(); - var args = new DownloadDataRequestArgs(url, 0, 0); - _unityWebDataRequestOp = _downloadBackend.CreateBytesRequest(args); - _unityWebDataRequestOp.SendRequest(); - _steps = ESteps.CheckRequest; - } - - // 检测下载结果 - if (_steps == ESteps.CheckRequest) - { - Progress = _unityWebDataRequestOp.DownloadProgress; - DownloadProgress = _unityWebDataRequestOp.DownloadProgress; - DownloadedBytes = _unityWebDataRequestOp.DownloadedBytes; - if (_unityWebDataRequestOp.IsDone == false) - return; - - // 检查网络错误 - if (_unityWebDataRequestOp.Status == EDownloadRequestStatus.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 WebBundleDecryptionContext(); - fileInfo.BundleName = _options.Bundle.BundleName; - fileInfo.FileLoadCRC = _options.Bundle.UnityCRC; - fileInfo.FileData = fileData; - var decryptResult = _decryptionServices.LoadAssetBundleSync(fileInfo); - return decryptResult.Result; - } - - /// - /// 获取网络请求地址 - /// - protected string GetRequestURL() - { - // 轮流返回请求地址 - _requestCount++; - if (_requestCount % 2 == 0) - return _options.FallbackURL; - else - return _options.MainURL; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebNormalAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebNormalAssetBundleOperation.cs deleted file mode 100644 index d27e4b1d..00000000 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebGameFileSystem/Operation/LoadWebNormalAssetBundleOperation.cs +++ /dev/null @@ -1,114 +0,0 @@ -using UnityEngine; - -namespace YooAsset -{ - internal class LoadWebNormalAssetBundleOperation : LoadWebAssetBundleOperation - { - protected enum ESteps - { - None, - CreateRequest, - CheckRequest, - TryAgain, - Done, - } - - private readonly DownloadFileOptions _options; - private readonly bool _disableUnityWebCache; - private readonly IDownloadBackend _downloadBackend; - private IDownloadAssetBundleRequest _unityAssetBundleRequestOp; - - private int _requestCount = 0; - private float _tryAgainTimer = 0; - private int _failedTryAgain; - private ESteps _steps = ESteps.None; - - - internal LoadWebNormalAssetBundleOperation(DownloadFileOptions options, bool disableUnityWebCache, IDownloadBackend downloadBackend) - { - _options = options; - _failedTryAgain = options.FailedTryAgain; - _disableUnityWebCache = disableUnityWebCache; - _downloadBackend = downloadBackend; - } - internal override void InternalStart() - { - _steps = ESteps.CreateRequest; - } - internal override void InternalUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - // 创建下载器 - if (_steps == ESteps.CreateRequest) - { - string url = GetRequestURL(); - var args = new DownloadAssetBundleRequestArgs(url, 0, 0, _disableUnityWebCache, _options.Bundle.FileHash, _options.Bundle.UnityCRC); - _unityAssetBundleRequestOp = _downloadBackend.CreateAssetBundleRequest(args); - _unityAssetBundleRequestOp.SendRequest(); - _steps = ESteps.CheckRequest; - } - - // 检测下载结果 - if (_steps == ESteps.CheckRequest) - { - Progress = _unityAssetBundleRequestOp.DownloadProgress; - DownloadedBytes = _unityAssetBundleRequestOp.DownloadedBytes; - DownloadProgress = _unityAssetBundleRequestOp.DownloadProgress; - if (_unityAssetBundleRequestOp.IsDone == false) - return; - - if (_unityAssetBundleRequestOp.Status == EDownloadRequestStatus.Succeed) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - Result = _unityAssetBundleRequestOp.Result; - } - else - { - if (_failedTryAgain > 0) - { - _steps = ESteps.TryAgain; - YooLogger.Warning($"Failed download : {_unityAssetBundleRequestOp.URL} Try again."); - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = _unityAssetBundleRequestOp.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; - } - } - } - - /// - /// 获取网络请求地址 - /// - protected string GetRequestURL() - { - // 轮流返回请求地址 - _requestCount++; - if (_requestCount % 2 == 0) - return _options.FallbackURL; - else - return _options.MainURL; - } - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSLoadBundleOperation.cs index 6e1e197d..f5ae804a 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSLoadBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/Operation/WRFSLoadBundleOperation.cs @@ -34,23 +34,17 @@ namespace YooAsset { if (_loadWebAssetBundleOp == null) { - string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName); - string fallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName); - DownloadFileOptions options = new DownloadFileOptions(_bundle, int.MaxValue); - options.SetURL(mainURL, fallbackURL); - - if (_bundle.Encrypted) - { - _loadWebAssetBundleOp = new LoadWebEncryptAssetBundleOperation(options, _fileSystem.BundleDecryptionServices, _fileSystem.DownloadBackend); - _loadWebAssetBundleOp.StartOperation(); - AddChildOperation(_loadWebAssetBundleOp); - } - else - { - _loadWebAssetBundleOp = new LoadWebNormalAssetBundleOperation(options, _fileSystem.DisableUnityWebCache, _fileSystem.DownloadBackend); - _loadWebAssetBundleOp.StartOperation(); - AddChildOperation(_loadWebAssetBundleOp); - } + var options = new LoadWebAssetBundleOptions(); + options.Bundle = _bundle; + options.FailedTryAgain = int.MaxValue; + options.WatchdogTimeout = _fileSystem.DownloadWatchDogTimeout; + options.DownloadBackend = _fileSystem.DownloadBackend; + options.DisableUnityWebCache = _fileSystem.DisableUnityWebCache; + options.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName); + options.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName); + _loadWebAssetBundleOp = _fileSystem.LoadAssetBundleFactory.Invoke(_bundle.Encrypted, options); + _loadWebAssetBundleOp.StartOperation(); + AddChildOperation(_loadWebAssetBundleOp); } _loadWebAssetBundleOp.UpdateOperation(); @@ -62,17 +56,16 @@ namespace YooAsset if (_loadWebAssetBundleOp.Status == EOperationStatus.Succeed) { - var assetBundle = _loadWebAssetBundleOp.Result; - if (assetBundle == null) + if (_loadWebAssetBundleOp.Result == null) { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"{nameof(WRFSLoadAssetBundleOperation)} loaded asset bundle is null."; + Error = $"Loaded asset bundle object is null."; } else { _steps = ESteps.Done; - Result = new AssetBundleResult(_fileSystem, _bundle, assetBundle, null); + Result = new AssetBundleResult(_fileSystem, _bundle, _loadWebAssetBundleOp.Result, null); Status = EOperationStatus.Succeed; } } diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/WebRemoteFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/WebRemoteFileSystem.cs index 9a730520..0d0b7d5a 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/WebRemoteFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebRemoteFileSystem/WebRemoteFileSystem.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Collections.Generic; using UnityEngine; @@ -53,15 +53,20 @@ namespace YooAsset /// public bool DisableUnityWebCache { private set; get; } = false; + /// + /// 自定义参数:下载任务的看门狗机制超时时间 + /// + public int DownloadWatchDogTimeout { private set; get; } = 0; + /// /// 自定义参数:远程服务接口的实例类(支持跨域下载) /// public IRemoteServices RemoteServices { private set; get; } /// - /// 自定义参数:解密服务接口的实例类 + /// 自定义参数:加载 AssetBundle 的工厂委托 /// - public IWebBundleDecryptionServices BundleDecryptionServices { private set; get; } + public LoadWebAssetBundleOperationFactory LoadAssetBundleFactory { private set; get; } /// /// 自定义参数:资源清单服务类 @@ -127,13 +132,18 @@ namespace YooAsset { DisableUnityWebCache = Convert.ToBoolean(value); } + else if (name == FileSystemParametersDefine.DOWNLOAD_WATCH_DOG_TIME) + { + int convertValue = Convert.ToInt32(value); + DownloadWatchDogTimeout = Mathf.Clamp(convertValue, 0, int.MaxValue); + } else if (name == FileSystemParametersDefine.REMOTE_SERVICES) { RemoteServices = (IRemoteServices)value; } - else if (name == FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES) + else if (name == FileSystemParametersDefine.LOAD_ASSETBUNDLE_OPERATION_FACTORY) { - BundleDecryptionServices = (IWebBundleDecryptionServices)value; + LoadAssetBundleFactory = (LoadWebAssetBundleOperationFactory)value; } else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES) { @@ -151,6 +161,10 @@ namespace YooAsset // 创建默认的下载后台接口 if (DownloadBackend == null) DownloadBackend = new UnityWebRequestBackend(WebRequestCreator); + + // 创建默认的 AssetBundle 加载工厂 + if (LoadAssetBundleFactory == null) + LoadAssetBundleFactory = DefaultLoadAssetBundleOperationFactory; } public virtual void OnDestroy() { @@ -181,21 +195,24 @@ namespace YooAsset { return false; } - public virtual string GetBundleFilePath(PackageBundle bundle) { throw new System.NotImplementedException(); } - public virtual byte[] ReadBundleFileData(PackageBundle bundle) - { - throw new System.NotImplementedException(); - } - public virtual string ReadBundleFileText(PackageBundle bundle) - { - throw new System.NotImplementedException(); - } #region 内部方法 + private LoadWebAssetBundleOperation DefaultLoadAssetBundleOperationFactory(bool bundleEncrypted, LoadWebAssetBundleOptions options) + { + if (bundleEncrypted) + { + string error = $"{nameof(DefaultLoadWebAssetBundleOperation)} cannot load encrypted bundle. Please provide a custom {nameof(LoadWebAssetBundleOperationFactory)}."; + return new LoadWebAssetBundleCompleteOperation(error, options); + } + else + { + return new DefaultLoadWebAssetBundleOperation(options); + } + } #endregion } } diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSLoadBundleOperation.cs index 3e60517b..b6812dd3 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSLoadBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/Operation/WSFSLoadBundleOperation.cs @@ -36,21 +36,18 @@ namespace YooAsset { string fileLoadPath = _fileSystem.GetWebFileLoadPath(_bundle); string mainURL = DownloadSystemTools.ToLocalURL(fileLoadPath); - DownloadFileOptions options = new DownloadFileOptions(_bundle, int.MaxValue); - options.SetURL(mainURL, mainURL); - if (_bundle.Encrypted) - { - _loadWebAssetBundleOp = new LoadWebEncryptAssetBundleOperation(options, _fileSystem.BundleDecryptionServices, _fileSystem.DownloadBackend); - _loadWebAssetBundleOp.StartOperation(); - AddChildOperation(_loadWebAssetBundleOp); - } - else - { - _loadWebAssetBundleOp = new LoadWebNormalAssetBundleOperation(options, _fileSystem.DisableUnityWebCache, _fileSystem.DownloadBackend); - _loadWebAssetBundleOp.StartOperation(); - AddChildOperation(_loadWebAssetBundleOp); - } + var options = new LoadWebAssetBundleOptions(); + options.Bundle = _bundle; + options.FailedTryAgain = int.MaxValue; + options.WatchdogTimeout = _fileSystem.DownloadWatchDogTimeout; + options.DownloadBackend = _fileSystem.DownloadBackend; + options.DisableUnityWebCache = _fileSystem.DisableUnityWebCache; + options.MainURL = mainURL; + options.FallbackURL = mainURL; + _loadWebAssetBundleOp = _fileSystem.LoadAssetBundleFactory.Invoke(_bundle.Encrypted, options); + _loadWebAssetBundleOp.StartOperation(); + AddChildOperation(_loadWebAssetBundleOp); } _loadWebAssetBundleOp.UpdateOperation(); @@ -62,17 +59,16 @@ namespace YooAsset if (_loadWebAssetBundleOp.Status == EOperationStatus.Succeed) { - var assetBundle = _loadWebAssetBundleOp.Result; - if (assetBundle == null) + if (_loadWebAssetBundleOp.Result == null) { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = $"{nameof(WSFSLoadAssetBundleOperation)} loaded asset bundle is null."; + Error = $"Loaded asset bundle object is null."; } else { _steps = ESteps.Done; - Result = new AssetBundleResult(_fileSystem, _bundle, assetBundle, null); + Result = new AssetBundleResult(_fileSystem, _bundle, _loadWebAssetBundleOp.Result, null); Status = EOperationStatus.Succeed; } } diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/WebServerFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/WebServerFileSystem.cs index 88714b52..50381076 100644 --- a/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/WebServerFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/FileSystems/WebServerFileSystem/WebServerFileSystem.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Collections.Generic; using UnityEngine; @@ -68,9 +68,14 @@ namespace YooAsset public bool DisableUnityWebCache { private set; get; } = false; /// - /// 自定义参数:解密服务接口的实例类 + /// 自定义参数:下载任务的看门狗机制超时时间 /// - public IWebBundleDecryptionServices BundleDecryptionServices { private set; get; } + public int DownloadWatchDogTimeout { private set; get; } = 0; + + /// + /// 自定义参数:加载 AssetBundle 的工厂委托 + /// + public LoadWebAssetBundleOperationFactory LoadAssetBundleFactory { private set; get; } /// /// 自定义参数:资源清单服务类 @@ -136,9 +141,14 @@ namespace YooAsset { DisableUnityWebCache = Convert.ToBoolean(value); } - else if (name == FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES) + else if (name == FileSystemParametersDefine.DOWNLOAD_WATCH_DOG_TIME) { - BundleDecryptionServices = (IWebBundleDecryptionServices)value; + int convertValue = Convert.ToInt32(value); + DownloadWatchDogTimeout = Mathf.Clamp(convertValue, 0, int.MaxValue); + } + else if (name == FileSystemParametersDefine.LOAD_ASSETBUNDLE_OPERATION_FACTORY) + { + LoadAssetBundleFactory = (LoadWebAssetBundleOperationFactory)value; } else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES) { @@ -161,6 +171,10 @@ namespace YooAsset // 创建默认的下载后台接口 if (DownloadBackend == null) DownloadBackend = new UnityWebRequestBackend(WebRequestCreator); + + // 创建默认的 AssetBundle 加载工厂 + if (LoadAssetBundleFactory == null) + LoadAssetBundleFactory = DefaultLoadAssetBundleOperationFactory; } public virtual void OnDestroy() { @@ -191,21 +205,24 @@ namespace YooAsset { return false; } - public virtual string GetBundleFilePath(PackageBundle bundle) { throw new System.NotImplementedException(); } - public virtual byte[] ReadBundleFileData(PackageBundle bundle) - { - throw new System.NotImplementedException(); - } - public virtual string ReadBundleFileText(PackageBundle bundle) - { - throw new System.NotImplementedException(); - } #region 内部方法 + private LoadWebAssetBundleOperation DefaultLoadAssetBundleOperationFactory(bool bundleEncrypted, LoadWebAssetBundleOptions options) + { + if (bundleEncrypted) + { + string error = $"{nameof(DefaultLoadWebAssetBundleOperation)} cannot load encrypted bundle. Please provide a custom {nameof(LoadWebAssetBundleOperationFactory)}."; + return new LoadWebAssetBundleCompleteOperation(error, options); + } + else + { + return new DefaultLoadWebAssetBundleOperation(options); + } + } protected string GetDefaultWebPackageRoot(string packageName) { string rootDirectory = YooAssetSettingsData.GetYooDefaultBuildinRoot(); diff --git a/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs index 48b7e1a9..bf5908b5 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs @@ -91,20 +91,9 @@ namespace YooAsset /// bool NeedImport(PackageBundle bundle); - /// - /// 获取Bundle文件路径 + /// 获取资源包本地路径 /// string GetBundleFilePath(PackageBundle bundle); - - /// - /// 读取Bundle文件的二进制数据 - /// - byte[] ReadBundleFileData(PackageBundle bundle); - - /// - /// 读取Bundle文件的文本数据 - /// - string ReadBundleFileText(PackageBundle bundle); } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadBundleOperation.cs index 19c6d3ce..da57ee96 100644 --- a/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadBundleOperation.cs +++ b/Assets/YooAsset/Runtime/FileSystem/Operation/FSLoadBundleOperation.cs @@ -11,12 +11,12 @@ namespace YooAsset /// /// 下载进度 /// - public float DownloadProgress { protected set; get; } = 0; + public float DownloadProgress { protected set; get; } /// /// 下载大小 /// - public long DownloadedBytes { protected set; get; } = 0; + public long DownloadedBytes { protected set; get; } /// /// 终止下载文件 diff --git a/Assets/YooAsset/Runtime/ResourceManager/Handle/RawFileHandle.cs b/Assets/YooAsset/Runtime/ResourceManager/Handle/RawFileHandle.cs index ebf85eda..3936d174 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Handle/RawFileHandle.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Handle/RawFileHandle.cs @@ -45,27 +45,6 @@ namespace YooAsset Provider.WaitForAsyncComplete(); } - - /// - /// 获取原生文件的二进制数据 - /// - public byte[] GetRawFileData() - { - if (IsValidWithWarning == false) - return null; - return Provider.BundleResultObject.ReadBundleFileData(); - } - - /// - /// 获取原生文件的文本数据 - /// - public string GetRawFileText() - { - if (IsValidWithWarning == false) - return null; - return Provider.BundleResultObject.ReadBundleFileText(); - } - /// /// 获取原生文件的路径 /// @@ -73,7 +52,7 @@ namespace YooAsset { if (IsValidWithWarning == false) return string.Empty; - return Provider.BundleResultObject.GetBundleFilePath(); + return Provider.LoadedBundleResult.GetBundleFilePath(); } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Handle/SceneHandle.cs b/Assets/YooAsset/Runtime/ResourceManager/Handle/SceneHandle.cs index ffe0914f..593d004f 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Handle/SceneHandle.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Handle/SceneHandle.cs @@ -56,7 +56,7 @@ namespace YooAsset { if (IsValidWithWarning == false) return string.Empty; - return Provider.SceneName; + return Provider.LoadedSceneName; } } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadSceneOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadSceneOperation.cs index 47f2fee5..fa982a8d 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadSceneOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadSceneOperation.cs @@ -112,7 +112,7 @@ namespace YooAsset } internal override string InternalGetDescription() { - return $"SceneName : {_provider.SceneName}"; + return $"SceneName : {_provider.LoadedSceneName}"; } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/AllAssetsProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/AllAssetsProvider.cs index 6a532a8d..2237d955 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/AllAssetsProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/AllAssetsProvider.cs @@ -12,7 +12,7 @@ namespace YooAsset { if (_loadAllAssetsOp == null) { - _loadAllAssetsOp = BundleResultObject.LoadAllAssetsAsync(MainAssetInfo); + _loadAllAssetsOp = LoadedBundleResult.LoadAllAssetsAsync(MainAssetInfo); _loadAllAssetsOp.StartOperation(); AddChildOperation(_loadAllAssetsOp); diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/AssetProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/AssetProvider.cs index 0b0e2f5d..af1e21d4 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/AssetProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/AssetProvider.cs @@ -12,7 +12,7 @@ namespace YooAsset { if (_loadAssetOp == null) { - _loadAssetOp = BundleResultObject.LoadAssetAsync(MainAssetInfo); + _loadAssetOp = LoadedBundleResult.LoadAssetAsync(MainAssetInfo); _loadAssetOp.StartOperation(); AddChildOperation(_loadAssetOp); diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs index ab62554b..e7109ed8 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs @@ -48,14 +48,14 @@ namespace YooAsset public UnityEngine.SceneManagement.Scene SceneObject { protected set; get; } /// - /// 获取的资源包对象 + /// 加载的资源包结果 /// - public BundleResult BundleResultObject { protected set; get; } + public BundleResult LoadedBundleResult { protected set; get; } /// /// 加载的场景名称 /// - public string SceneName { protected set; get; } + public string LoadedSceneName { protected set; get; } /// /// 引用计数 @@ -165,8 +165,8 @@ namespace YooAsset } // 检测加载结果 - BundleResultObject = _mainBundleLoader.Result; - if (BundleResultObject == null) + LoadedBundleResult = _mainBundleLoader.Result; + if (LoadedBundleResult == null) { string error = $"Loaded bundle result is null."; InvokeCompletion(error, EOperationStatus.Failed); diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/SceneProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/SceneProvider.cs index 4a5a4814..bff838a2 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/SceneProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/SceneProvider.cs @@ -16,13 +16,13 @@ namespace YooAsset { _loadParams = loadParams; _suspendLoad = suspendLoad; - SceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath); + LoadedSceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath); } protected override void ProcessBundleResult() { if (_loadSceneOp == null) { - _loadSceneOp = BundleResultObject.LoadSceneOperation(MainAssetInfo, _loadParams, _suspendLoad); + _loadSceneOp = LoadedBundleResult.LoadSceneOperation(MainAssetInfo, _loadParams, _suspendLoad); _loadSceneOp.StartOperation(); AddChildOperation(_loadSceneOp); } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/SubAssetsProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/SubAssetsProvider.cs index 3e3a9532..ccc7d6b7 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/SubAssetsProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/SubAssetsProvider.cs @@ -12,7 +12,7 @@ namespace YooAsset { if (_loadSubAssetsOp == null) { - _loadSubAssetsOp = BundleResultObject.LoadSubAssetsAsync(MainAssetInfo); + _loadSubAssetsOp = LoadedBundleResult.LoadSubAssetsAsync(MainAssetInfo); _loadSubAssetsOp.StartOperation(); AddChildOperation(_loadSubAssetsOp); diff --git a/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs b/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs index 32ed56e8..067098a5 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs @@ -723,7 +723,7 @@ namespace YooAsset } #endregion - #region 资源加载 [全部资源] + #region 资源加载 [全资源] /// /// 同步加载资源包内所有资源对象 /// diff --git a/Assets/YooAsset/Runtime/Services/IBundleDecryptionServices.cs b/Assets/YooAsset/Runtime/Services/IBundleDecryptionServices.cs deleted file mode 100644 index c8dc7631..00000000 --- a/Assets/YooAsset/Runtime/Services/IBundleDecryptionServices.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System.IO; -using UnityEngine; - -namespace YooAsset -{ - public struct BundleDecryptionContext - { - /// - /// 资源包名称 - /// - public string BundleName; - - /// - /// 文件加载路径 - /// - public string FileLoadPath; - - /// - /// Unity引擎用于内容校验的CRC - /// - public uint FileLoadCRC; - } - public struct BundleDecryptionAsyncResult - { - /// - /// 异步请求句柄 - /// - public AssetBundleCreateRequest CreateRequest; - - /// - /// 托管流对象 - /// 注意:流对象在资源包对象释放的时候会自动释放 - /// - public Stream ManagedStream; - } - public struct BundleDecryptionSyncResult - { - /// - /// 资源包对象 - /// - public AssetBundle Result; - - /// - /// 托管流对象 - /// 注意:流对象在资源包对象释放的时候会自动释放 - /// - public Stream ManagedStream; - } - public interface IBundleDecryptionServices - { - /// - /// 同步方式获取解密的资源包 - /// - BundleDecryptionSyncResult LoadAssetBundleSync(BundleDecryptionContext bundleInfo); - - /// - /// 异步方式获取解密的资源包 - /// - BundleDecryptionAsyncResult LoadAssetBundleAsync(BundleDecryptionContext bundleInfo); - - /// - /// 后备方式获取解密的资源包 - /// 注意:当正常解密方法失败后,会触发后备加载! - /// 说明:建议通过LoadFromMemory()方法加载资源包作为保底机制。 - /// issues : https://github.com/tuyoogame/YooAsset/issues/562 - /// - BundleDecryptionSyncResult LoadAssetBundleFallback(BundleDecryptionContext bundleInfo); - - /// - /// 获取解密的字节数据 - /// - byte[] ReadFileData(BundleDecryptionContext bundleInfo); - - /// - /// 获取解密的文本数据 - /// - string ReadFileText(BundleDecryptionContext bundleInfo); - } - - public struct WebBundleDecryptionContext - { - /// - /// 资源包名称 - /// - public string BundleName; - - /// - /// Unity引擎用于内容校验的CRC - /// - public uint FileLoadCRC; - - /// - /// 文件字节数据 - /// - public byte[] FileData; - } - public struct WebBundleDecryptionSyncResult - { - /// - /// 资源包对象 - /// - public AssetBundle Result; - } - public interface IWebBundleDecryptionServices - { - WebBundleDecryptionSyncResult LoadAssetBundleSync(WebBundleDecryptionContext bundleInfo); - } -} diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileEncryption.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileEncryption.cs new file mode 100644 index 00000000..eb6eb891 --- /dev/null +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileEncryption.cs @@ -0,0 +1,136 @@ +using System; +using System.IO; +using YooAsset; + +public class BundleStream : FileStream +{ + public const byte KEY = 64; + + public BundleStream(string path, FileMode mode, FileAccess access, FileShare share) : base(path, mode, access, share) + { + } + public BundleStream(string path, FileMode mode) : base(path, mode) + { + } + public override int Read(byte[] array, int offset, int count) + { + var index = base.Read(array, offset, count); + for (int i = 0; i < array.Length; i++) + { + array[i] ^= KEY; + } + return index; + } +} +public class TestFileStreamEncryption : IBundleEncryptionServices +{ + public BundleEncryptionResult Encrypt(BundleEncryptionContext fileInfo) + { + // 说明:对TestRes3资源目录进行加密 + if (fileInfo.BundleName.Contains("_testres3_")) + { + var fileData = File.ReadAllBytes(fileInfo.FileLoadPath); + for (int i = 0; i < fileData.Length; i++) + { + fileData[i] ^= BundleStream.KEY; + } + + BundleEncryptionResult result = new BundleEncryptionResult(); + result.Encrypted = true; + result.EncryptedData = fileData; + return result; + } + else + { + BundleEncryptionResult result = new BundleEncryptionResult(); + result.Encrypted = false; + return result; + } + } +} +public class TestFileOffsetEncryption : IBundleEncryptionServices +{ + public BundleEncryptionResult Encrypt(BundleEncryptionContext fileInfo) + { + // 说明:对TestRes3资源目录进行加密 + if (fileInfo.BundleName.Contains("_testres3_")) + { + int offset = 32; + byte[] fileData = File.ReadAllBytes(fileInfo.FileLoadPath); + var encryptedData = new byte[fileData.Length + offset]; + Buffer.BlockCopy(fileData, 0, encryptedData, offset, fileData.Length); + + BundleEncryptionResult result = new BundleEncryptionResult(); + result.Encrypted = true; + result.EncryptedData = encryptedData; + return result; + } + else + { + BundleEncryptionResult result = new BundleEncryptionResult(); + result.Encrypted = false; + return result; + } + } +} + +public class TestLoadAssetBundleFromOffsetOperation : DefaultLoadAssetBundleFromOffsetOperation +{ + private const uint FILE_OFFSET = 32; + + public TestLoadAssetBundleFromOffsetOperation(LoadAssetBundleOptions options) : base(options) { } + + protected override uint GetFileOffset() + { + return FILE_OFFSET; + } +} +public class TestLoadAssetBundleFromMemoryOperation : DefaultLoadAssetBundleFromMemoryOperation +{ + public TestLoadAssetBundleFromMemoryOperation(LoadAssetBundleOptions options) : base(options) { } + + protected override byte[] DecryptData(byte[] data) + { + for (int i = 0; i < data.Length; i++) + { + data[i] ^= BundleStream.KEY; + } + return data; + } +} +public class TestLoadAssetBundleFromStreamOperation : DefaultLoadAssetBundleFromStreamOperation +{ + public TestLoadAssetBundleFromStreamOperation(LoadAssetBundleOptions options) : base(options) { } + + protected override FileStream CreateManagedFileStream() + { + var fileStream = new BundleStream(_options.FileLoadPath, FileMode.Open, FileAccess.Read, FileShare.Read); + return fileStream; + } + protected override uint GetManagedReadBufferSize() + { + return 1024; + } + protected override byte[] DecryptData(byte[] data) + { + for (int i = 0; i < data.Length; i++) + { + data[i] ^= BundleStream.KEY; + } + return data; + } +} +public class TestWebAssetBundleFromMemoryDecryption : DefaultLoadWebAssetBundleFromMemoryOperation +{ + public TestWebAssetBundleFromMemoryDecryption(LoadWebAssetBundleOptions opionts) : base(opionts) { } + + protected override byte[] Decryption(byte[] data) + { + for (int i = 0; i < data.Length; i++) + { + data[i] ^= BundleStream.KEY; + } + + return data; + } +} diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileStreamEncryption.cs.meta b/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileEncryption.cs.meta similarity index 100% rename from Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileStreamEncryption.cs.meta rename to Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileEncryption.cs.meta diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileOffsetEncryption.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileOffsetEncryption.cs deleted file mode 100644 index 43b4b3e1..00000000 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileOffsetEncryption.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.IO; -using System.Text; -using System.Collections; -using UnityEngine; -using YooAsset; - -/// -/// 文件偏移加密方式 -/// -public class TestFileOffsetEncryption : IBundleEncryptionServices -{ - public BundleEncryptionResult Encrypt(BundleEncryptionContext fileInfo) - { - // 说明:对TestRes3资源目录进行加密 - if (fileInfo.BundleName.Contains("_testres3_")) - { - int offset = 32; - byte[] fileData = File.ReadAllBytes(fileInfo.FileLoadPath); - var encryptedData = new byte[fileData.Length + offset]; - Buffer.BlockCopy(fileData, 0, encryptedData, offset, fileData.Length); - - BundleEncryptionResult result = new BundleEncryptionResult(); - result.Encrypted = true; - result.EncryptedData = encryptedData; - return result; - } - else - { - BundleEncryptionResult result = new BundleEncryptionResult(); - result.Encrypted = false; - return result; - } - } -} - -/// -/// 资源文件偏移解密类 -/// -public class TestFileOffsetDecryption : IBundleDecryptionServices -{ - /// - /// 同步方式获取解密的资源包对象 - /// 注意:加载流对象在资源包对象释放的时候会自动释放 - /// - BundleDecryptionSyncResult IBundleDecryptionServices.LoadAssetBundleSync(BundleDecryptionContext fileInfo) - { - var decryptResult = new BundleDecryptionSyncResult(); - decryptResult.ManagedStream = null; - decryptResult.Result = AssetBundle.LoadFromFile(fileInfo.FileLoadPath, fileInfo.FileLoadCRC, GetFileOffset()); - return decryptResult; - } - - /// - /// 异步方式获取解密的资源包对象 - /// 注意:加载流对象在资源包对象释放的时候会自动释放 - /// - BundleDecryptionAsyncResult IBundleDecryptionServices.LoadAssetBundleAsync(BundleDecryptionContext fileInfo) - { - BundleDecryptionAsyncResult decryptResult = new BundleDecryptionAsyncResult(); - decryptResult.ManagedStream = null; - decryptResult.CreateRequest = AssetBundle.LoadFromFileAsync(fileInfo.FileLoadPath, fileInfo.FileLoadCRC, GetFileOffset()); - return decryptResult; - } - - /// - /// 后备方式获取解密的资源包对象 - /// - BundleDecryptionSyncResult IBundleDecryptionServices.LoadAssetBundleFallback(BundleDecryptionContext fileInfo) - { - return new BundleDecryptionSyncResult(); - } - - /// - /// 获取解密的字节数据 - /// - byte[] IBundleDecryptionServices.ReadFileData(BundleDecryptionContext fileInfo) - { - throw new System.NotImplementedException(); - } - - /// - /// 获取解密的文本数据 - /// - string IBundleDecryptionServices.ReadFileText(BundleDecryptionContext fileInfo) - { - throw new System.NotImplementedException(); - } - - private static ulong GetFileOffset() - { - return 32; - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileStreamEncryption.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileStreamEncryption.cs deleted file mode 100644 index 909e29aa..00000000 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/CryptoSample/TestFileStreamEncryption.cs +++ /dev/null @@ -1,159 +0,0 @@ -using System; -using System.IO; -using System.Text; -using System.Collections; -using UnityEngine; -using YooAsset; - -/// -/// 资源文件解密流 -/// -public class BundleStream : FileStream -{ - public const byte KEY = 64; - - public BundleStream(string path, FileMode mode, FileAccess access, FileShare share) : base(path, mode, access, share) - { - } - public BundleStream(string path, FileMode mode) : base(path, mode) - { - } - - public override int Read(byte[] array, int offset, int count) - { - var index = base.Read(array, offset, count); - for (int i = 0; i < array.Length; i++) - { - array[i] ^= KEY; - } - return index; - } -} - -/// -/// 文件流加密方式 -/// -public class TestFileStreamEncryption : IBundleEncryptionServices -{ - public BundleEncryptionResult Encrypt(BundleEncryptionContext fileInfo) - { - // 说明:对TestRes3资源目录进行加密 - if (fileInfo.BundleName.Contains("_testres3_")) - { - var fileData = File.ReadAllBytes(fileInfo.FileLoadPath); - for (int i = 0; i < fileData.Length; i++) - { - fileData[i] ^= BundleStream.KEY; - } - - BundleEncryptionResult result = new BundleEncryptionResult(); - result.Encrypted = true; - result.EncryptedData = fileData; - return result; - } - else - { - BundleEncryptionResult result = new BundleEncryptionResult(); - result.Encrypted = false; - return result; - } - } -} - -/// -/// 资源文件流解密类 -/// -public class TestFileStreamDecryption : IBundleDecryptionServices -{ - /// - /// 同步方式获取解密的资源包对象 - /// - BundleDecryptionSyncResult IBundleDecryptionServices.LoadAssetBundleSync(BundleDecryptionContext fileInfo) - { - BundleStream bundleStream = new BundleStream(fileInfo.FileLoadPath, FileMode.Open, FileAccess.Read, FileShare.Read); - var decryptResult = new BundleDecryptionSyncResult(); - decryptResult.ManagedStream = bundleStream; - decryptResult.Result = AssetBundle.LoadFromStream(bundleStream, fileInfo.FileLoadCRC, GetManagedReadBufferSize()); - return decryptResult; - } - - /// - /// 异步方式获取解密的资源包对象 - /// - BundleDecryptionAsyncResult IBundleDecryptionServices.LoadAssetBundleAsync(BundleDecryptionContext fileInfo) - { - BundleStream bundleStream = new BundleStream(fileInfo.FileLoadPath, FileMode.Open, FileAccess.Read, FileShare.Read); - var decryptResult = new BundleDecryptionAsyncResult(); - decryptResult.ManagedStream = bundleStream; - decryptResult.CreateRequest = AssetBundle.LoadFromStreamAsync(bundleStream, fileInfo.FileLoadCRC, GetManagedReadBufferSize()); - return decryptResult; - } - - /// - /// 后备方式获取解密的资源包 - /// 注意:当正常解密方法失败后,会触发后备加载! - /// 说明:建议通过LoadFromMemory()方法加载资源包作为保底机制。 - /// - BundleDecryptionSyncResult IBundleDecryptionServices.LoadAssetBundleFallback(BundleDecryptionContext fileInfo) - { - byte[] fileData = File.ReadAllBytes(fileInfo.FileLoadPath); - var assetBundle = AssetBundle.LoadFromMemory(fileData); - var decryptResult = new BundleDecryptionSyncResult(); - decryptResult.Result = assetBundle; - return decryptResult; - } - - /// - /// 获取解密的字节数据 - /// - byte[] IBundleDecryptionServices.ReadFileData(BundleDecryptionContext fileInfo) - { - throw new System.NotImplementedException(); - } - - /// - /// 获取解密的文本数据 - /// - string IBundleDecryptionServices.ReadFileText(BundleDecryptionContext fileInfo) - { - throw new System.NotImplementedException(); - } - - private static uint GetManagedReadBufferSize() - { - return 1024; - } -} - -/// -/// WebGL平台解密类 -/// 注意:WebGL平台支持内存解密 -/// -public class TestWebFileMemoryDecryption : IWebBundleDecryptionServices -{ - public WebBundleDecryptionSyncResult LoadAssetBundleSync(WebBundleDecryptionContext fileInfo) - { - /* - byte[] copyData = new byte[fileInfo.FileData.Length]; - Buffer.BlockCopy(fileInfo.FileData, 0, copyData, 0, fileInfo.FileData.Length); - - for (int i = 0; i < copyData.Length; i++) - { - copyData[i] ^= BundleStream.KEY; - } - - WebDecryptResult decryptResult = new WebDecryptResult(); - decryptResult.Result = AssetBundle.LoadFromMemory(copyData); - return decryptResult; - */ - - for (int i = 0; i < fileInfo.FileData.Length; i++) - { - fileInfo.FileData[i] ^= BundleStream.KEY; - } - - WebBundleDecryptionSyncResult decryptResult = new WebBundleDecryptionSyncResult(); - decryptResult.Result = AssetBundle.LoadFromMemory(fileInfo.FileData); - return decryptResult; - } -} \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/T2_TestBuldinFileSystem.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/T2_TestBuldinFileSystem.cs index 8651066a..0ed2c895 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/T2_TestBuldinFileSystem.cs +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/T2_TestBuldinFileSystem/T2_TestBuldinFileSystem.cs @@ -60,9 +60,8 @@ public class T2_TestBuldinFileSystem : IPrebuildSetup, IPostBuildCleanup // 初始化资源包 var initParams = new OfflinePlayModeOptions(); - var fileDecryption = new TestFileStreamDecryption(); var manifestServices = new TestRestoreManifest(); - initParams.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(fileDecryption, packageRoot); + initParams.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(packageRoot); initParams.BuildinFileSystemParameters.AddParameter(FileSystemParametersDefine.DISABLE_CATALOG_FILE, true); initParams.BuildinFileSystemParameters.AddParameter(FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES, manifestServices); var initializeOp = package.InitializePackageAsync(initParams); @@ -100,7 +99,7 @@ public class T2_TestBuldinFileSystem : IPrebuildSetup, IPostBuildCleanup // 初始化资源包 var initParams = new OfflinePlayModeOptions(); - initParams.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(null, packageRoot); + initParams.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(packageRoot); initParams.BuildinFileSystemParameters.AddParameter(FileSystemParametersDefine.APPEND_FILE_EXTENSION, true); initParams.BuildinFileSystemParameters.AddParameter(FileSystemParametersDefine.DISABLE_CATALOG_FILE, true); var initializeOp = package.InitializePackageAsync(initParams); diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/T3_TestCacheFileSystem.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/T3_TestCacheFileSystem.cs index 632f5d92..8ce4d6d7 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/T3_TestCacheFileSystem.cs +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/T3_TestCacheFileSystem/T3_TestCacheFileSystem.cs @@ -45,13 +45,12 @@ public class T3_TestCacheFileSystem : IPrebuildSetup, IPostBuildCleanup // 初始化资源包 var initParams = new HostPlayModeOptions(); - var fileDecryption = new TestFileStreamDecryption(); var manifestServices = new TestRestoreManifest(); string hostServerIP = "http://127.0.0.1/CDN/Android/Test/"; var remoteServices = new TestRemoteServices(hostServerIP); initParams.BuildinFileSystemParameters = null; - initParams.CacheFileSystemParameters = FileSystemParameters.CreateDefaultCacheFileSystemParameters(remoteServices, fileDecryption); + initParams.CacheFileSystemParameters = FileSystemParameters.CreateDefaultCacheFileSystemParameters(remoteServices); initParams.CacheFileSystemParameters.AddParameter(FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES, manifestServices); var initializeOp = package.InitializePackageAsync(initParams); yield return initializeOp; diff --git a/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestLoadRawFile.cs b/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestLoadRawFile.cs index 721194cc..ae99e6ca 100644 --- a/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestLoadRawFile.cs +++ b/Assets/YooAsset/Samples~/Test Sample/Runtime/TestLoadAsset/TestLoadRawFile.cs @@ -24,13 +24,6 @@ public class TestLoadRawFile var filePath = rawFileHandle.GetRawFilePath(); Assert.IsNotNull(filePath); - - var fileText = rawFileHandle.GetRawFileText(); - TestLogger.Log(this, fileText); - Assert.IsNotNull(fileText); - - var fileData = rawFileHandle.GetRawFileData(); - Assert.IsNotNull(fileData); } // 测试同步加载 @@ -40,13 +33,6 @@ public class TestLoadRawFile var filePath = rawFileHandle.GetRawFilePath(); Assert.IsNotNull(filePath); - - var fileText = rawFileHandle.GetRawFileText(); - TestLogger.Log(this, fileText); - Assert.IsNotNull(fileText); - - var fileData = rawFileHandle.GetRawFileData(); - Assert.IsNotNull(fileData); } } } \ No newline at end of file