refactor : 重构代码

This commit is contained in:
何冠峰
2026-02-03 14:02:38 +08:00
parent c2d8b8efcb
commit 0ec07033f7
130 changed files with 1448 additions and 1111 deletions

Binary file not shown.

View File

@@ -83,7 +83,7 @@ namespace YooAsset.Editor
public static string GetPackageManifestProcessServicesClassName(string packageName, string buildPipeline)
{
string key = $"{Application.productName}_{packageName}_{buildPipeline}_ManifestProcessServicesClassName";
return EditorPrefs.GetString(key, $"{typeof(ManifestProcessNone).FullName}");
return EditorPrefs.GetString(key, $"{typeof(ManifestEncryptorNone).FullName}");
}
public static void SetPackageManifestProcessServicesClassName(string packageName, string buildPipeline, string encyptionClassName)
{
@@ -95,7 +95,7 @@ namespace YooAsset.Editor
public static string GetPackageManifestRestoreServicesClassName(string packageName, string buildPipeline)
{
string key = $"{Application.productName}_{packageName}_{buildPipeline}_ManifestRestoreServicesClassName";
return EditorPrefs.GetString(key, $"{typeof(ManifestRestoreNone).FullName}");
return EditorPrefs.GetString(key, $"{typeof(ManifestDecryptorNone).FullName}");
}
public static void SetPackageManifestRestoreServicesClassName(string packageName, string buildPipeline, string encyptionClassName)
{

View File

@@ -94,19 +94,19 @@ namespace YooAsset.Editor
public string BuildinFileCopyParams;
/// <summary>
/// 资源包加密服务类
/// 资源包加密
/// </summary>
public IBundleEncryptionServices EncryptionServices;
public IBundleEncryptor BundleEncryptor;
/// <summary>
/// 资源清单加密服务类
/// 资源清单加密
/// </summary>
public IManifestProcessServices ManifestProcessServices;
public IManifestEncryptor ManifestEncryptor;
/// <summary>
/// 资源清单解密服务类
/// 资源清单解密
/// </summary>
public IManifestRestoreServices ManifestRestoreServices;
public IManifestDecryptor ManifestDecryptor;
private string _pipelineOutputDirectory = string.Empty;
private string _packageOutputDirectory = string.Empty;

View File

@@ -14,7 +14,7 @@ namespace YooAsset.Editor
{
string buildinRootDirectory = buildParametersContext.GetBuildinRootDirectory();
string buildPackageName = buildParametersContext.Parameters.PackageName;
var manifestServices = buildParametersContext.Parameters.ManifestRestoreServices;
var manifestServices = buildParametersContext.Parameters.ManifestDecryptor;
BuiltinFileCatalogTools.CreateFile(manifestServices, buildPackageName, buildinRootDirectory);
// 刷新目录

View File

@@ -81,7 +81,7 @@ namespace YooAsset.Editor
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion);
packagePath = $"{packageOutputDirectory}/{fileName}";
PackageManifestTools.SerializeManifestToBinary(packagePath, manifest, buildParameters.ManifestProcessServices);
PackageManifestTools.SerializeManifestToBinary(packagePath, manifest, buildParameters.ManifestEncryptor);
packageHash = HashUtility.ComputeFileCRC32(packagePath);
BuildLogger.Log($"Create package manifest file: {packagePath}");
}
@@ -106,7 +106,7 @@ namespace YooAsset.Editor
{
ManifestContext manifestContext = new ManifestContext();
byte[] bytesData = FileUtility.ReadAllBytes(packagePath);
manifestContext.Manifest = PackageManifestTools.DeserializeManifestFromBinary(bytesData, buildParameters.ManifestRestoreServices);
manifestContext.Manifest = PackageManifestTools.DeserializeManifestFromBinary(bytesData, buildParameters.ManifestDecryptor);
context.SetContextObject(manifestContext);
}
}

View File

@@ -44,9 +44,9 @@ namespace YooAsset.Editor
buildReport.Summary.EnableSharePackRule = buildParameters.EnableSharePackRule;
buildReport.Summary.SingleReferencedPackAlone = buildParameters.SingleReferencedPackAlone;
buildReport.Summary.FileNameStyle = buildParameters.FileNameStyle;
buildReport.Summary.EncryptionServicesClassName = buildParameters.EncryptionServices == null ? "null" : buildParameters.EncryptionServices.GetType().FullName;
buildReport.Summary.ManifestProcessServicesClassName = buildParameters.ManifestProcessServices == null ? "null" : buildParameters.ManifestProcessServices.GetType().FullName;
buildReport.Summary.ManifestRestoreServicesClassName = buildParameters.ManifestRestoreServices == null ? "null" : buildParameters.ManifestRestoreServices.GetType().FullName;
buildReport.Summary.EncryptionServicesClassName = buildParameters.BundleEncryptor == null ? "null" : buildParameters.BundleEncryptor.GetType().FullName;
buildReport.Summary.ManifestProcessServicesClassName = buildParameters.ManifestEncryptor == null ? "null" : buildParameters.ManifestEncryptor.GetType().FullName;
buildReport.Summary.ManifestRestoreServicesClassName = buildParameters.ManifestDecryptor == null ? "null" : buildParameters.ManifestDecryptor.GetType().FullName;
if (buildParameters is BuiltinBuildParameters)
{

View File

@@ -13,7 +13,7 @@ namespace YooAsset.Editor
/// </summary>
public void EncryptingBundleFiles(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext)
{
var encryptionServices = buildParametersContext.Parameters.EncryptionServices;
var encryptionServices = buildParametersContext.Parameters.BundleEncryptor;
if (encryptionServices == null)
return;
@@ -24,14 +24,14 @@ namespace YooAsset.Editor
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
foreach (var bundleInfo in buildMapContext.Collection)
{
BundleEncryptionContext fileInfo = new BundleEncryptionContext();
fileInfo.BundleName = bundleInfo.BundleName;
fileInfo.FileLoadPath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
var encryptResult = encryptionServices.Encrypt(fileInfo);
BundleEncryptArgs args = new BundleEncryptArgs();
args.BundleName = bundleInfo.BundleName;
args.FilePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
var encryptResult = encryptionServices.Encrypt(args);
if (encryptResult.Encrypted)
{
string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}.encrypt";
FileUtility.WriteAllBytes(filePath, encryptResult.EncryptedData);
FileUtility.WriteAllBytes(filePath, encryptResult.EncryptedFileData);
bundleInfo.EncryptedFilePath = filePath;
bundleInfo.Encrypted = true;
BuildLogger.Log($"Bundle file encryption complete: {filePath}");

View File

@@ -1,9 +1,9 @@

namespace YooAsset.Editor
{
public class EncryptionNone : IBundleEncryptionServices
public class EncryptionNone : IBundleEncryptor
{
public BundleEncryptionResult Encrypt(BundleEncryptionContext fileInfo)
public BundleEncryptResult Encrypt(BundleEncryptArgs fileInfo)
{
throw new System.NotImplementedException();
}

View File

@@ -1,17 +1,17 @@

namespace YooAsset.Editor
{
public class ManifestProcessNone : IManifestProcessServices
public class ManifestEncryptorNone : IManifestEncryptor
{
byte[] IManifestProcessServices.ProcessManifest(byte[] fileData)
byte[] IManifestEncryptor.Encrypt(byte[] fileData)
{
return fileData;
}
}
public class ManifestRestoreNone : IManifestRestoreServices
public class ManifestDecryptorNone : IManifestDecryptor
{
byte[] IManifestRestoreServices.RestoreManifest(byte[] fileData)
byte[] IManifestDecryptor.Decrypt(byte[] fileData)
{
return fileData;
}

View File

@@ -44,43 +44,43 @@ namespace YooAsset.Editor
}
/// <summary>
/// 创建资源包加密服务类实例
/// 创建资源包加密实例
/// </summary>
protected IBundleEncryptionServices CreateEncryptionServicesInstance()
protected IBundleEncryptor CreateBundleEncryptorInstance()
{
var className = AssetBundleBuilderSetting.GetPackageEncyptionServicesClassName(PackageName, PipelineName);
var classTypes = EditorTools.GetAssignableTypes(typeof(IBundleEncryptionServices));
var classTypes = EditorTools.GetAssignableTypes(typeof(IBundleEncryptor));
var classType = classTypes.Find(x => x.FullName.Equals(className));
if (classType != null)
return (IBundleEncryptionServices)Activator.CreateInstance(classType);
return (IBundleEncryptor)Activator.CreateInstance(classType);
else
return null;
}
/// <summary>
/// 创建资源清单加密服务类实例
/// 创建资源清单加密实例
/// </summary>
protected IManifestProcessServices CreateManifestProcessServicesInstance()
protected IManifestEncryptor CreateManifestEncryptorInstance()
{
var className = AssetBundleBuilderSetting.GetPackageManifestProcessServicesClassName(PackageName, PipelineName);
var classTypes = EditorTools.GetAssignableTypes(typeof(IManifestProcessServices));
var classTypes = EditorTools.GetAssignableTypes(typeof(IManifestEncryptor));
var classType = classTypes.Find(x => x.FullName.Equals(className));
if (classType != null)
return (IManifestProcessServices)Activator.CreateInstance(classType);
return (IManifestEncryptor)Activator.CreateInstance(classType);
else
return null;
}
/// <summary>
/// 创建资源清单解密服务类实例
/// 创建资源清单解密实例
/// </summary>
protected IManifestRestoreServices CreateManifestRestoreServicesInstance()
protected IManifestDecryptor CreateManifestDecryptorInstance()
{
var className = AssetBundleBuilderSetting.GetPackageManifestRestoreServicesClassName(PackageName, PipelineName);
var classTypes = EditorTools.GetAssignableTypes(typeof(IManifestRestoreServices));
var classTypes = EditorTools.GetAssignableTypes(typeof(IManifestDecryptor));
var classType = classTypes.Find(x => x.FullName.Equals(className));
if (classType != null)
return (IManifestRestoreServices)Activator.CreateInstance(classType);
return (IManifestDecryptor)Activator.CreateInstance(classType);
else
return null;
}
@@ -184,7 +184,7 @@ namespace YooAsset.Editor
protected PopupField<Type> CreateEncryptionServicesField(VisualElement container)
{
// 资源包加密服务类
var classTypes = EditorTools.GetAssignableTypes(typeof(IBundleEncryptionServices));
var classTypes = EditorTools.GetAssignableTypes(typeof(IBundleEncryptor));
if (classTypes.Count > 0)
{
var className = AssetBundleBuilderSetting.GetPackageEncyptionServicesClassName(PackageName, PipelineName);
@@ -215,7 +215,7 @@ namespace YooAsset.Editor
protected PopupField<Type> CreateManifestProcessServicesField(VisualElement container)
{
// 资源清单加密服务类
var classTypes = EditorTools.GetAssignableTypes(typeof(IManifestProcessServices));
var classTypes = EditorTools.GetAssignableTypes(typeof(IManifestEncryptor));
if (classTypes.Count > 0)
{
var className = AssetBundleBuilderSetting.GetPackageManifestProcessServicesClassName(PackageName, PipelineName);
@@ -246,7 +246,7 @@ namespace YooAsset.Editor
protected PopupField<Type> CreateManifestRestoreServicesField(VisualElement container)
{
// 资源清单加密服务类
var classTypes = EditorTools.GetAssignableTypes(typeof(IManifestRestoreServices));
var classTypes = EditorTools.GetAssignableTypes(typeof(IManifestDecryptor));
if (classTypes.Count > 0)
{
var className = AssetBundleBuilderSetting.GetPackageManifestRestoreServicesClassName(PackageName, PipelineName);

View File

@@ -121,9 +121,9 @@ namespace YooAsset.Editor
buildParameters.CompressOption = compressOption;
buildParameters.ClearBuildCacheFiles = clearBuildCache;
buildParameters.UseAssetDependencyDB = useAssetDependencyDB;
buildParameters.EncryptionServices = CreateEncryptionServicesInstance();
buildParameters.ManifestProcessServices = CreateManifestProcessServicesInstance();
buildParameters.ManifestRestoreServices = CreateManifestRestoreServicesInstance();
buildParameters.BundleEncryptor = CreateBundleEncryptorInstance();
buildParameters.ManifestEncryptor = CreateManifestEncryptorInstance();
buildParameters.ManifestDecryptor = CreateManifestDecryptorInstance();
BuiltinBuildPipeline pipeline = new BuiltinBuildPipeline();
var buildResult = pipeline.Run(buildParameters, true);

View File

@@ -113,9 +113,9 @@ namespace YooAsset.Editor
buildParameters.BuildinFileCopyParams = buildinFileCopyParams;
buildParameters.ClearBuildCacheFiles = clearBuildCache;
buildParameters.UseAssetDependencyDB = useAssetDependencyDB;
buildParameters.EncryptionServices = CreateEncryptionServicesInstance();
buildParameters.ManifestProcessServices = CreateManifestProcessServicesInstance();
buildParameters.ManifestRestoreServices = CreateManifestRestoreServicesInstance();
buildParameters.BundleEncryptor = CreateBundleEncryptorInstance();
buildParameters.ManifestEncryptor = CreateManifestEncryptorInstance();
buildParameters.ManifestDecryptor = CreateManifestDecryptorInstance();
RawFileBuildPipeline pipeline = new RawFileBuildPipeline();
var buildResult = pipeline.Run(buildParameters, true);

View File

@@ -121,9 +121,9 @@ namespace YooAsset.Editor
buildParameters.CompressOption = compressOption;
buildParameters.ClearBuildCacheFiles = clearBuildCache;
buildParameters.UseAssetDependencyDB = useAssetDependencyDB;
buildParameters.EncryptionServices = CreateEncryptionServicesInstance();
buildParameters.ManifestProcessServices = CreateManifestProcessServicesInstance();
buildParameters.ManifestRestoreServices = CreateManifestRestoreServicesInstance();
buildParameters.BundleEncryptor = CreateBundleEncryptorInstance();
buildParameters.ManifestEncryptor = CreateManifestEncryptorInstance();
buildParameters.ManifestDecryptor = CreateManifestDecryptorInstance();
buildParameters.BuiltinShadersBundleName = GetBuiltinShaderBundleName();
ScriptableBuildPipeline pipeline = new ScriptableBuildPipeline();

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 1ca8ffceab2965e4c8892f62efa86e90
guid: c40f1ef3e0cc72f49903ce3b3a68d0cb
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -0,0 +1,162 @@
using System.IO;
using UnityEngine;
namespace YooAsset
{
internal class LoadLocalAssetBundleOperation : FCLoadBundleOperation
{
private enum ESteps
{
None,
LoadBundle,
CheckResult,
Done,
}
private readonly PackageBundle _bundle;
private readonly LoadLocalAssetBundleOptions _options;
private AssetBundleCreateRequest _createRequest;
private AssetBundle _assetBundle;
private Stream _loadStream;
private ESteps _steps = ESteps.None;
public bool UnityEngineLoadFailed = false;
public LoadLocalAssetBundleOperation(LoadLocalAssetBundleOptions options)
{
_options = options;
}
internal override void InternalStart()
{
_steps = ESteps.LoadBundle;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadBundle)
{
if (_bundle.IsEncrypted == false)
{
LoadFromFile();
}
else
{
var decryptor = _options.Decryptor;
if (decryptor == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{_options.CacheName} decryptor is null.";
return;
}
if (decryptor is IBundleOffsetDecryptor offsetDecryptor)
{
LoadFromFileWithOffset(offsetDecryptor);
}
else if (decryptor is IBundleMemoryDecryptor memoryDecryptor)
{
LoadFromMemory(memoryDecryptor);
}
else if (decryptor is IBundleStreamDecryptor streamDecryptor)
{
LoadFromStream(streamDecryptor);
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{_options.CacheName} not support {decryptor.GetType().Name}";
return;
}
}
_steps = ESteps.CheckResult;
}
if (_steps == ESteps.CheckResult)
{
if (_createRequest != null)
{
if (IsWaitForCompletion)
{
// ǿ<>ƹ<EFBFBD><C6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̣߳<DFB3>ע<EFBFBD><EFBFBD>ò<EFBFBD><C3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܺ<EFBFBD>ʱ<EFBFBD><CAB1>
YooLogger.Warning("Suspend the main thread to load unity bundle.");
_assetBundle = _createRequest.assetBundle;
}
else
{
if (_createRequest.isDone == false)
return;
_assetBundle = _createRequest.assetBundle;
}
}
if (_assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Unity engine load failed.";
UnityEngineLoadFailed = true;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = new AssetBundleResult(_options.FilePath, _options.Bundle, _assetBundle, _loadStream);
}
}
}
internal override void InternalWaitForCompletion()
{
ExecuteBatch();
}
private void LoadFromFile()
{
if (IsWaitForCompletion)
_assetBundle = AssetBundle.LoadFromFile(_options.FilePath);
else
_createRequest = AssetBundle.LoadFromFileAsync(_options.FilePath);
}
private void LoadFromFileWithOffset(IBundleOffsetDecryptor decryptor)
{
var args = new BundleDecryptArgs();
args.Bundle = _bundle;
args.FilePath = _options.FilePath;
uint offset = decryptor.GetFileOffset(args);
if (IsWaitForCompletion)
_assetBundle = AssetBundle.LoadFromFile(_options.FilePath, 0, offset);
else
_createRequest = AssetBundle.LoadFromFileAsync(_options.FilePath, 0, offset);
}
private void LoadFromMemory(IBundleMemoryDecryptor decryptor)
{
var args = new BundleDecryptArgs();
args.Bundle = _bundle;
args.FilePath = _options.FilePath;
var binaryData = decryptor.GetDecryptData(args);
if (IsWaitForCompletion)
_assetBundle = AssetBundle.LoadFromMemory(binaryData);
else
_createRequest = AssetBundle.LoadFromMemoryAsync(binaryData);
}
private void LoadFromStream(IBundleStreamDecryptor decryptor)
{
var args = new BundleDecryptArgs();
args.Bundle = _bundle;
args.FilePath = _options.FilePath;
uint bufferSize = decryptor.GetReadBufferSize(args);
_loadStream = decryptor.GetDecryptStream(args);
if (IsWaitForCompletion)
_assetBundle = AssetBundle.LoadFromStream(_loadStream, 0, bufferSize);
else
_createRequest = AssetBundle.LoadFromStreamAsync(_loadStream, 0, bufferSize);
}
}
}

View File

@@ -0,0 +1,30 @@
namespace YooAsset
{
/// <summary>
/// 加载 AssetBundle 的上下文信息
/// </summary>
internal struct LoadLocalAssetBundleOptions
{
/// <summary>
/// 文件缓存名称
/// </summary>
public string CacheName { get; set; }
/// <summary>
/// 资源包信息
/// </summary>
public PackageBundle Bundle { get; set; }
/// <summary>
/// 文件加载路径
/// </summary>
public string FilePath { get; set; }
/// <summary>
/// 解密接口
/// </summary>
public IBundleDecryptor Decryptor { get; set; }
}
}

View File

@@ -0,0 +1,111 @@
using System;
using System.IO;
namespace YooAsset
{
internal class LoadLocalRawBundleOperation : FCLoadBundleOperation
{
private enum ESteps
{
None,
LoadBundle,
CheckResult,
Done,
}
protected readonly LoadLocalRawBundleOptions _options;
private RawBundle _rawBundle;
private ESteps _steps = ESteps.None;
public LoadLocalRawBundleOperation(LoadLocalRawBundleOptions options)
{
_options = options;
}
internal override void InternalStart()
{
_steps = ESteps.LoadBundle;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadBundle)
{
if (_options.Bundle.IsEncrypted == false)
{
if (IsSupportFileIO(_options.FilePath) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"FileIO not supported for builtin path : {_options.FilePath}";
return;
}
LoadFromFile();
}
else
{
var decryptor = _options.Decryptor;
if (decryptor == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{_options.CacheName} decryptor is null.";
return;
}
if (decryptor is IBundleMemoryDecryptor memoryDecryptor)
{
LoadFromMemory(memoryDecryptor);
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{_options.CacheName} not support {decryptor.GetType().Name}";
return;
}
}
_steps = ESteps.CheckResult;
}
if (_steps == ESteps.CheckResult)
{
if (_rawBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Loaded raw bundle is null.";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = new RawBundleResult(_options.FilePath, _options.Bundle, _rawBundle);
}
}
}
internal override void InternalWaitForCompletion()
{
ExecuteBatch();
}
private void LoadFromFile()
{
byte[] data = File.ReadAllBytes(_options.FilePath);
if (data != null)
_rawBundle = new RawBundle(data);
}
private void LoadFromMemory(IBundleMemoryDecryptor decryptor)
{
var args = new BundleDecryptArgs();
args.Bundle = _options.Bundle;
args.FilePath = _options.FilePath;
var binaryData = decryptor.GetDecryptData(args);
if (binaryData != null)
_rawBundle = new RawBundle(binaryData);
}
}
}

View File

@@ -0,0 +1,29 @@
namespace YooAsset
{
/// <summary>
/// 加载 RawBundle 的上下文信息
/// </summary>
internal struct LoadLocalRawBundleOptions
{
/// <summary>
/// 文件缓存名称
/// </summary>
public string CacheName { get; set; }
/// <summary>
/// 资源包信息
/// </summary>
public PackageBundle Bundle { get; set; }
/// <summary>
/// 文件加载路径
/// </summary>
public string FilePath { get; set; }
/// <summary>
/// 解密接口
/// </summary>
public IBundleDecryptor Decryptor { get; set; }
}
}

View File

@@ -0,0 +1,252 @@
using UnityEngine;
namespace YooAsset
{
internal abstract class LoadWebAssetBundleOperation : FCLoadBundleOperation
{
}
internal class LoadWebNormalAssetBundleOperation : LoadWebAssetBundleOperation
{
private enum ESteps
{
None,
DownloadBundle,
CheckResult,
TryAgain,
Done,
}
protected readonly LoadWebAssetBundleOptions _options;
private IDownloadAssetBundleRequest _downloadAssetBundleRequest;
private ESteps _steps = ESteps.None;
// ʧ<><CAA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
private int _requestCount = 0;
private float _tryAgainTimer = 0;
private int _failedTryAgain;
public LoadWebNormalAssetBundleOperation(LoadWebAssetBundleOptions options)
{
_options = options;
_failedTryAgain = int.MaxValue; //ע<><EFBFBD><E2A3BA><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD>ʧ<EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>³<EFBFBD><C2B3><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD>ɹ<EFBFBD>
}
internal override void InternalStart()
{
_steps = ESteps.DownloadBundle;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.DownloadBundle)
{
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.CheckResult;
}
if (_steps == ESteps.CheckResult)
{
Progress = _downloadAssetBundleRequest.DownloadProgress;
if (_downloadAssetBundleRequest.IsDone == false)
return;
if (_downloadAssetBundleRequest.Status == EDownloadRequestStatus.Succeeded)
{
var assetBundle = _downloadAssetBundleRequest.Result;
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Fatal error: dwonload asset bundle is null.";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = new AssetBundleResult(_downloadAssetBundleRequest.Url, _options.Bundle, assetBundle, null);
}
}
else
{
if (_failedTryAgain > 0)
{
_steps = ESteps.TryAgain;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloadAssetBundleRequest.Error;
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
_downloadAssetBundleRequest.Dispose();
}
if (_steps == ESteps.TryAgain)
{
_tryAgainTimer += UnityEngine.Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
_tryAgainTimer = 0f;
_failedTryAgain--;
Progress = 0f;
_steps = ESteps.DownloadBundle;
}
}
}
private string GetRequestURL()
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
_requestCount++;
if (_requestCount % 2 == 0)
return _options.FallbackURL;
else
return _options.MainURL;
}
}
internal class LoadWebEncryptedAssetBundleOperation : LoadWebAssetBundleOperation
{
private enum ESteps
{
None,
DownloadData,
CheckResult,
TryAgain,
Done,
}
protected readonly LoadWebAssetBundleOptions _options;
private IDownloadBytesRequest _downloadBytesRequest;
private IBundleMemoryDecryptor _decryptor;
private ESteps _steps = ESteps.None;
// ʧ<><CAA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
private int _requestCount = 0;
private float _tryAgainTimer = 0;
private int _failedTryAgain;
public LoadWebEncryptedAssetBundleOperation(LoadWebAssetBundleOptions options)
{
_options = options;
_failedTryAgain = int.MaxValue; //ע<><EFBFBD><E2A3BA><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD>ʧ<EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>³<EFBFBD><C2B3><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD>ɹ<EFBFBD>
}
internal override void InternalStart()
{
_steps = ESteps.DownloadData;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.DownloadData)
{
var decryptor = _options.Decryptor;
if (decryptor == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{_options.CacheName} decryptor is null.";
return;
}
if (decryptor is IBundleMemoryDecryptor)
{
string url = GetRequestURL();
_decryptor = decryptor as IBundleMemoryDecryptor;
var args = new DownloadDataRequestArgs(url, 0, _options.WatchdogTimeout);
_downloadBytesRequest = _options.DownloadBackend.CreateBytesRequest(args);
_downloadBytesRequest.SendRequest();
_steps = ESteps.CheckResult;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{_options.CacheName} not support {decryptor.GetType().Name}";
return;
}
}
if (_steps == ESteps.CheckResult)
{
Progress = _downloadBytesRequest.DownloadProgress;
if (_downloadBytesRequest.IsDone == false)
return;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (_downloadBytesRequest.Status == EDownloadRequestStatus.Succeeded)
{
var assetBundle = LoadFromMemory(_decryptor, _downloadBytesRequest.Result);
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Unity engine load failed.";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = new AssetBundleResult(_downloadBytesRequest.Url, _options.Bundle, assetBundle, null);
}
}
else
{
if (_failedTryAgain > 0)
{
_steps = ESteps.TryAgain;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloadBytesRequest.Error;
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
_downloadBytesRequest.Dispose();
}
if (_steps == ESteps.TryAgain)
{
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
_tryAgainTimer = 0f;
_failedTryAgain--;
Progress = 0f;
_steps = ESteps.DownloadData;
}
}
}
private AssetBundle LoadFromMemory(IBundleMemoryDecryptor decryptor, byte[] fileData)
{
var args = new BundleDecryptArgs();
args.Bundle = _options.Bundle;
args.FileData = fileData;
var binaryData = decryptor.GetDecryptData(args);
return AssetBundle.LoadFromMemory(binaryData);
}
private string GetRequestURL()
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
_requestCount++;
if (_requestCount % 2 == 0)
return _options.FallbackURL;
else
return _options.MainURL;
}
}
}

View File

@@ -0,0 +1,49 @@
namespace YooAsset
{
/// <summary>
/// 加载 AssetBundle 的上下文信息
/// </summary>
internal struct LoadWebAssetBundleOptions
{
/// <summary>
/// 文件缓存名称
/// </summary>
public string CacheName { get; set; }
/// <summary>
/// 资源包信息
/// </summary>
public PackageBundle Bundle { get; set; }
/// <summary>
/// 请求地址
/// </summary>
public string MainURL { get; set; }
/// <summary>
/// 请求地址
/// </summary>
public string FallbackURL { get; set; }
/// <summary>
/// 解密接口
/// </summary>
public IBundleDecryptor Decryptor { get; set; }
/// <summary>
/// 下载后台接口
/// </summary>
public IDownloadBackend DownloadBackend { get; set; }
/// <summary>
/// 看门狗超时时间
/// </summary>
public int WatchdogTimeout { get; set; }
/// <summary>
/// 禁用Unity的网络缓存
/// </summary>
public bool DisableUnityWebCache { get; set; }
}
}

View File

@@ -7,6 +7,19 @@ namespace YooAsset
{
internal struct CacheConfig
{
/// <summary>
/// AssetBundle 解密器
/// </summary>
public IBundleDecryptor AssetBundleDecryptor { get; set; }
/// <summary>
/// RawBundle 解密器
/// </summary>
public IBundleDecryptor RawBundleDecryptor { get; set; }
/// <summary>
/// 下载后台接口
/// </summary>
public IDownloadBackend DownloadBackend { get; set; }
}

View File

@@ -12,7 +12,7 @@ namespace YooAsset
/// 生成包裹的内置资源目录文件
/// 说明:根据指定目录下的文件生成清单文件。
/// </summary>
public static bool CreateFile(IManifestRestoreServices services, string packageName, string packageDirectory)
public static bool CreateFile(IManifestDecryptor decryptor, string packageName, string packageDirectory)
{
// 获取资源清单版本
string packageVersion;
@@ -40,7 +40,7 @@ namespace YooAsset
}
var binaryData = FileUtility.ReadAllBytes(manifestFilePath);
packageManifest = PackageManifestTools.DeserializeManifestFromBinary(binaryData, services);
packageManifest = PackageManifestTools.DeserializeManifestFromBinary(binaryData, decryptor);
}
// 获取文件名映射关系

View File

@@ -1,7 +1,4 @@
using System;
using System.IO;
using UnityEngine;

namespace YooAsset
{
internal class BFCLoadAssetBundleOperation : FCLoadBundleOperation
@@ -9,16 +6,15 @@ namespace YooAsset
private enum ESteps
{
None,
LoadAssetBundle,
CheckResult,
GetEntry,
LoadBundle,
Done,
}
private readonly BuiltinFileCache _fileCache;
private readonly PackageBundle _bundle;
private AssetBundleCreateRequest _createRequest;
private AssetBundle _assetBundle;
private string _filePath;
private LoadLocalAssetBundleOperation _loadLocalAssetBundleOp;
private BuiltinFileCacheEntry _cacheEntry;
private ESteps _steps = ESteps.None;
public BFCLoadAssetBundleOperation(BuiltinFileCache fileCache, PackageBundle bundle)
@@ -28,62 +24,63 @@ namespace YooAsset
}
internal override void InternalStart()
{
_steps = ESteps.LoadAssetBundle;
_steps = ESteps.GetEntry;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadAssetBundle)
if (_steps == ESteps.GetEntry)
{
var entry = _fileCache.GetEntry(_bundle.BundleGUID);
if (entry == null)
_cacheEntry = _fileCache.GetEntry(_bundle.BundleGUID);
if (_cacheEntry == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Not found file cache entry: {_bundle.BundleGUID}";
return;
}
_filePath = entry.FilePath;
if (IsWaitForCompletion)
_assetBundle = AssetBundle.LoadFromFile(_filePath);
else
_createRequest = AssetBundle.LoadFromFileAsync(_filePath);
_steps = ESteps.CheckResult;
{
_steps = ESteps.LoadBundle;
}
}
if (_steps == ESteps.CheckResult)
if (_steps == ESteps.LoadBundle)
{
if (_createRequest != null)
if (_loadLocalAssetBundleOp == null)
{
if (IsWaitForCompletion)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity bundle.");
_assetBundle = _createRequest.assetBundle;
}
else
{
if (_createRequest.isDone == false)
return;
_assetBundle = _createRequest.assetBundle;
}
var options = new LoadLocalAssetBundleOptions();
options.CacheName = _fileCache.GetType().Name;
options.Bundle = _bundle;
options.FilePath = _cacheEntry.FilePath;
options.Decryptor = _fileCache.Config.AssetBundleDecryptor;
_loadLocalAssetBundleOp = new LoadLocalAssetBundleOperation(options);
_loadLocalAssetBundleOp.StartOperation();
AddChildOperation(_loadLocalAssetBundleOp);
}
if (_assetBundle == null)
if (IsWaitForCompletion)
_loadLocalAssetBundleOp.WaitForCompletion();
_loadLocalAssetBundleOp.UpdateOperation();
if (_loadLocalAssetBundleOp.IsDone == false)
return;
if (_loadLocalAssetBundleOp.Status == EOperationStatus.Succeeded)
{
if (_loadLocalAssetBundleOp.BundleResult == null)
throw new YooInternalException("Loaded asset bundle result is null.");
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = _loadLocalAssetBundleOp.BundleResult;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed to load asset bundle : {_bundle.BundleName}";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = new AssetBundleResult(_filePath, _bundle, _assetBundle, null);
Error = _loadLocalAssetBundleOp.Error;
}
}
}
@@ -98,12 +95,15 @@ namespace YooAsset
private enum ESteps
{
None,
LoadRawBundle,
GetEntry,
LoadBundle,
Done,
}
private readonly BuiltinFileCache _fileCache;
private readonly PackageBundle _bundle;
private LoadLocalRawBundleOperation _loadLocalRawBundleOp;
private BuiltinFileCacheEntry _cacheEntry;
private ESteps _steps = ESteps.None;
public BFCLoadRawBundleOperation(BuiltinFileCache fileCache, PackageBundle bundle)
@@ -113,48 +113,61 @@ namespace YooAsset
}
internal override void InternalStart()
{
_steps = ESteps.LoadRawBundle;
_steps = ESteps.GetEntry;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadRawBundle)
if (_steps == ESteps.GetEntry)
{
var entry = _fileCache.GetEntry(_bundle.BundleGUID);
if (entry == null)
_cacheEntry = _fileCache.GetEntry(_bundle.BundleGUID);
if (_cacheEntry == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Not found file cache entry: {_bundle.BundleGUID}";
return;
}
string filePath = entry.FilePath;
if (IsSupportFileIO(filePath) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"FileIO not supported for builtin path : {filePath}";
}
else
{
if (File.Exists(filePath))
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
_steps = ESteps.LoadBundle;
}
}
byte[] data = File.ReadAllBytes(filePath);
var rawBundle = new RawBundle(data);
BundleResult = new RawBundleResult(filePath, _bundle, rawBundle);
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Can not found raw bundle file : {filePath}";
}
if (_steps == ESteps.LoadBundle)
{
if(_loadLocalRawBundleOp == null)
{
var options = new LoadLocalRawBundleOptions();
options.CacheName = _fileCache.GetType().Name;
options.Bundle = _bundle;
options.FilePath = _cacheEntry.FilePath;
options.Decryptor = _fileCache.Config.AssetBundleDecryptor;
_loadLocalRawBundleOp = new LoadLocalRawBundleOperation(options);
_loadLocalRawBundleOp.StartOperation();
AddChildOperation(_loadLocalRawBundleOp);
}
if (IsWaitForCompletion)
_loadLocalRawBundleOp.WaitForCompletion();
_loadLocalRawBundleOp.UpdateOperation();
if (_loadLocalRawBundleOp.IsDone == false)
return;
if(_loadLocalRawBundleOp.Status == EOperationStatus.Succeeded)
{
if (_loadLocalRawBundleOp.BundleResult == null)
throw new YooInternalException("Loaded raw bundle result is null.");
BundleResult = _loadLocalRawBundleOp.BundleResult;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadLocalRawBundleOp.Error;
}
}
}
@@ -163,16 +176,4 @@ namespace YooAsset
ExecuteBatch();
}
}
internal abstract class BFCLoadAssetBundleFromOperation : FCLoadBundleOperation
{
internal abstract AssetBundle LoadFromOffset();
internal abstract AssetBundleCreateRequest LoadFromOffsetAsync();
internal abstract AssetBundle LoadFromMemory();
internal abstract AssetBundleCreateRequest LoadFromMemoryAsync();
internal abstract AssetBundle LoadFromStream();
internal abstract AssetBundleCreateRequest LoadFromStreamAsync();
}
}

View File

@@ -84,8 +84,17 @@ namespace YooAsset
}
public virtual FCLoadBundleOperation LoadBundleAsync(LoadBundleOptions options)
{
var operation = new EFCLoadVirtualBundleOperation(this, options.Bundle);
return operation;
if (options.Bundle.BundleType == (int)EBundleType.VirtualBundle)
{
var operation = new EFCLoadVirtualBundleOperation(this, options.Bundle);
return operation;
}
else
{
string error = $"{nameof(EditorFileCache)} not support load bundle type : {options.Bundle.BundleType}";
var operation = new FCLoadBundleErrorOperation(error);
return operation;
}
}
public virtual bool IsCached(string bundleGUID)
{

View File

@@ -1,75 +0,0 @@
using System.IO;
using UnityEngine;
namespace YooAsset
{
/// <summary>
/// 加载 AssetBundle 的抽象基类
/// 用户可继承此类实现自定义加载逻辑(如加密解密)
/// </summary>
public abstract class LoadAssetBundleOperation : AsyncOperationBase
{
protected readonly LoadAssetBundleOptions _options;
/// <summary>
/// 加载结果AssetBundle 对象
/// </summary>
public AssetBundle Result { get; protected set; }
/// <summary>
/// 托管流对象(如果使用流加载)
/// 注意:流对象在资源包对象释放的时候会自动释放
/// </summary>
public Stream ManagedStream { get; protected set; }
public LoadAssetBundleOperation(LoadAssetBundleOptions options)
{
_options = options;
}
/// <summary>
/// 后备加载方法:从内存加载 AssetBundle
/// 当主加载方式失败时FileSystem 会调用此方法作为后备机制
/// </summary>
/// <returns>加载成功返回 AssetBundle 对象,失败返回 null</returns>
public abstract AssetBundle LoadFromMemory();
/// <summary>
/// 检查文件路径是否支持 FileIO 读取
/// </summary>
protected static bool IsSupportFileIO(string filePath)
{
if (string.IsNullOrEmpty(filePath))
return true;
if (filePath.StartsWith("jar:") || filePath.StartsWith("content:"))
return false;
return true;
}
}
/// <summary>
/// 立即完成(失败)的 AssetBundle 加载操作
/// 用途:当 Factory 判定某种场景不支持(例如默认实现不支持加密包)时,返回该 Operation
/// </summary>
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;
}
}
}

View File

@@ -1,19 +0,0 @@
namespace YooAsset
{
/// <summary>
/// 加载 AssetBundle 的上下文信息
/// </summary>
public struct LoadAssetBundleOptions
{
/// <summary>
/// 文件加载路径
/// </summary>
internal string FileLoadPath { get; set; }
/// <summary>
/// 资源包信息
/// </summary>
internal PackageBundle Bundle { get; set; }
}
}

View File

@@ -1,57 +0,0 @@
using System.Text;
namespace YooAsset
{
/// <summary>
/// 加载 RawBundle 的抽象基类
/// 用户可继承此类实现自定义加载逻辑(如加密解密)
/// </summary>
public abstract class LoadRawBundleOperation : AsyncOperationBase
{
protected readonly LoadRawBundleOptions _options;
/// <summary>
/// 加载结果RawBundle 对象
/// </summary>
public RawBundle Result { get; protected set; }
public LoadRawBundleOperation(LoadRawBundleOptions options)
{
_options = options;
}
/// <summary>
/// 检查文件路径是否支持 FileIO 读取
/// </summary>
protected static bool IsSupportFileIO(string filePath)
{
if (string.IsNullOrEmpty(filePath))
return true;
if (filePath.StartsWith("jar:") || filePath.StartsWith("content:"))
return false;
return true;
}
}
/// <summary>
/// 立即完成(失败)的 RawBundle 加载操作
/// 用途:当 Factory 判定某种场景不支持(例如默认实现不支持加密包)时,返回该 Operation
/// </summary>
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()
{
}
}
}

View File

@@ -1,19 +0,0 @@
namespace YooAsset
{
/// <summary>
/// 加载 RawBundle 的上下文信息
/// </summary>
public struct LoadRawBundleOptions
{
/// <summary>
/// 文件加载路径
/// </summary>
internal string FileLoadPath { get; set; }
/// <summary>
/// 资源包信息
/// </summary>
internal PackageBundle Bundle { get; set; }
}
}

View File

@@ -9,18 +9,18 @@ namespace YooAsset
private enum ESteps
{
None,
LoadAssetBundle,
CheckResult,
GetEntry,
LoadBundle,
VerifyFile,
TryFallback,
Done,
}
private readonly SandboxFileCache _fileCache;
private readonly PackageBundle _bundle;
private LoadLocalAssetBundleOperation _loadLocalAssetBundleOp;
private FCVerifyCacheOperation _verifyCacheOp;
private AssetBundleCreateRequest _createRequest;
private AssetBundle _assetBundle;
private string _filePath;
private SandboxFileCacheEntry _cacheEntry;
private ESteps _steps = ESteps.None;
public SFCLoadAssetBundleOperation(SandboxFileCache fileCache, PackageBundle bundle)
@@ -30,64 +30,75 @@ namespace YooAsset
}
internal override void InternalStart()
{
_steps = ESteps.LoadAssetBundle;
_steps = ESteps.GetEntry;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadAssetBundle)
if (_steps == ESteps.GetEntry)
{
var entry = _fileCache.GetEntry(_bundle.BundleGUID);
if (entry == null)
_cacheEntry = _fileCache.GetEntry(_bundle.BundleGUID);
if (_cacheEntry == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Not found file cache entry: {_bundle.BundleGUID}";
return;
}
_filePath = entry.DataFilePath;
if (IsWaitForCompletion)
_assetBundle = AssetBundle.LoadFromFile(_filePath);
else
_createRequest = AssetBundle.LoadFromFileAsync(_filePath);
_steps = ESteps.CheckResult;
{
_steps = ESteps.LoadBundle;
}
}
if (_steps == ESteps.CheckResult)
if (_steps == ESteps.LoadBundle)
{
if (_createRequest != null)
if (_loadLocalAssetBundleOp == null)
{
if (IsWaitForCompletion)
var options = new LoadLocalAssetBundleOptions();
options.CacheName = _fileCache.GetType().Name;
options.Bundle = _bundle;
options.FilePath = _cacheEntry.DataFilePath;
options.Decryptor = _fileCache.Config.AssetBundleDecryptor;
_loadLocalAssetBundleOp = new LoadLocalAssetBundleOperation(options);
_loadLocalAssetBundleOp.StartOperation();
AddChildOperation(_loadLocalAssetBundleOp);
}
if (IsWaitForCompletion)
_loadLocalAssetBundleOp.WaitForCompletion();
_loadLocalAssetBundleOp.UpdateOperation();
if (_loadLocalAssetBundleOp.IsDone == false)
return;
if (_loadLocalAssetBundleOp.Status == EOperationStatus.Succeeded)
{
if (_loadLocalAssetBundleOp.BundleResult == null)
throw new YooInternalException("Loaded asset bundle result is null.");
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = _loadLocalAssetBundleOp.BundleResult;
}
else
{
// 注意:如果引擎加载失败,需要重新验证文件
if (_loadLocalAssetBundleOp.UnityEngineLoadFailed)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity bundle.");
_assetBundle = _createRequest.assetBundle;
_steps = ESteps.VerifyFile;
}
else
{
if (_createRequest.isDone == false)
return;
_assetBundle = _createRequest.assetBundle;
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadLocalAssetBundleOp.Error;
}
}
if (_assetBundle == null)
{
_steps = ESteps.TryFallback;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = new AssetBundleResult(_filePath, _bundle, _assetBundle, null);
}
}
if (_steps == ESteps.TryFallback)
if (_steps == ESteps.VerifyFile)
{
// 注意当缓存文件的校验等级为Low的时候并不能保证缓存文件的完整性。
// 说明在AssetBundle文件加载失败的情况下我们需要重新验证文件的完整性
@@ -110,22 +121,7 @@ namespace YooAsset
if (_verifyCacheOp.Status == EOperationStatus.Succeeded)
{
// 调用后备加载方法
// 注意:在安卓移动平台,华为和三星真机上有极小概率加载资源包失败。
// 说明:大多数情况在首次安装下载资源到沙盒内,游戏过程中切换到后台再回到游戏内有很大概率触发!
AssetBundle assetBundle = LoadFromMemory();
if (assetBundle != null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = new AssetBundleResult(_filePath, _bundle, assetBundle, null);
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed to load asset bundle from memory : {_bundle.BundleName}";
}
_steps = ESteps.TryFallback;
}
else
{
@@ -134,19 +130,70 @@ namespace YooAsset
Error = _verifyCacheOp.Error;
}
}
if (_steps == ESteps.TryFallback)
{
// 调用后备加载方法
// 注意:在安卓移动平台,华为和三星真机上有极小概率加载资源包失败。
// 说明:大多数情况在首次安装下载资源到沙盒内,游戏过程中切换到后台再回到游戏内有很大概率触发!
AssetBundle assetBundle;
if (_bundle.IsEncrypted)
{
if (_fileCache.Config.AssetBundleFallbackDecryptor == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(SandboxFileCache)} fallback decryptor is null.";
return;
}
assetBundle = FallbackLoadDecryptAssetBundle(_fileCache.Config.AssetBundleFallbackDecryptor);
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed fallback load encrypted asset bundle: {_bundle.BundleName}";
}
}
else
{
assetBundle = FallbackLoadAssetBundle();
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed fallback load asset bundle: {_bundle.BundleName}";
}
}
if (assetBundle != null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = new AssetBundleResult(_cacheEntry.DataFilePath, _bundle, assetBundle, null);
}
}
}
internal override void InternalWaitForCompletion()
{
ExecuteBatch();
}
private AssetBundle LoadFromMemory()
private AssetBundle FallbackLoadAssetBundle()
{
byte[] fileData = FileUtility.ReadAllBytes(_filePath);
byte[] fileData = FileUtility.ReadAllBytes(_cacheEntry.DataFilePath);
if (fileData == null || fileData.Length == 0)
return null;
return AssetBundle.LoadFromMemory(fileData);
}
private AssetBundle FallbackLoadDecryptAssetBundle(IBundleMemoryDecryptor decryptor)
{
var args = new BundleDecryptArgs();
args.Bundle = _bundle;
args.FilePath = _cacheEntry.DataFilePath;
var binaryData = decryptor.GetDecryptData(args);
return AssetBundle.LoadFromMemory(binaryData);
}
}
internal class SFCLoadRawBundleOperation : FCLoadBundleOperation
@@ -154,12 +201,16 @@ namespace YooAsset
private enum ESteps
{
None,
LoadRawBundle,
GetEntry,
LoadBundle,
Done,
}
private readonly SandboxFileCache _fileCache;
private readonly PackageBundle _bundle;
private LoadLocalRawBundleOperation _loadLocalRawBundleOp;
private SandboxFileCacheEntry _cacheEntry;
private ESteps _steps = ESteps.None;
public SFCLoadRawBundleOperation(SandboxFileCache fileCache, PackageBundle bundle)
@@ -169,39 +220,61 @@ namespace YooAsset
}
internal override void InternalStart()
{
_steps = ESteps.LoadRawBundle;
_steps = ESteps.GetEntry;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadRawBundle)
if (_steps == ESteps.GetEntry)
{
var entry = _fileCache.GetEntry(_bundle.BundleGUID);
if (entry == null)
_cacheEntry = _fileCache.GetEntry(_bundle.BundleGUID);
if (_cacheEntry == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Not found file cache entry: {_bundle.BundleGUID}";
return;
}
else
{
_steps = ESteps.LoadBundle;
}
}
if (_steps == ESteps.LoadBundle)
{
if (_loadLocalRawBundleOp == null)
{
var options = new LoadLocalRawBundleOptions();
options.CacheName = _fileCache.GetType().Name;
options.Bundle = _bundle;
options.FilePath = _cacheEntry.DataFilePath;
options.Decryptor = _fileCache.Config.AssetBundleDecryptor;
_loadLocalRawBundleOp = new LoadLocalRawBundleOperation(options);
_loadLocalRawBundleOp.StartOperation();
AddChildOperation(_loadLocalRawBundleOp);
}
string filePath = entry.DataFilePath;
if (File.Exists(filePath))
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
if (IsWaitForCompletion)
_loadLocalRawBundleOp.WaitForCompletion();
byte[] data = File.ReadAllBytes(filePath);
var rawBundle = new RawBundle(data);
BundleResult = new RawBundleResult(filePath, _bundle, rawBundle);
_loadLocalRawBundleOp.UpdateOperation();
if (_loadLocalRawBundleOp.IsDone == false)
return;
if (_loadLocalRawBundleOp.Status == EOperationStatus.Succeeded)
{
if (_loadLocalRawBundleOp.BundleResult == null)
throw new YooInternalException("Loaded raw bundle result is null.");
BundleResult = _loadLocalRawBundleOp.BundleResult;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Can not found raw bundle file : {filePath}";
Error = _loadLocalRawBundleOp.Error;
}
}
}
@@ -210,16 +283,4 @@ namespace YooAsset
ExecuteBatch();
}
}
internal abstract class SFCLoadAssetBundleFromOperation : FCLoadBundleOperation
{
internal abstract AssetBundle LoadFromOffset();
internal abstract AssetBundleCreateRequest LoadFromOffsetAsync();
internal abstract AssetBundle LoadFromMemory();
internal abstract AssetBundleCreateRequest LoadFromMemoryAsync();
internal abstract AssetBundle LoadFromStream();
internal abstract AssetBundleCreateRequest LoadFromStreamAsync();
}
}

View File

@@ -16,6 +16,21 @@ namespace YooAsset
/// 文件校验级别
/// </summary>
public EFileVerifyLevel FileVerifyLevel { get; set; }
/// <summary>
/// AssetBundle 解密器
/// </summary>
public IBundleDecryptor AssetBundleDecryptor { get; set; }
/// <summary>
/// RawBundle 解密器
/// </summary>
public IBundleDecryptor RawBundleDecryptor { get; set; }
/// <summary>
/// AssetBundle 备用解密器
/// </summary>
public IBundleMemoryDecryptor AssetBundleFallbackDecryptor { get; set; }
}
private const int HashFolderLength = 2;

View File

@@ -6,121 +6,89 @@ namespace YooAsset
private enum ESteps
{
None,
CreateRequest,
CheckRequest,
TryAgain,
GetEntry,
LoadBundle,
Done,
}
private readonly WebRemoteFileCache _fileCache;
private readonly LoadBundleOptions _options;
private IDownloadAssetBundleRequest _downloadAssetBundleRequest;
private LoadWebAssetBundleOperation _loadWebAssetBundleOp;
private WebRemoteFileCacheEntry _cacheEntry;
private ESteps _steps = ESteps.None;
// 失败重试
private int _requestCount = 0;
private float _tryAgainTimer = 0;
private int _failedTryAgain;
public WRFCLoadAssetBundleOperation(WebRemoteFileCache fileCache, LoadBundleOptions options)
{
_fileCache = fileCache;
_options = options;
_failedTryAgain = fileCache.Config.RetryCount;
}
internal override void InternalStart()
{
_steps = ESteps.CreateRequest;
_steps = ESteps.GetEntry;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CreateRequest)
if (_steps == ESteps.GetEntry)
{
var entry = _fileCache.GetEntry(_options.Bundle);
if(entry == null)
_cacheEntry = _fileCache.GetEntry(_options.Bundle);
if (_cacheEntry == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Not found file cache entry: {_options.Bundle.BundleGUID}";
return;
}
string url = GetRequestURL(entry);
var args = new DownloadAssetBundleRequestArgs(url, 0, _fileCache.Config.WatchdogTimeout, _fileCache.Config.DisableUnityWebCache, _options.Bundle.FileHash, _options.Bundle.UnityCRC);
_downloadAssetBundleRequest = _fileCache.Config.DownloadBackend.CreateAssetBundleRequest(args);
_downloadAssetBundleRequest.SendRequest();
_steps = ESteps.CheckRequest;
}
if (_steps == ESteps.CheckRequest)
{
Progress = _downloadAssetBundleRequest.DownloadProgress;
if (_downloadAssetBundleRequest.IsDone == false)
return;
if (_downloadAssetBundleRequest.Status == EDownloadRequestStatus.Succeeded)
{
var assetBundle = _downloadAssetBundleRequest.Result;
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed to load asset bundle : {_options.Bundle.BundleName}";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = new AssetBundleResult(null, _options.Bundle, assetBundle, null);
}
}
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);
}
_steps = ESteps.LoadBundle;
}
// 最终释放请求器
_downloadAssetBundleRequest.Dispose();
}
if (_steps == ESteps.TryAgain)
if (_steps == ESteps.LoadBundle)
{
_tryAgainTimer += UnityEngine.Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
if (_loadWebAssetBundleOp == null)
{
_tryAgainTimer = 0f;
_failedTryAgain--;
Progress = 0f;
_steps = ESteps.CreateRequest;
var options = new LoadWebAssetBundleOptions();
options.CacheName = _fileCache.GetType().Name;
options.Bundle = _options.Bundle;
options.MainURL = _cacheEntry.MainURL;
options.FallbackURL = _cacheEntry.FallbackURL;
options.Decryptor = _fileCache.Config.AssetBundleDecryptor;
options.DownloadBackend = _fileCache.Config.DownloadBackend;
options.WatchdogTimeout = _fileCache.Config.WatchdogTimeout;
options.DisableUnityWebCache = _fileCache.Config.DisableUnityWebCache;
if (_options.Bundle.IsEncrypted)
_loadWebAssetBundleOp = new LoadWebEncryptedAssetBundleOperation(options);
else
_loadWebAssetBundleOp = new LoadWebNormalAssetBundleOperation(options);
_loadWebAssetBundleOp.StartOperation();
AddChildOperation(_loadWebAssetBundleOp);
}
_loadWebAssetBundleOp.UpdateOperation();
if (_loadWebAssetBundleOp.IsDone == false)
return;
if (_loadWebAssetBundleOp.Status == EOperationStatus.Succeeded)
{
if (_loadWebAssetBundleOp.BundleResult == null)
throw new YooInternalException("Loaded asset bundle result is null.");
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = _loadWebAssetBundleOp.BundleResult;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadWebAssetBundleOp.Error;
}
}
}
/// <summary>
/// 获取网络请求地址
/// </summary>
protected string GetRequestURL(WebRemoteFileCacheEntry entry)
{
// 轮流返回请求地址
_requestCount++;
if (_requestCount % 2 == 0)
return entry.FallbackURL;
else
return entry.MainURL;
}
}
}

View File

@@ -7,27 +7,30 @@ namespace YooAsset
{
internal struct CacheConfig
{
/// <summary>
/// 看门狗超时时间
/// </summary>
public int WatchdogTimeout { get; set; }
/// <summary>
/// 禁用Unity的网络缓存
/// </summary>
public bool DisableUnityWebCache { get; set; }
/// <summary>
/// AssetBundle 解密器
/// </summary>
public IBundleDecryptor AssetBundleDecryptor { get; set; }
/// <summary>
/// 远程服务接口
/// </summary>
public IRemoteServices RemoteServices { get; set; }
/// <summary>
/// 下载后台接口
/// </summary>
public IDownloadBackend DownloadBackend { get; set; }
/// <summary>
/// 看门狗超时时间
/// </summary>
public int WatchdogTimeout { get; set; }
/// <summary>
/// 失败后重试次数
/// </summary>
public int RetryCount { get; set; }
}
private readonly Dictionary<string, WebRemoteFileCacheEntry> _caches = new Dictionary<string, WebRemoteFileCacheEntry>(10000);
@@ -101,8 +104,17 @@ namespace YooAsset
}
public virtual FCLoadBundleOperation LoadBundleAsync(LoadBundleOptions options)
{
var operation = new WRFCLoadAssetBundleOperation(this, options);
return operation;
if (options.Bundle.BundleType == (int)EBundleType.AssetBundle)
{
var operation = new WRFCLoadAssetBundleOperation(this, options);
return operation;
}
else
{
string error = $"{nameof(WebServerFileCache)} not support load bundle type : {options.Bundle.BundleType}";
var operation = new FCLoadBundleErrorOperation(error);
return operation;
}
}
public virtual bool IsCached(string bundleGUID)
{

View File

@@ -1,110 +1,93 @@

namespace YooAsset
{
internal class WFCLoadAssetBundleOperation : FCLoadBundleOperation
internal class WSFCLoadAssetBundleOperation : FCLoadBundleOperation
{
private enum ESteps
{
None,
CreateRequest,
CheckRequest,
TryAgain,
GetEntry,
LoadBundle,
Done,
}
private readonly WebServerFileCache _fileCache;
private readonly LoadBundleOptions _options;
private IDownloadAssetBundleRequest _downloadAssetBundleRequest;
private LoadWebAssetBundleOperation _loadWebAssetBundleOp;
private WebServerFileCacheEntry _cacheEntry;
private ESteps _steps = ESteps.None;
// 失败重试
private float _tryAgainTimer = 0;
private int _failedTryAgain;
public WFCLoadAssetBundleOperation(WebServerFileCache fileCache, LoadBundleOptions options)
public WSFCLoadAssetBundleOperation(WebServerFileCache fileCache, LoadBundleOptions options)
{
_fileCache = fileCache;
_options = options;
_failedTryAgain = fileCache.Config.RetryCount;
}
internal override void InternalStart()
{
_steps = ESteps.CreateRequest;
_steps = ESteps.GetEntry;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CreateRequest)
if (_steps == ESteps.GetEntry)
{
var entry = _fileCache.GetEntry(_options.Bundle.BundleGUID);
if (entry == null)
_cacheEntry = _fileCache.GetEntry(_options.Bundle.BundleGUID);
if (_cacheEntry == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Not found file cache entry: {_options.Bundle.BundleGUID}";
return;
}
string url = DownloadSystemTools.ToLocalUrl(entry.FilePath);
var args = new DownloadAssetBundleRequestArgs(url, 0, _fileCache.Config.WatchdogTimeout, _fileCache.Config.DisableUnityWebCache, _options.Bundle.FileHash, _options.Bundle.UnityCRC);
_downloadAssetBundleRequest = _fileCache.Config.DownloadBackend.CreateAssetBundleRequest(args);
_downloadAssetBundleRequest.SendRequest();
_steps = ESteps.CheckRequest;
}
if (_steps == ESteps.CheckRequest)
{
Progress = _downloadAssetBundleRequest.DownloadProgress;
if (_downloadAssetBundleRequest.IsDone == false)
return;
if (_downloadAssetBundleRequest.Status == EDownloadRequestStatus.Succeeded)
{
var assetBundle = _downloadAssetBundleRequest.Result;
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed to load asset bundle : {_options.Bundle.BundleName}";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = new AssetBundleResult(null, _options.Bundle, assetBundle, null);
}
}
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);
}
_steps = ESteps.LoadBundle;
}
// 最终释放请求器
_downloadAssetBundleRequest.Dispose();
}
if (_steps == ESteps.TryAgain)
if (_steps == ESteps.LoadBundle)
{
_tryAgainTimer += UnityEngine.Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
if (_loadWebAssetBundleOp == null)
{
_tryAgainTimer = 0f;
_failedTryAgain--;
Progress = 0f;
_steps = ESteps.CreateRequest;
string url = DownloadSystemTools.ToLocalUrl(_cacheEntry.FilePath);
var options = new LoadWebAssetBundleOptions();
options.CacheName = _fileCache.GetType().Name;
options.Bundle = _options.Bundle;
options.MainURL = url;
options.FallbackURL = url;
options.Decryptor = _fileCache.Config.AssetBundleDecryptor;
options.DownloadBackend = _fileCache.Config.DownloadBackend;
options.WatchdogTimeout = _fileCache.Config.WatchdogTimeout;
options.DisableUnityWebCache = _fileCache.Config.DisableUnityWebCache;
if (_options.Bundle.IsEncrypted)
_loadWebAssetBundleOp = new LoadWebEncryptedAssetBundleOperation(options);
else
_loadWebAssetBundleOp = new LoadWebNormalAssetBundleOperation(options);
_loadWebAssetBundleOp.StartOperation();
AddChildOperation(_loadWebAssetBundleOp);
}
_loadWebAssetBundleOp.UpdateOperation();
if (_loadWebAssetBundleOp.IsDone == false)
return;
if (_loadWebAssetBundleOp.Status == EOperationStatus.Succeeded)
{
if (_loadWebAssetBundleOp.BundleResult == null)
throw new YooInternalException("Loaded asset bundle result is null.");
_steps = ESteps.Done;
Status = EOperationStatus.Succeeded;
BundleResult = _loadWebAssetBundleOp.BundleResult;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadWebAssetBundleOp.Error;
}
}
}

View File

@@ -7,25 +7,25 @@ namespace YooAsset
{
internal struct CacheConfig
{
/// <summary>
/// 禁用Unity的网络缓存
/// </summary>
public bool DisableUnityWebCache { get; set; }
/// <summary>
/// 下载后台接口
/// </summary>
public IDownloadBackend DownloadBackend { get; set; }
/// <summary>
/// 看门狗超时时间
/// </summary>
public int WatchdogTimeout { get; set; }
/// <summary>
/// 失败后重试次数
/// 禁用Unity的网络缓存
/// </summary>
public int RetryCount { get; set; }
public bool DisableUnityWebCache { get; set; }
/// <summary>
/// AssetBundle 解密器
/// </summary>
public IBundleDecryptor AssetBundleDecryptor { get; set; }
/// <summary>
/// 下载后台接口
/// </summary>
public IDownloadBackend DownloadBackend { get; set; }
}
private readonly Dictionary<string, WebServerFileCacheEntry> _caches = new Dictionary<string, WebServerFileCacheEntry>(10000);
@@ -99,8 +99,17 @@ namespace YooAsset
}
public virtual FCLoadBundleOperation LoadBundleAsync(LoadBundleOptions options)
{
var operation = new WFCLoadAssetBundleOperation(this, options);
return operation;
if (options.Bundle.BundleType == (int)EBundleType.AssetBundle)
{
var operation = new WSFCLoadAssetBundleOperation(this, options);
return operation;
}
else
{
string error = $"{nameof(WebServerFileCache)} not support load bundle type : {options.Bundle.BundleType}";
var operation = new FCLoadBundleErrorOperation(error);
return operation;
}
}
public virtual bool IsCached(string bundleGUID)
{

View File

@@ -2,6 +2,7 @@ using System;
using System.IO;
using UnityEngine;
/*
namespace YooAsset
{
/// <summary>
@@ -96,72 +97,8 @@ namespace YooAsset
/// </summary>
public abstract class DefaultLoadAssetBundleFromOffsetOperation : LoadAssetBundleOperation
{
private enum ESteps
protected DefaultLoadAssetBundleFromOffsetOperation(LoadAssetBundleOptions options) : base(options)
{
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 (IsWaitForCompletion)
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 (IsWaitForCompletion)
{
// 强制挂起主线程(注意:该操作会很耗时)
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.Succeeded;
}
}
}
internal override void InternalWaitForCompletion()
{
ExecuteBatch();
}
/// <summary>
@@ -209,9 +146,6 @@ namespace YooAsset
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckFilePath)
{
string filePath = _options.FileLoadPath;
@@ -246,41 +180,6 @@ namespace YooAsset
_steps = ESteps.CheckResult;
}
if (_steps == ESteps.CheckResult)
{
if (_createRequest != null)
{
if (IsWaitForCompletion)
{
// 强制挂起主线程(注意:该操作会很耗时)
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.Succeeded;
}
}
}
internal override void InternalWaitForCompletion()
{
ExecuteBatch();
}
/// <summary>
@@ -313,20 +212,13 @@ namespace YooAsset
CheckResult,
Done,
}
private AssetBundleCreateRequest _createRequest;
private ESteps _steps = ESteps.None;
public DefaultLoadAssetBundleFromStreamOperation(LoadAssetBundleOptions options) : base(options) { }
internal override void InternalStart()
protected DefaultLoadAssetBundleFromStreamOperation(LoadAssetBundleOptions options) : base(options)
{
_steps = ESteps.CheckFilePath;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckFilePath)
{
string filePath = _options.FileLoadPath;
@@ -341,65 +233,7 @@ namespace YooAsset
_steps = ESteps.LoadAssetBundle;
}
}
if (_steps == ESteps.LoadAssetBundle)
{
ManagedStream = CreateManagedFileStream();
uint bufferSize = GetManagedReadBufferSize();
if (IsWaitForCompletion)
Result = AssetBundle.LoadFromStream(ManagedStream, 0, bufferSize);
else
_createRequest = AssetBundle.LoadFromStreamAsync(ManagedStream, 0, bufferSize);
_steps = ESteps.CheckResult;
}
if (_steps == ESteps.CheckResult)
{
if (_createRequest != null)
{
if (IsWaitForCompletion)
{
// 强制挂起主线程(注意:该操作会很耗时)
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.Succeeded;
}
}
}
internal override void InternalWaitForCompletion()
{
ExecuteBatch();
}
/// <summary>
/// 获取文件流
/// </summary>
protected abstract FileStream CreateManagedFileStream();
/// <summary>
/// 获取缓冲池大小
/// </summary>
protected abstract uint GetManagedReadBufferSize();
/// <summary>
/// 文件数据解密
@@ -416,4 +250,5 @@ namespace YooAsset
return AssetBundle.LoadFromMemory(rawData);
}
}
}
}
*/

View File

@@ -1,5 +1,6 @@
using System.IO;
/*
namespace YooAsset
{
/// <summary>
@@ -25,24 +26,6 @@ namespace YooAsset
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckFilePath)
{
string filePath = _options.FileLoadPath;
if (IsSupportFileIO(filePath) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"FileIO not supported for builtin path : {filePath}";
}
else
{
_steps = ESteps.LoadRawBundle;
}
}
if (_steps == ESteps.LoadRawBundle)
{
string filePath = _options.FileLoadPath;
@@ -61,10 +44,6 @@ namespace YooAsset
}
}
}
internal override void InternalWaitForCompletion()
{
ExecuteBatch();
}
}
/// <summary>
@@ -90,24 +69,6 @@ namespace YooAsset
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckFilePath)
{
string filePath = _options.FileLoadPath;
if (IsSupportFileIO(filePath) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"FileIO not supported for builtin path : {filePath}";
}
else
{
_steps = ESteps.LoadRawBundle;
}
}
if (_steps == ESteps.LoadRawBundle)
{
string filePath = _options.FileLoadPath;
@@ -136,10 +97,6 @@ namespace YooAsset
}
}
}
internal override void InternalWaitForCompletion()
{
ExecuteBatch();
}
/// <summary>
/// 文件数据解密
@@ -147,3 +104,4 @@ namespace YooAsset
protected abstract byte[] DecryptData(byte[] data);
}
}
*/

View File

@@ -1,5 +1,6 @@
using UnityEngine;
/*
namespace YooAsset
{
/// <summary>
@@ -247,3 +248,4 @@ namespace YooAsset
}
}
}
*/

View File

@@ -96,7 +96,7 @@ namespace YooAsset
/// <param name="packageRoot">文件系统的根目录</param>
public static FileSystemParameters CreateDefaultCacheFileSystemParameters(IRemoteServices remoteServices, string packageRoot = null)
{
string fileSystemClass = typeof(CacheFileSystem).FullName;
string fileSystemClass = typeof(SandboxFileSystem).FullName;
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
return fileSystemParams;

View File

@@ -24,25 +24,25 @@ namespace YooAsset
public const string REMOTE_SERVICES = "REMOTE_SERVICES";
/// <summary>
/// 资源清单服务类 <see cref=IManifestRestoreServices>
/// AssetBundle 解密器 <see cref=IBundleDecryptor>
/// </summary>
public const string MANIFEST_RESTORE_SERVICES = "MANIFEST_RESTORE_SERVICES";
public const string ASSETBUNDLE_DECRYPTOR = "ASSETBUNDLE_DECRYPTOR";
/// <summary>
/// 禁用Unity的网络缓存 <see cref=bool>
/// </summary>
public const string DISABLE_UNITY_WEB_CACHE = "DISABLE_UNITY_WEB_CACHE";
/// <summary>
/// 禁用边玩边下机制 <see cref=bool>
/// </summary>
public const string DISABLE_ONDEMAND_DOWNLOAD = "DISABLE_ONDEMAND_DOWNLOAD";
/// <summary>
/// UnityWebRequest 创建委托 <see cref=UnityWebRequestCreator>
/// </summary>
public const string UNITY_WEB_REQUEST_CREATOR = "UNITY_WEB_REQUEST_CREATOR";
/// <summary>
/// 禁用边玩边下机制 <see cref=bool>
/// </summary>
public const string DOWNLOAD_DISABLE_ONDEMAND = "DOWNLOAD_DISABLE_ONDEMAND";
/// <summary>
/// 下载后台接口 <see cref=IDownloadBackend>
/// </summary>
@@ -66,12 +66,12 @@ namespace YooAsset
/// <summary>
/// 启用断点续传的最小尺寸 <see cref=long>
/// </summary>
public const string RESUME_DOWNLOAD_MINMUM_SIZE = "RESUME_DOWNLOAD_MINMUM_SIZE";
public const string DOWNLOAD_RESUME_MINMUM_SIZE = "DOWNLOAD_RESUME_MINMUM_SIZE";
/// <summary>
/// 断点续传下载器关注的错误码 <see cref=List<long>>
/// </summary>
public const string RESUME_DOWNLOAD_RESPONSE_CODES = "RESUME_DOWNLOAD_RESPONSE_CODES";
public const string DOWNLOAD_RESUME_RESPONSE_CODES = "DOWNLOAD_RESUME_RESPONSE_CODES";
/// <summary>
/// 模拟WebGL平台模式 <see cref=bool>
@@ -112,5 +112,20 @@ namespace YooAsset
/// 解压文件系统的根目录 <see cref=string>
/// </summary>
public const string UNPACK_FILE_SYSTEM_ROOT = "UNPACK_FILE_SYSTEM_ROOT";
/// <summary>
/// RawBundle 解密器 <see cref=IBundleDecryptor>
/// </summary>
public const string RAWBUNDLE_DECRYPTOR = "RAWBUNDLE_DECRYPTOR";
/// <summary>
/// AssetBundle 备用解密器 <see cref=IBundleMemoryDecryptor>
/// </summary>
public const string ASSETBUNDLE_FALLBACK_DECRYPTOR = "ASSETBUNDLE_FALLBACK_DECRYPTOR";
/// <summary>
/// 资源清单解密器 <see cref=IManifestDecryptor>
/// </summary>
public const string MANIFEST_DECRYPTOR = "MANIFEST_DECRYPTOR";
}
}

View File

@@ -93,9 +93,24 @@ namespace YooAsset
public int UnpackMaxRequestPerFrame { private set; get; }
/// <summary>
/// 自定义参数:资源清单服务类
/// 自定义参数:AssetBundle 解密器
/// </summary>
public IManifestRestoreServices ManifestRestoreServices { private set; get; }
public IBundleDecryptor AssetBundleDecryptor { get; set; }
/// <summary>
/// 自定义参数RawBundle 解密器
/// </summary>
public IBundleDecryptor RawBundleDecryptor { get; set; }
/// <summary>
/// 自定义参数AssetBundle 备用解密器
/// </summary>
public IBundleMemoryDecryptor AssetBundleFallbackDecryptor { get; set; }
/// <summary>
/// 自定义参数:资源清单解密器
/// </summary>
public IManifestDecryptor ManifestDecryptor { private set; get; }
#endregion
@@ -190,9 +205,21 @@ namespace YooAsset
// 限制在合理范围内1-32
UnpackMaxRequestPerFrame = Mathf.Clamp(convertValue, 1, 32);
}
else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES)
else if (name == FileSystemParametersDefine.ASSETBUNDLE_DECRYPTOR)
{
ManifestRestoreServices = (IManifestRestoreServices)value;
AssetBundleDecryptor = (IBundleDecryptor)value;
}
else if (name == FileSystemParametersDefine.RAWBUNDLE_DECRYPTOR)
{
RawBundleDecryptor = (IBundleDecryptor)value;
}
else if (name == FileSystemParametersDefine.ASSETBUNDLE_FALLBACK_DECRYPTOR)
{
AssetBundleFallbackDecryptor = (IBundleMemoryDecryptor)value;
}
else if (name == FileSystemParametersDefine.MANIFEST_DECRYPTOR)
{
ManifestDecryptor = (IManifestDecryptor)value;
}
else
{
@@ -218,13 +245,15 @@ namespace YooAsset
unpackRoot = GetDefaultUnpackCacheRoot(packageName);
else
unpackRoot = UnpackFileSystemRoot;
_unpackManifestFilesRoot = PathUtility.Combine(unpackRoot, BuiltinFileSystemConstants.UnpackManifestFilesFolderName);
_unpackBundleFilesRoot = PathUtility.Combine(unpackRoot, BuiltinFileSystemConstants.UnpackBundleFilesFolderName);
_unpackTempFilesRoot = PathUtility.Combine(unpackRoot, BuiltinFileSystemConstants.UnpackTempFilesFolderName);
_unpackManifestFilesRoot = PathUtility.Combine(unpackRoot, BuiltinFileSystemDefine.UnpackManifestFilesFolderName);
_unpackBundleFilesRoot = PathUtility.Combine(unpackRoot, BuiltinFileSystemDefine.UnpackBundleFilesFolderName);
_unpackTempFilesRoot = PathUtility.Combine(unpackRoot, BuiltinFileSystemDefine.UnpackTempFilesFolderName);
// 创建内置缓存对象
{
var cacheConfig = new BuiltinFileCache.CacheConfig();
cacheConfig.AssetBundleDecryptor = AssetBundleDecryptor;
cacheConfig.RawBundleDecryptor = RawBundleDecryptor;
cacheConfig.DownloadBackend = DownloadBackend;
BuiltinFileCache = new BuiltinFileCache(packageName, _packageRoot, cacheConfig);
}
@@ -232,8 +261,11 @@ namespace YooAsset
// 创建沙盒缓存对象
{
var cacheConfig = new SandboxFileCache.CacheConfig();
cacheConfig.FileVerifyLevel = FileVerifyLevel;
cacheConfig.FileVerifyMaxConcurrency = FileVerifyMaxConcurrency;
cacheConfig.FileVerifyLevel = FileVerifyLevel;
cacheConfig.AssetBundleDecryptor = AssetBundleDecryptor;
cacheConfig.RawBundleDecryptor = RawBundleDecryptor;
cacheConfig.AssetBundleFallbackDecryptor = AssetBundleFallbackDecryptor;
UnpackFileCache = new SandboxFileCache(packageName, _unpackBundleFilesRoot, cacheConfig);
}
}
@@ -341,7 +373,7 @@ namespace YooAsset
}
public string GetSandboxAppFootPrintFilePath()
{
return PathUtility.Combine(_unpackManifestFilesRoot, DefaultCacheFileSystemDefine.AppFootPrintFileName);
return PathUtility.Combine(_unpackManifestFilesRoot, SandboxFileSystemDefine.AppFootPrintFileName);
}
/// <summary>

View File

@@ -1,7 +1,7 @@
namespace YooAsset
{
internal class BuiltinFileSystemConstants
internal class BuiltinFileSystemDefine
{
/// <summary>
/// 解压清单文件的文件夹名称

View File

@@ -1,4 +1,4 @@

namespace YooAsset
{
internal class BFSInitializeOperation : FSInitializeOperation
@@ -45,7 +45,7 @@ namespace YooAsset
var appFootprint = new ApplicationFootprint(footprintFilePath);
appFootprint.Load(_fileSystem.PackageName);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˮӡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>װ<EFBFBD><EFBFBD><EFBFBD>״δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ
// 如果水印发生变化,则说明覆盖安装后首次打开游戏
if (appFootprint.IsDirty())
{
if (_fileSystem.InstallClearMode == EInstallCleanupMode.None)
@@ -163,8 +163,8 @@ namespace YooAsset
if (_steps == ESteps.CreateScheduler)
{
// ע<EFBFBD><EFBFBD>: <20><><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹ<EFBFBD><D6B9>ʼ<EFBFBD><CABC>ʧ<EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// ע<EFBFBD><EFBFBD>: <20><><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>
// 注意: 下载调度中心在最后一步创建,防止初始化失败后残留任务。
// 注意: 下载调度中心作为独立任务运行!
if (_fileSystem.UnpackScheduler == null)
{
var schedulerConfig = new DownloadSchedulerOperation.SchedulerConfig();

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.IO;
namespace YooAsset
@@ -77,7 +77,7 @@ namespace YooAsset
{
if (_webFileRequestOp == null)
{
//TODO <EFBFBD>Ž<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ijЩ<EFBFBD><EFBFBD>׿<EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ף<EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>UnityWebRequest<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>
//TODO 团结引擎在某些安卓机型红米通过UnityWebRequest拷贝包内文件会小概率失败需要借助其它方式来拷贝包内文件。
string url = DownloadSystemTools.ToLocalUrl(_sourceFilePath);
var args = new DownloadFileRequestArgs(url, _destFilePath, 60, 0);
_webFileRequestOp = _fileSystem.DownloadBackend.CreateFileRequest(args);
@@ -102,7 +102,7 @@ namespace YooAsset
}
internal override void InternalWaitForCompletion()
{
//TODO <EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><EFBFBD>ò<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̣߳<EFBFBD>
//TODO 等待解压本地文件完毕,该操作会挂起主线程!
ExecuteUntilComplete();
}
}

View File

@@ -120,7 +120,7 @@ namespace YooAsset
if (string.IsNullOrEmpty(destRoot))
{
string defaultCacheRoot = YooAssetSettingsData.GetYooDefaultCacheRoot();
destRoot = PathUtility.Combine(defaultCacheRoot, _fileSystem.PackageName, DefaultCacheFileSystemDefine.ManifestFilesFolderName);
destRoot = PathUtility.Combine(defaultCacheRoot, _fileSystem.PackageName, SandboxFileSystemDefine.ManifestFilesFolderName);
}
return destRoot;
}

View File

@@ -102,7 +102,7 @@ namespace YooAsset
{
if (_deserializer == null)
{
_deserializer = new DeserializeManifestOperation(_fileSystem.ManifestRestoreServices, _fileData);
_deserializer = new DeserializeManifestOperation(_fileSystem.ManifestDecryptor, _fileData);
_deserializer.StartOperation();
AddChildOperation(_deserializer);
}

View File

@@ -13,7 +13,7 @@ namespace YooAsset
Done,
}
private readonly CacheFileSystem _fileSystem;
private readonly SandboxFileSystem _fileSystem;
private readonly string _tempFilePath;
private bool _enableResume = false;
private long _fileOriginLength = 0;
@@ -21,7 +21,7 @@ namespace YooAsset
private FCWriteCacheOperation _writeCacheOp;
private ESteps _steps = ESteps.None;
internal DownloadAndCacheFileOperation(CacheFileSystem fileSystem, PackageBundle bundle, string url) : base(bundle, url)
internal DownloadAndCacheFileOperation(SandboxFileSystem fileSystem, PackageBundle bundle, string url) : base(bundle, url)
{
_fileSystem = fileSystem;
_tempFilePath = _fileSystem.GetTempFilePath(bundle);

View File

@@ -12,7 +12,7 @@ namespace YooAsset
Done,
}
private readonly CacheFileSystem _fileSystem;
private readonly SandboxFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly int _timeout;
private IDownloadFileRequest _webFileRequestOp;
@@ -20,7 +20,7 @@ namespace YooAsset
private ESteps _steps = ESteps.None;
internal DownloadPackageHashOperation(CacheFileSystem fileSystem, string packageVersion, int timeout)
internal DownloadPackageHashOperation(SandboxFileSystem fileSystem, string packageVersion, int timeout)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;

View File

@@ -12,7 +12,7 @@ namespace YooAsset
Done,
}
private readonly CacheFileSystem _fileSystem;
private readonly SandboxFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly int _timeout;
private IDownloadFileRequest _webFileRequestOp;
@@ -20,7 +20,7 @@ namespace YooAsset
private ESteps _steps = ESteps.None;
internal DownloadPackageManifestOperation(CacheFileSystem fileSystem, string packageVersion, int timeout)
internal DownloadPackageManifestOperation(SandboxFileSystem fileSystem, string packageVersion, int timeout)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;

View File

@@ -13,13 +13,13 @@ namespace YooAsset
Done,
}
private readonly CacheFileSystem _fileSystem;
private readonly SandboxFileSystem _fileSystem;
private readonly string _sourceFilePath;
private readonly string _tempFilePath;
private FCWriteCacheOperation _bundleCacheOp;
private ESteps _steps = ESteps.None;
internal ImportAndCacheFileOperation(CacheFileSystem fileSystem, PackageBundle bundle, string sourceFilePath) : base(bundle, sourceFilePath)
internal ImportAndCacheFileOperation(SandboxFileSystem fileSystem, PackageBundle bundle, string sourceFilePath) : base(bundle, sourceFilePath)
{
_fileSystem = fileSystem;
_sourceFilePath = sourceFilePath;

View File

@@ -11,7 +11,7 @@ namespace YooAsset
Done,
}
private readonly CacheFileSystem _fileSystem;
private readonly SandboxFileSystem _fileSystem;
private readonly string _packageVersion;
private ESteps _steps = ESteps.None;
@@ -21,7 +21,7 @@ namespace YooAsset
public string PackageHash { private set; get; }
internal LoadCachePackageHashOperation(CacheFileSystem fileSystem, string packageVersion)
internal LoadCachePackageHashOperation(SandboxFileSystem fileSystem, string packageVersion)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;

View File

@@ -13,7 +13,7 @@ namespace YooAsset
Done,
}
private readonly CacheFileSystem _fileSystem;
private readonly SandboxFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly string _packageHash;
private DeserializeManifestOperation _deserializer;
@@ -26,7 +26,7 @@ namespace YooAsset
public PackageManifest Manifest { private set; get; }
internal LoadCachePackageManifestOperation(CacheFileSystem fileSystem, string packageVersion, string packageHash)
internal LoadCachePackageManifestOperation(SandboxFileSystem fileSystem, string packageVersion, string packageHash)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;
@@ -75,7 +75,7 @@ namespace YooAsset
{
if (_deserializer == null)
{
_deserializer = new DeserializeManifestOperation(_fileSystem.ManifestRestoreServices, _fileData);
_deserializer = new DeserializeManifestOperation(_fileSystem.ManifestDecryptor, _fileData);
_deserializer.StartOperation();
AddChildOperation(_deserializer);
}

View File

@@ -10,7 +10,7 @@ namespace YooAsset
Done,
}
private readonly CacheFileSystem _fileSystem;
private readonly SandboxFileSystem _fileSystem;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private IDownloadTextRequest _webTextRequestOp;
@@ -23,7 +23,7 @@ namespace YooAsset
internal string PackageVersion { set; get; }
internal RequestRemotePackageVersionOperation(CacheFileSystem fileSystem, bool appendTimeTicks, int timeout)
internal RequestRemotePackageVersionOperation(SandboxFileSystem fileSystem, bool appendTimeTicks, int timeout)
{
_fileSystem = fileSystem;
_appendTimeTicks = appendTimeTicks;

View File

@@ -3,7 +3,7 @@ using System.IO;
namespace YooAsset
{
internal class CFSClearCacheOperation : FSClearCacheOperation
internal class SFSClearCacheOperation : FSClearCacheOperation
{
private enum ESteps
{
@@ -12,12 +12,12 @@ namespace YooAsset
Done,
}
private readonly CacheFileSystem _fileSystem;
private readonly SandboxFileSystem _fileSystem;
private readonly ClearCacheOptions _options;
private FCClearCacheOperation _clearCacheOp;
private ESteps _steps = ESteps.None;
internal CFSClearCacheOperation(CacheFileSystem fileSystem, ClearCacheOptions options)
internal SFSClearCacheOperation(SandboxFileSystem fileSystem, ClearCacheOptions options)
{
_fileSystem = fileSystem;
_options = options;
@@ -68,10 +68,10 @@ namespace YooAsset
Done,
}
private readonly CacheFileSystem _fileSystem;
private readonly SandboxFileSystem _fileSystem;
private ESteps _steps = ESteps.None;
internal CFSClearAllCacheManifestOperation(CacheFileSystem fileSystem)
internal CFSClearAllCacheManifestOperation(SandboxFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
@@ -96,7 +96,7 @@ namespace YooAsset
foreach (FileInfo fileInfo in directoryInfo.GetFiles())
{
string fileName = fileInfo.Name;
if (fileName == DefaultCacheFileSystemDefine.AppFootPrintFileName)
if (fileName == SandboxFileSystemDefine.AppFootPrintFileName)
continue;
fileInfo.Delete();
@@ -126,11 +126,11 @@ namespace YooAsset
Done,
}
private readonly CacheFileSystem _fileSystem;
private readonly SandboxFileSystem _fileSystem;
private readonly PackageManifest _manifest;
private ESteps _steps = ESteps.None;
internal CFSClearUnusedCacheManifestOperation(CacheFileSystem fileSystem, PackageManifest manifest)
internal CFSClearUnusedCacheManifestOperation(SandboxFileSystem fileSystem, PackageManifest manifest)
{
_fileSystem = fileSystem;
_manifest = manifest;
@@ -173,7 +173,7 @@ namespace YooAsset
foreach (FileInfo fileInfo in directoryInfo.GetFiles())
{
string fileName = fileInfo.Name;
if (fileName == DefaultCacheFileSystemDefine.AppFootPrintFileName)
if (fileName == SandboxFileSystemDefine.AppFootPrintFileName)
continue;
if (fileName == activeManifestFileName || fileName == activeHashFileName)
continue;

View File

@@ -2,7 +2,7 @@ using UnityEngine;
namespace YooAsset
{
internal class CFSDownloadFileOperation : FSDownloadFileOperation
internal class SFSDownloadFileOperation : FSDownloadFileOperation
{
protected enum ESteps
{
@@ -13,7 +13,7 @@ namespace YooAsset
Done,
}
private readonly CacheFileSystem _fileSystem;
private readonly SandboxFileSystem _fileSystem;
private readonly DownloadFileOptions _options;
private DownloadFileBaseOperation _downloadFileOp;
private ESteps _steps = ESteps.None;
@@ -23,7 +23,7 @@ namespace YooAsset
private float _tryAgainTimer = 0;
private int _failedTryAgain;
internal CFSDownloadFileOperation(CacheFileSystem fileSystem, DownloadFileOptions options) : base(options.Bundle)
internal SFSDownloadFileOperation(SandboxFileSystem fileSystem, DownloadFileOptions options) : base(options.Bundle)
{
_fileSystem = fileSystem;
_options = options;

View File

@@ -1,7 +1,7 @@
namespace YooAsset
{
internal class CFSInitializeOperation : FSInitializeOperation
internal class SFSInitializeOperation : FSInitializeOperation
{
private enum ESteps
{
@@ -12,12 +12,12 @@ namespace YooAsset
Done,
}
private readonly CacheFileSystem _fileSystem;
private readonly SandboxFileSystem _fileSystem;
private FCInitializeOperation _initializeFileCacheOp;
private ESteps _steps = ESteps.None;
internal CFSInitializeOperation(CacheFileSystem fileSystem)
internal SFSInitializeOperation(SandboxFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
@@ -45,29 +45,29 @@ namespace YooAsset
// 如果水印发生变化,则说明覆盖安装后首次打开游戏
if (appFootprint.IsDirty())
{
if (_fileSystem.InstallClearMode == EInstallCleanupMode.None)
if (_fileSystem.InstallCleanupMode == EInstallCleanupMode.None)
{
YooLogger.Warning("Do nothing when overwrite install application.");
}
else if (_fileSystem.InstallClearMode == EInstallCleanupMode.ClearAllCacheFiles)
else if (_fileSystem.InstallCleanupMode == EInstallCleanupMode.ClearAllCacheFiles)
{
_fileSystem.DeleteAllBundleFiles();
_fileSystem.DeleteAllManifestFiles();
YooLogger.Warning("Delete all cache files when overwrite install application.");
}
else if (_fileSystem.InstallClearMode == EInstallCleanupMode.ClearAllBundleFiles)
else if (_fileSystem.InstallCleanupMode == EInstallCleanupMode.ClearAllBundleFiles)
{
_fileSystem.DeleteAllBundleFiles();
YooLogger.Warning("Delete all bundle files when overwrite install application.");
}
else if (_fileSystem.InstallClearMode == EInstallCleanupMode.ClearAllManifestFiles)
else if (_fileSystem.InstallCleanupMode == EInstallCleanupMode.ClearAllManifestFiles)
{
_fileSystem.DeleteAllManifestFiles();
YooLogger.Warning("Delete all manifest files when overwrite install application.");
}
else
{
throw new System.NotImplementedException(_fileSystem.InstallClearMode.ToString());
throw new System.NotImplementedException(_fileSystem.InstallCleanupMode.ToString());
}
appFootprint.Coverage(_fileSystem.PackageName);

View File

@@ -1,7 +1,7 @@
namespace YooAsset
{
internal class CFSLoadBundleOperation : FSLoadBundleOperation
internal class SFSLoadBundleOperation : FSLoadBundleOperation
{
private enum ESteps
{
@@ -14,13 +14,13 @@ namespace YooAsset
Done,
}
private readonly CacheFileSystem _fileSystem;
private readonly SandboxFileSystem _fileSystem;
private readonly LoadBundleOptions _options;
private FSDownloadFileOperation _downloadFileOp;
private FCLoadBundleOperation _loadBundleOp;
private ESteps _steps = ESteps.None;
internal CFSLoadBundleOperation(CacheFileSystem fileSystem, LoadBundleOptions options)
internal SFSLoadBundleOperation(SandboxFileSystem fileSystem, LoadBundleOptions options)
{
_fileSystem = fileSystem;
_options = options;
@@ -139,7 +139,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Loaded bundle result is null.";
Error = "Fatal error: loaded bundle result is null.";
YooLogger.Error(Error);
}
else

View File

@@ -2,7 +2,7 @@
namespace YooAsset
{
internal class CFSLoadPackageManifestOperation : FSLoadManifestOperation
internal class SFSLoadPackageManifestOperation : FSLoadManifestOperation
{
private enum ESteps
{
@@ -14,7 +14,7 @@ namespace YooAsset
Done,
}
private readonly CacheFileSystem _fileSystem;
private readonly SandboxFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly int _timeout;
private DownloadPackageHashOperation _downloadPackageHashOp;
@@ -24,7 +24,7 @@ namespace YooAsset
private ESteps _steps = ESteps.None;
internal CFSLoadPackageManifestOperation(CacheFileSystem fileSystem, string packageVersion, int timeout)
internal SFSLoadPackageManifestOperation(SandboxFileSystem fileSystem, string packageVersion, int timeout)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;

View File

@@ -1,7 +1,7 @@

namespace YooAsset
{
internal class CFSRequestPackageVersionOperation : FSRequestVersionOperation
internal class SFSRequestPackageVersionOperation : FSRequestVersionOperation
{
private enum ESteps
{
@@ -10,14 +10,14 @@ namespace YooAsset
Done,
}
private readonly CacheFileSystem _fileSystem;
private readonly SandboxFileSystem _fileSystem;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private RequestRemotePackageVersionOperation _requestRemotePackageVersionOp;
private ESteps _steps = ESteps.None;
internal CFSRequestPackageVersionOperation(CacheFileSystem fileSystem, bool appendTimeTicks, int timeout)
internal SFSRequestPackageVersionOperation(SandboxFileSystem fileSystem, bool appendTimeTicks, int timeout)
{
_fileSystem = fileSystem;
_appendTimeTicks = appendTimeTicks;

View File

@@ -7,10 +7,9 @@ using UnityEngine;
namespace YooAsset
{
/// <summary>
/// 缓存文件系统
/// 说明正在进行的下载器会在ResourcePackage销毁的时候执行Abort操作
/// 沙盒文件系统
/// </summary>
internal class CacheFileSystem : IFileSystem
internal class SandboxFileSystem : IFileSystem
{
protected readonly Dictionary<string, string> _tempFilePathMapping = new Dictionary<string, string>(10000);
protected string _packageRoot;
@@ -52,12 +51,12 @@ namespace YooAsset
/// <summary>
/// 自定义参数:覆盖安装缓存清理模式
/// </summary>
public EInstallCleanupMode InstallClearMode { private set; get; } = EInstallCleanupMode.ClearAllManifestFiles;
public EInstallCleanupMode InstallCleanupMode { private set; get; } = EInstallCleanupMode.None;
/// <summary>
/// 自定义参数:初始化的时候缓存文件校验级别
/// </summary>
public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle;
public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Low;
/// <summary>
/// 自定义参数:初始化的时候缓存文件校验最大并发数
@@ -101,27 +100,42 @@ namespace YooAsset
public List<long> ResumeDownloadResponseCodes { private set; get; } = null;
/// <summary>
/// 自定义参数:资源清单服务类
/// 自定义参数:AssetBundle 解密器
/// </summary>
public IManifestRestoreServices ManifestRestoreServices { private set; get; }
public IBundleDecryptor AssetBundleDecryptor { get; set; }
/// <summary>
/// 自定义参数RawBundle 解密器
/// </summary>
public IBundleDecryptor RawBundleDecryptor { get; set; }
/// <summary>
/// 自定义参数AssetBundle 备用解密器
/// </summary>
public IBundleMemoryDecryptor AssetBundleFallbackDecryptor { get; set; }
/// <summary>
/// 自定义参数:资源清单解密器
/// </summary>
public IManifestDecryptor ManifestDecryptor { private set; get; }
#endregion
public CacheFileSystem()
public SandboxFileSystem()
{
}
public virtual FSInitializeOperation InitializeAsync()
{
var operation = new CFSInitializeOperation(this);
var operation = new SFSInitializeOperation(this);
return operation;
}
public virtual FSRequestVersionOperation RequestVersionAsync(RequestVersionOptions options)
{
var operation = new CFSRequestPackageVersionOperation(this, options.AppendTimeTicks, options.Timeout);
var operation = new SFSRequestPackageVersionOperation(this, options.AppendTimeTicks, options.Timeout);
return operation;
}
public virtual FSLoadManifestOperation LoadManifestAsync(LoadManifestOptions options)
{
var operation = new CFSLoadPackageManifestOperation(this, options.PackageVersion, options.Timeout);
var operation = new SFSLoadPackageManifestOperation(this, options.PackageVersion, options.Timeout);
return operation;
}
public virtual FSClearCacheOperation ClearCacheAsync(ClearCacheOptions options)
@@ -138,18 +152,18 @@ namespace YooAsset
}
else
{
var operation = new CFSClearCacheOperation(this, options);
var operation = new SFSClearCacheOperation(this, options);
return operation;
}
}
public virtual FSDownloadFileOperation DownloadFileAsync(DownloadFileOptions options)
{
var downloader = new CFSDownloadFileOperation(this, options);
var downloader = new SFSDownloadFileOperation(this, options);
return downloader;
}
public virtual FSLoadBundleOperation LoadBundleAsync(LoadBundleOptions options)
{
var operation = new CFSLoadBundleOperation(this, options);
var operation = new SFSLoadBundleOperation(this, options);
return operation;
}
@@ -169,7 +183,7 @@ namespace YooAsset
}
else if (name == FileSystemParametersDefine.INSTALL_CLEAR_MODE)
{
InstallClearMode = (EInstallCleanupMode)value;
InstallCleanupMode = (EInstallCleanupMode)value;
}
else if (name == FileSystemParametersDefine.FILE_VERIFY_LEVEL)
{
@@ -186,7 +200,7 @@ namespace YooAsset
// 限制在合理范围内1-32
FileVerifyMaxConcurrency = Mathf.Clamp(convertValue, 1, 32);
}
else if (name == FileSystemParametersDefine.DISABLE_ONDEMAND_DOWNLOAD)
else if (name == FileSystemParametersDefine.DOWNLOAD_DISABLE_ONDEMAND)
{
DisableOnDemandDownload = Convert.ToBoolean(value);
}
@@ -217,17 +231,29 @@ namespace YooAsset
int convertValue = Convert.ToInt32(value);
DownloadWatchDogTimeout = Mathf.Clamp(convertValue, 0, int.MaxValue);
}
else if (name == FileSystemParametersDefine.RESUME_DOWNLOAD_MINMUM_SIZE)
else if (name == FileSystemParametersDefine.DOWNLOAD_RESUME_MINMUM_SIZE)
{
ResumeDownloadMinimumSize = Convert.ToInt64(value);
}
else if (name == FileSystemParametersDefine.RESUME_DOWNLOAD_RESPONSE_CODES)
else if (name == FileSystemParametersDefine.DOWNLOAD_RESUME_RESPONSE_CODES)
{
ResumeDownloadResponseCodes = (List<long>)value;
}
else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES)
else if (name == FileSystemParametersDefine.ASSETBUNDLE_DECRYPTOR)
{
ManifestRestoreServices = (IManifestRestoreServices)value;
AssetBundleDecryptor = (IBundleDecryptor)value;
}
else if (name == FileSystemParametersDefine.RAWBUNDLE_DECRYPTOR)
{
RawBundleDecryptor = (IBundleDecryptor)value;
}
else if (name == FileSystemParametersDefine.ASSETBUNDLE_FALLBACK_DECRYPTOR)
{
AssetBundleFallbackDecryptor = (IBundleMemoryDecryptor)value;
}
else if (name == FileSystemParametersDefine.MANIFEST_DECRYPTOR)
{
ManifestDecryptor = (IManifestDecryptor)value;
}
else
{
@@ -243,15 +269,18 @@ namespace YooAsset
else
_packageRoot = packageRoot;
_cacheBundleFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.BundleFilesFolderName);
_cacheManifestFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.ManifestFilesFolderName);
_tempFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.TempFilesFolderName);
_cacheBundleFilesRoot = PathUtility.Combine(_packageRoot, SandboxFileSystemDefine.BundleFilesFolderName);
_cacheManifestFilesRoot = PathUtility.Combine(_packageRoot, SandboxFileSystemDefine.ManifestFilesFolderName);
_tempFilesRoot = PathUtility.Combine(_packageRoot, SandboxFileSystemDefine.TempFilesFolderName);
// 创建文件缓存系统
{
var cacheConfig = new SandboxFileCache.CacheConfig();
cacheConfig.FileVerifyLevel = FileVerifyLevel;
cacheConfig.FileVerifyMaxConcurrency = FileVerifyMaxConcurrency;
cacheConfig.FileVerifyLevel = FileVerifyLevel;
cacheConfig.AssetBundleDecryptor = AssetBundleDecryptor;
cacheConfig.RawBundleDecryptor = RawBundleDecryptor;
cacheConfig.AssetBundleFallbackDecryptor = AssetBundleFallbackDecryptor;
FileCache = new SandboxFileCache(PackageName, _cacheBundleFilesRoot, cacheConfig);
}
@@ -326,7 +355,7 @@ namespace YooAsset
}
public string GetSandboxAppFootPrintFilePath()
{
return PathUtility.Combine(_cacheManifestFilesRoot, DefaultCacheFileSystemDefine.AppFootPrintFileName);
return PathUtility.Combine(_cacheManifestFilesRoot, SandboxFileSystemDefine.AppFootPrintFileName);
}
public string GetTempFilePath(PackageBundle bundle)
{

View File

@@ -1,7 +1,7 @@

namespace YooAsset
{
internal class DefaultCacheFileSystemDefine
internal class SandboxFileSystemDefine
{
/// <summary>
/// 记录应用程序版本的文件名称

View File

@@ -1,55 +0,0 @@
using UnityEngine;
namespace YooAsset
{
/// <summary>
/// 加载 AssetBundle 的抽象基类
/// 用户可继承此类实现自定义加载逻辑(如加密解密)
/// </summary>
public abstract class LoadWebAssetBundleOperation : AsyncOperationBase
{
protected readonly LoadWebAssetBundleOptions _options;
/// <summary>
/// 加载结果AssetBundle 对象
/// </summary>
public AssetBundle Result { get; protected set; }
/// <summary>
/// 下载进度
/// </summary>
public float DownloadProgress { protected set; get; }
/// <summary>
/// 下载大小
/// </summary>
public long DownloadedBytes { protected set; get; }
public LoadWebAssetBundleOperation(LoadWebAssetBundleOptions options)
{
_options = options;
}
}
/// <summary>
/// 立即完成(失败)的 AssetBundle 加载操作
/// 用途:当 Factory 判定某种场景不支持(例如默认实现不支持加密包)时,返回该 Operation
/// </summary>
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()
{
}
}
}

View File

@@ -1,44 +0,0 @@
namespace YooAsset
{
/// <summary>
/// 加载 AssetBundle 的上下文信息
/// </summary>
public struct LoadWebAssetBundleOptions
{
/// <summary>
/// 资源包信息
/// </summary>
internal PackageBundle Bundle { get; set; }
/// <summary>
/// 失败后重试次数
/// </summary>
internal int RetryCount { get; set; }
/// <summary>
/// 看门狗超时时间
/// </summary>
internal int WatchdogTimeout { get; set; }
/// <summary>
/// 下载后台接口
/// </summary>
internal IDownloadBackend DownloadBackend { get; set; }
/// <summary>
/// 禁用Unity的网络缓存
/// </summary>
internal bool DisableUnityWebCache { get; set; }
/// <summary>
/// 主资源地址
/// </summary>
internal string MainURL { get; set; }
/// <summary>
/// 备用资源地址
/// </summary>
internal string FallbackURL { get; set; }
}
}

View File

@@ -11,7 +11,7 @@ internal class LoadWebPackageManifestOperation : AsyncOperationBase
Done,
}
private readonly IManifestRestoreServices _manifestServices;
private readonly IManifestDecryptor _manifestDecryptor;
private readonly IRemoteServices _remoteServices;
private readonly IDownloadBackend _downloadBackend;
private readonly string _packageName;
@@ -29,10 +29,10 @@ internal class LoadWebPackageManifestOperation : AsyncOperationBase
public PackageManifest Manifest { private set; get; }
internal LoadWebPackageManifestOperation(IManifestRestoreServices manifestServices, IRemoteServices remoteServices, IDownloadBackend downloadBackend,
internal LoadWebPackageManifestOperation(IManifestDecryptor manifestDecryptor, IRemoteServices remoteServices, IDownloadBackend downloadBackend,
string packageName, string packageVersion, string packageHash, int timeout)
{
_manifestServices = manifestServices;
_manifestDecryptor = manifestDecryptor;
_remoteServices = remoteServices;
_downloadBackend = downloadBackend;
_packageName = packageName;
@@ -96,7 +96,7 @@ internal class LoadWebPackageManifestOperation : AsyncOperationBase
{
if (_deserializer == null)
{
_deserializer = new DeserializeManifestOperation(_manifestServices, _webDataRequestOp.Result);
_deserializer = new DeserializeManifestOperation(_manifestDecryptor, _webDataRequestOp.Result);
_deserializer.StartOperation();
AddChildOperation(_deserializer);
}

Some files were not shown because too many files have changed in this diff Show More