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