mirror of
https://github.com/tuyoogame/YooAsset.git
synced 2026-05-27 11:10:11 +00:00
refactor : 重构代码
This commit is contained in:
@@ -36,14 +36,6 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
return _fileSystem.GetBundleFilePath(_packageBundle);
|
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)
|
public override FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -93,11 +93,11 @@ namespace YooAsset
|
|||||||
error = $"Failed to load asset : {_assetInfo.AssetPath} AssetType : null AssetBundle : {_packageBundle.BundleName}";
|
error = $"Failed to load asset : {_assetInfo.AssetPath} AssetType : null AssetBundle : {_packageBundle.BundleName}";
|
||||||
else
|
else
|
||||||
error = $"Failed to load asset : {_assetInfo.AssetPath} AssetType : {_assetInfo.AssetType} AssetBundle : {_packageBundle.BundleName}";
|
error = $"Failed to load asset : {_assetInfo.AssetPath} AssetType : {_assetInfo.AssetType} AssetBundle : {_packageBundle.BundleName}";
|
||||||
YooLogger.Error(error);
|
|
||||||
|
|
||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
Error = error;
|
|
||||||
Status = EOperationStatus.Failed;
|
Status = EOperationStatus.Failed;
|
||||||
|
Error = error;
|
||||||
|
YooLogger.Error(Error);
|
||||||
}
|
}
|
||||||
else
|
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
|
fileFormatVersion: 2
|
||||||
guid: 3b82b4b846083d34b958320b584d8d9b
|
guid: 067ac2067f265624bac214127575d7d5
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
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
|
fileFormatVersion: 2
|
||||||
guid: 3444518ef1b082a46a9855fef4f69c86
|
guid: 05b4aa37709184a408090202f98b93d3
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
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
|
fileFormatVersion: 2
|
||||||
guid: 2f88823353464474faf7b020a76f9b2d
|
guid: 32e01cb4600c49f42b8ec19be8f0fb22
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
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
|
fileFormatVersion: 2
|
||||||
guid: 174e56f3a30d7fd4e80bde43ba267631
|
guid: b866c4ec2f032aa4eb0d4f9094273100
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
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
|
fileFormatVersion: 2
|
||||||
guid: 0f65d2f6038b95246b7a09cec4055b3a
|
guid: f0fd9af541471154d9fc968abd450d31
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
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();
|
public abstract void UnloadBundleFile();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取资源包文件的路径
|
/// 获取资源包文件的本地路径
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract string GetBundleFilePath();
|
public abstract string GetBundleFilePath();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 读取资源包文件的二进制数据
|
|
||||||
/// </summary>
|
|
||||||
public abstract byte[] ReadBundleFileData();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 读取资源包文件的文本数据
|
|
||||||
/// </summary>
|
|
||||||
public abstract string ReadBundleFileText();
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <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
|
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()
|
internal override void InternalStart()
|
||||||
{
|
{
|
||||||
Error = $"{nameof(RawBundleLoadAssetOperation)} not support load asset.";
|
_steps = ESteps.LoadObject;
|
||||||
Status = EOperationStatus.Failed;
|
|
||||||
}
|
}
|
||||||
internal override void InternalUpdate()
|
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 IFileSystem _fileSystem;
|
||||||
private readonly PackageBundle _packageBundle;
|
private readonly PackageBundle _packageBundle;
|
||||||
|
private readonly RawBundle _rawBundle;
|
||||||
|
|
||||||
public RawBundleResult(IFileSystem fileSystem, PackageBundle packageBundle)
|
public RawBundleResult(IFileSystem fileSystem, PackageBundle packageBundle, RawBundle rawBundle)
|
||||||
{
|
{
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
_packageBundle = packageBundle;
|
_packageBundle = packageBundle;
|
||||||
|
_rawBundle = rawBundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UnloadBundleFile()
|
public override void UnloadBundleFile()
|
||||||
{
|
{
|
||||||
|
if (_rawBundle != null)
|
||||||
|
{
|
||||||
|
_rawBundle.Unload();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public override string GetBundleFilePath()
|
public override string GetBundleFilePath()
|
||||||
{
|
{
|
||||||
return _fileSystem.GetBundleFilePath(_packageBundle);
|
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)
|
public override FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo)
|
||||||
{
|
{
|
||||||
var operation = new RawBundleLoadAssetOperation();
|
var operation = new RawBundleLoadAssetOperation(_packageBundle, _rawBundle, assetInfo);
|
||||||
return operation;
|
return operation;
|
||||||
}
|
}
|
||||||
public override FSLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo)
|
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);
|
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)
|
public override FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace YooAsset
|
namespace YooAsset
|
||||||
@@ -81,13 +81,11 @@ namespace YooAsset
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建默认的内置文件系统参数
|
/// 创建默认的内置文件系统参数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="decryptionServices">加密文件解密服务类</param>
|
|
||||||
/// <param name="packageRoot">文件系统的根目录</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;
|
string fileSystemClass = typeof(BuiltinFileSystem).FullName;
|
||||||
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
|
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
|
||||||
fileSystemParams.AddParameter(FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES, decryptionServices);
|
|
||||||
return fileSystemParams;
|
return fileSystemParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,14 +93,12 @@ namespace YooAsset
|
|||||||
/// 创建默认的缓存文件系统参数
|
/// 创建默认的缓存文件系统参数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="remoteServices">远端资源地址查询服务类</param>
|
/// <param name="remoteServices">远端资源地址查询服务类</param>
|
||||||
/// <param name="decryptionServices">加密文件解密服务类</param>
|
|
||||||
/// <param name="packageRoot">文件系统的根目录</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;
|
string fileSystemClass = typeof(CacheFileSystem).FullName;
|
||||||
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
|
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
|
||||||
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
|
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
|
||||||
fileSystemParams.AddParameter(FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES, decryptionServices);
|
|
||||||
return fileSystemParams;
|
return fileSystemParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,11 +107,10 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="decryptionServices">加密文件解密服务类</param>
|
/// <param name="decryptionServices">加密文件解密服务类</param>
|
||||||
/// <param name="disableUnityWebCache">禁用Unity的网络缓存</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;
|
string fileSystemClass = typeof(WebServerFileSystem).FullName;
|
||||||
var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
|
var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
|
||||||
fileSystemParams.AddParameter(FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES, decryptionServices);
|
|
||||||
fileSystemParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, disableUnityWebCache);
|
fileSystemParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, disableUnityWebCache);
|
||||||
return fileSystemParams;
|
return fileSystemParams;
|
||||||
}
|
}
|
||||||
@@ -126,12 +121,11 @@ namespace YooAsset
|
|||||||
/// <param name="remoteServices">远端资源地址查询服务类</param>
|
/// <param name="remoteServices">远端资源地址查询服务类</param>
|
||||||
/// <param name="decryptionServices">加密文件解密服务类</param>
|
/// <param name="decryptionServices">加密文件解密服务类</param>
|
||||||
/// <param name="disableUnityWebCache">禁用Unity的网络缓存</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;
|
string fileSystemClass = typeof(WebRemoteFileSystem).FullName;
|
||||||
var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
|
var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
|
||||||
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
|
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
|
||||||
fileSystemParams.AddParameter(FileSystemParametersDefine.BUNDLE_DECRYPTION_SERVICES, decryptionServices);
|
|
||||||
fileSystemParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, disableUnityWebCache);
|
fileSystemParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, disableUnityWebCache);
|
||||||
return fileSystemParams;
|
return fileSystemParams;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
namespace YooAsset
|
namespace YooAsset
|
||||||
{
|
{
|
||||||
public class FileSystemParametersDefine
|
public class FileSystemParametersDefine
|
||||||
@@ -24,9 +24,14 @@ namespace YooAsset
|
|||||||
public const string REMOTE_SERVICES = "REMOTE_SERVICES";
|
public const string REMOTE_SERVICES = "REMOTE_SERVICES";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 解密服务接口的实例类 <see cref=IBundleDecryptionServices>
|
/// 加载 AssetBundle 的 Operation 工厂委托
|
||||||
/// </summary>
|
/// </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>
|
/// <summary>
|
||||||
/// 资源清单服务类 <see cref=IManifestRestoreServices>
|
/// 资源清单服务类 <see cref=IManifestRestoreServices>
|
||||||
@@ -74,7 +79,7 @@ namespace YooAsset
|
|||||||
public const string DOWNLOAD_MAX_REQUEST_PER_FRAME = "DOWNLOAD_MAX_REQUEST_PER_FRAME";
|
public const string DOWNLOAD_MAX_REQUEST_PER_FRAME = "DOWNLOAD_MAX_REQUEST_PER_FRAME";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 下载任务的看门狗机制监控时间 <see cref=int>
|
/// 下载任务的看门狗机制超时时间 <see cref=int>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string DOWNLOAD_WATCH_DOG_TIME = "DOWNLOAD_WATCH_DOG_TIME";
|
public const string DOWNLOAD_WATCH_DOG_TIME = "DOWNLOAD_WATCH_DOG_TIME";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@@ -105,9 +105,14 @@ namespace YooAsset
|
|||||||
public string UnpackFileSystemRoot { private set; get; }
|
public string UnpackFileSystemRoot { private set; get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 自定义参数:解密服务接口的实例类
|
/// 自定义参数:加载 AssetBundle 的工厂委托
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IBundleDecryptionServices BundleDecryptionServices { private set; get; }
|
public LoadAssetBundleOperationFactory LoadAssetBundleFactory { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义参数:加载 RawBundle 的工厂委托
|
||||||
|
/// </summary>
|
||||||
|
public LoadRawBundleOperationFactory LoadRawBundleFactory { private set; get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 自定义参数:资源清单服务类
|
/// 自定义参数:资源清单服务类
|
||||||
@@ -225,9 +230,13 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
UnpackFileSystemRoot = (string)value;
|
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)
|
else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES)
|
||||||
{
|
{
|
||||||
@@ -255,6 +264,14 @@ namespace YooAsset
|
|||||||
if (DownloadBackend == null)
|
if (DownloadBackend == null)
|
||||||
DownloadBackend = new UnityWebRequestBackend(WebRequestCreator);
|
DownloadBackend = new UnityWebRequestBackend(WebRequestCreator);
|
||||||
|
|
||||||
|
// 创建默认的 AssetBundle 加载工厂
|
||||||
|
if (LoadAssetBundleFactory == null)
|
||||||
|
LoadAssetBundleFactory = DefaultLoadAssetBundleOperationFactory;
|
||||||
|
|
||||||
|
// 创建默认的 RawBundle 加载工厂
|
||||||
|
if (LoadRawBundleFactory == null)
|
||||||
|
LoadRawBundleFactory = DefaultLoadRawBundleOperationFactory;
|
||||||
|
|
||||||
// 创建解压文件系统
|
// 创建解压文件系统
|
||||||
var remoteServices = new UnpackRemoteService(_packageRoot);
|
var remoteServices = new UnpackRemoteService(_packageRoot);
|
||||||
_unpackFileSystem = new UnpackFileSystem();
|
_unpackFileSystem = new UnpackFileSystem();
|
||||||
@@ -265,7 +282,8 @@ namespace YooAsset
|
|||||||
_unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, FileVerifyLevel);
|
_unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, FileVerifyLevel);
|
||||||
_unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_MAX_CONCURRENCY, FileVerifyMaxConcurrency);
|
_unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_MAX_CONCURRENCY, FileVerifyMaxConcurrency);
|
||||||
_unpackFileSystem.SetParameter(FileSystemParametersDefine.APPEND_FILE_EXTENSION, AppendFileExtension);
|
_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.SetParameter(FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES, CopyLocalFileServices);
|
||||||
_unpackFileSystem.OnCreate(packageName, UnpackFileSystemRoot);
|
_unpackFileSystem.OnCreate(packageName, UnpackFileSystemRoot);
|
||||||
}
|
}
|
||||||
@@ -315,88 +333,15 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual string GetBundleFilePath(PackageBundle bundle)
|
public virtual string GetBundleFilePath(PackageBundle bundle)
|
||||||
{
|
{
|
||||||
if (IsUnpackBundleFile(bundle))
|
if (IsUnpackBundleFile(bundle))
|
||||||
|
{
|
||||||
return _unpackFileSystem.GetBundleFilePath(bundle);
|
return _unpackFileSystem.GetBundleFilePath(bundle);
|
||||||
|
}
|
||||||
|
|
||||||
return GetBuiltinFileLoadPath(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>
|
/// <summary>
|
||||||
/// 是否属于解压资源包文件
|
/// 是否属于解压资源包文件
|
||||||
@@ -420,6 +365,30 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
|
|
||||||
#region 内部方法
|
#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)
|
protected string GetDefaultBuiltinPackageRoot(string packageName)
|
||||||
{
|
{
|
||||||
string rootDirectory = YooAssetSettingsData.GetYooDefaultBuildinRoot();
|
string rootDirectory = YooAssetSettingsData.GetYooDefaultBuildinRoot();
|
||||||
@@ -476,36 +445,6 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
return _unpackFileSystem.InitializeAsync();
|
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
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,24 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace YooAsset
|
namespace YooAsset
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 加载AssetBundle文件
|
/// 加载 AssetBundle 文件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class BFSLoadAssetBundleOperation : FSLoadBundleOperation
|
internal class BFSLoadAssetBundleOperation : FSLoadBundleOperation
|
||||||
{
|
{
|
||||||
private enum ESteps
|
private enum ESteps
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
LoadAssetBundle,
|
LoadBuiltinAssetBundle,
|
||||||
CheckResult,
|
CheckResult,
|
||||||
Done,
|
Done,
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly BuiltinFileSystem _fileSystem;
|
private readonly BuiltinFileSystem _fileSystem;
|
||||||
private readonly PackageBundle _bundle;
|
private readonly PackageBundle _bundle;
|
||||||
private AssetBundleCreateRequest _createRequest;
|
private LoadAssetBundleOperation _loadAssetBundleOp;
|
||||||
private AssetBundle _assetBundle;
|
|
||||||
private Stream _managedStream;
|
|
||||||
private ESteps _steps = ESteps.None;
|
private ESteps _steps = ESteps.None;
|
||||||
|
|
||||||
|
|
||||||
@@ -33,99 +31,55 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
DownloadProgress = 1f;
|
DownloadProgress = 1f;
|
||||||
DownloadedBytes = _bundle.FileSize;
|
DownloadedBytes = _bundle.FileSize;
|
||||||
_steps = ESteps.LoadAssetBundle;
|
_steps = ESteps.LoadBuiltinAssetBundle;
|
||||||
}
|
}
|
||||||
internal override void InternalUpdate()
|
internal override void InternalUpdate()
|
||||||
{
|
{
|
||||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_steps == ESteps.LoadAssetBundle)
|
if (_steps == ESteps.LoadBuiltinAssetBundle)
|
||||||
{
|
{
|
||||||
if (_bundle.Encrypted)
|
var options = new LoadAssetBundleOptions();
|
||||||
{
|
options.FileLoadPath = _fileSystem.GetBuiltinFileLoadPath(_bundle);
|
||||||
if (_fileSystem.BundleDecryptionServices == null)
|
options.Bundle = _bundle;
|
||||||
{
|
_loadAssetBundleOp = _fileSystem.LoadAssetBundleFactory.Invoke(_bundle.Encrypted, options);
|
||||||
_steps = ESteps.Done;
|
_loadAssetBundleOp.StartOperation();
|
||||||
Status = EOperationStatus.Failed;
|
AddChildOperation(_loadAssetBundleOp);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_steps = ESteps.CheckResult;
|
_steps = ESteps.CheckResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_steps == ESteps.CheckResult)
|
if (_steps == ESteps.CheckResult)
|
||||||
{
|
{
|
||||||
if (_createRequest != null)
|
if (IsWaitingForAsyncComplete)
|
||||||
{
|
_loadAssetBundleOp.WaitForAsyncComplete();
|
||||||
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 (_assetBundle == null)
|
_loadAssetBundleOp.UpdateOperation();
|
||||||
|
if (_loadAssetBundleOp.IsDone == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_loadAssetBundleOp.Status == EOperationStatus.Succeed)
|
||||||
{
|
{
|
||||||
if (_bundle.Encrypted)
|
if (_loadAssetBundleOp.Result == null)
|
||||||
{
|
{
|
||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
Status = EOperationStatus.Failed;
|
Status = EOperationStatus.Failed;
|
||||||
Error = $"Failed to load encrypted buildin asset bundle file : {_bundle.BundleName}";
|
Error = "Loaded builtin asset bundle is null.";
|
||||||
YooLogger.Error(Error);
|
YooLogger.Error(Error);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
Status = EOperationStatus.Failed;
|
Result = new AssetBundleResult(_fileSystem, _bundle, _loadAssetBundleOp.Result, _loadAssetBundleOp.ManagedStream);
|
||||||
Error = $"Failed to load buildin asset bundle file : {_bundle.BundleName}";
|
Status = EOperationStatus.Succeed;
|
||||||
YooLogger.Error(Error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
Result = new AssetBundleResult(_fileSystem, _bundle, _assetBundle, _managedStream);
|
Status = EOperationStatus.Failed;
|
||||||
Status = EOperationStatus.Succeed;
|
Error = _loadAssetBundleOp.Error;
|
||||||
|
YooLogger.Error(Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,7 +90,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 加载原生文件
|
/// 加载 RawBundle 文件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class BFSLoadRawBundleOperation : FSLoadBundleOperation
|
internal class BFSLoadRawBundleOperation : FSLoadBundleOperation
|
||||||
{
|
{
|
||||||
@@ -144,11 +98,13 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
LoadBuiltinRawBundle,
|
LoadBuiltinRawBundle,
|
||||||
|
CheckResult,
|
||||||
Done,
|
Done,
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly BuiltinFileSystem _fileSystem;
|
private readonly BuiltinFileSystem _fileSystem;
|
||||||
private readonly PackageBundle _bundle;
|
private readonly PackageBundle _bundle;
|
||||||
|
private LoadRawBundleOperation _loadRawBundleOp;
|
||||||
private ESteps _steps = ESteps.None;
|
private ESteps _steps = ESteps.None;
|
||||||
|
|
||||||
|
|
||||||
@@ -170,29 +126,47 @@ namespace YooAsset
|
|||||||
|
|
||||||
if (_steps == ESteps.LoadBuiltinRawBundle)
|
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
|
if (_steps == ESteps.CheckResult)
|
||||||
//TODO : 安卓平台内置文件属于APK压缩包内的文件。
|
{
|
||||||
_steps = ESteps.Done;
|
if (IsWaitingForAsyncComplete)
|
||||||
Status = EOperationStatus.Failed;
|
_loadRawBundleOp.WaitForAsyncComplete();
|
||||||
Error = $"Can not load android buildin raw bundle file : {filePath}";
|
|
||||||
YooLogger.Error(Error);
|
_loadRawBundleOp.UpdateOperation();
|
||||||
#else
|
if (_loadRawBundleOp.IsDone == false)
|
||||||
if (File.Exists(filePath))
|
return;
|
||||||
|
|
||||||
|
if (_loadRawBundleOp.Status == EOperationStatus.Succeed)
|
||||||
{
|
{
|
||||||
_steps = ESteps.Done;
|
if (_loadRawBundleOp.Result == null)
|
||||||
Result = new RawBundleResult(_fileSystem, _bundle);
|
{
|
||||||
Status = EOperationStatus.Succeed;
|
_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
|
else
|
||||||
{
|
{
|
||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
Status = EOperationStatus.Failed;
|
Status = EOperationStatus.Failed;
|
||||||
Error = $"Can not found buildin raw bundle file : {filePath}";
|
Error = _loadRawBundleOp.Error;
|
||||||
YooLogger.Error(Error);
|
YooLogger.Error(Error);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal override void InternalWaitForAsyncComplete()
|
internal override void InternalWaitForAsyncComplete()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -112,9 +112,9 @@ namespace YooAsset
|
|||||||
public int DownloadMaxRequestPerFrame { private set; get; } = 5;
|
public int DownloadMaxRequestPerFrame { private set; get; } = 5;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 自定义参数:下载任务的看门狗机制监控时间
|
/// 自定义参数:下载任务的看门狗机制超时时间
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int DownloadWatchDogTime { private set; get; } = 0;
|
public int DownloadWatchDogTimeout { private set; get; } = 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 自定义参数:启用断点续传的最小尺寸
|
/// 自定义参数:启用断点续传的最小尺寸
|
||||||
@@ -127,9 +127,14 @@ namespace YooAsset
|
|||||||
public List<long> ResumeDownloadResponseCodes { private set; get; } = null;
|
public List<long> ResumeDownloadResponseCodes { private set; get; } = null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 自定义参数:解密服务接口的实例类
|
/// 自定义参数:加载 AssetBundle 的工厂委托
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IBundleDecryptionServices BundleDecryptionServices { private set; get; }
|
public LoadAssetBundleOperationFactory LoadAssetBundleFactory { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义参数:加载 RawBundle 的工厂委托
|
||||||
|
/// </summary>
|
||||||
|
public LoadRawBundleOperationFactory LoadRawBundleFactory { private set; get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 自定义参数:资源清单服务类
|
/// 自定义参数:资源清单服务类
|
||||||
@@ -307,7 +312,7 @@ namespace YooAsset
|
|||||||
else if (name == FileSystemParametersDefine.DOWNLOAD_WATCH_DOG_TIME)
|
else if (name == FileSystemParametersDefine.DOWNLOAD_WATCH_DOG_TIME)
|
||||||
{
|
{
|
||||||
int convertValue = Convert.ToInt32(value);
|
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)
|
else if (name == FileSystemParametersDefine.RESUME_DOWNLOAD_MINMUM_SIZE)
|
||||||
{
|
{
|
||||||
@@ -317,9 +322,13 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
ResumeDownloadResponseCodes = (List<long>)value;
|
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)
|
else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES)
|
||||||
{
|
{
|
||||||
@@ -350,6 +359,14 @@ namespace YooAsset
|
|||||||
// 创建默认的下载后台接口
|
// 创建默认的下载后台接口
|
||||||
if (DownloadBackend == null)
|
if (DownloadBackend == null)
|
||||||
DownloadBackend = new UnityWebRequestBackend(WebRequestCreator);
|
DownloadBackend = new UnityWebRequestBackend(WebRequestCreator);
|
||||||
|
|
||||||
|
// 创建默认的 AssetBundle 加载工厂
|
||||||
|
if (LoadAssetBundleFactory == null)
|
||||||
|
LoadAssetBundleFactory = DefaultLoadAssetBundleOperationFactory;
|
||||||
|
|
||||||
|
// 创建默认的 RawBundle 加载工厂
|
||||||
|
if (LoadRawBundleFactory == null)
|
||||||
|
LoadRawBundleFactory = DefaultLoadRawBundleOperationFactory;
|
||||||
}
|
}
|
||||||
public virtual void OnDestroy()
|
public virtual void OnDestroy()
|
||||||
{
|
{
|
||||||
@@ -393,74 +410,17 @@ namespace YooAsset
|
|||||||
|
|
||||||
return Exists(bundle) == false;
|
return Exists(bundle) == false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual string GetBundleFilePath(PackageBundle bundle)
|
public virtual string GetBundleFilePath(PackageBundle bundle)
|
||||||
{
|
{
|
||||||
return GetCacheBundleFileLoadPath(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 缓存相关
|
#region 缓存相关
|
||||||
public List<string> GetAllCachedBundleGUIDs()
|
public List<string> GetAllCachedBundleGUIDs()
|
||||||
{
|
{
|
||||||
return _records.Keys.ToList();
|
return _records.Keys.ToList();
|
||||||
}
|
}
|
||||||
public FileCacheEntry GetRecordFileElement(PackageBundle bundle)
|
public FileCacheEntry GetRecordFileEntry(PackageBundle bundle)
|
||||||
{
|
{
|
||||||
if (_records.TryGetValue(bundle.BundleGUID, out FileCacheEntry element))
|
if (_records.TryGetValue(bundle.BundleGUID, out FileCacheEntry element))
|
||||||
return element;
|
return element;
|
||||||
@@ -504,7 +464,7 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
return _records.ContainsKey(bundleGUID);
|
return _records.ContainsKey(bundleGUID);
|
||||||
}
|
}
|
||||||
public bool RecordBundleFile(string bundleGUID, FileCacheEntry element)
|
public bool RecordBundleFile(string bundleGUID, FileCacheEntry entry)
|
||||||
{
|
{
|
||||||
if (_records.ContainsKey(bundleGUID))
|
if (_records.ContainsKey(bundleGUID))
|
||||||
{
|
{
|
||||||
@@ -512,7 +472,7 @@ namespace YooAsset
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_records.Add(bundleGUID, element);
|
_records.Add(bundleGUID, entry);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -594,6 +554,30 @@ namespace YooAsset
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 内部方法
|
#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)
|
public string GetDefaultCachePackageRoot(string packageName)
|
||||||
{
|
{
|
||||||
string rootDirectory = YooAssetSettingsData.GetYooDefaultCacheRoot();
|
string rootDirectory = YooAssetSettingsData.GetYooDefaultCacheRoot();
|
||||||
@@ -647,51 +631,6 @@ namespace YooAsset
|
|||||||
Directory.Delete(_cacheManifestFilesRoot, true);
|
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
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,14 @@ namespace YooAsset
|
|||||||
DataFileSize = dataFileSize;
|
DataFileSize = dataFileSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修正内容
|
||||||
|
/// </summary>
|
||||||
|
public void Modify(string dataFilePath)
|
||||||
|
{
|
||||||
|
DataFilePath = dataFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 删除记录文件
|
/// 删除记录文件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@@ -12,17 +12,16 @@ namespace YooAsset
|
|||||||
CheckExist,
|
CheckExist,
|
||||||
DownloadFile,
|
DownloadFile,
|
||||||
AbortDownload,
|
AbortDownload,
|
||||||
LoadAssetBundle,
|
LoadCacheAssetBundle,
|
||||||
CheckResult,
|
CheckResult,
|
||||||
|
TryFallback,
|
||||||
Done,
|
Done,
|
||||||
}
|
}
|
||||||
|
|
||||||
protected readonly CacheFileSystem _fileSystem;
|
protected readonly CacheFileSystem _fileSystem;
|
||||||
protected readonly PackageBundle _bundle;
|
protected readonly PackageBundle _bundle;
|
||||||
protected FSDownloadFileOperation _downloadFileOp;
|
protected FSDownloadFileOperation _downloadFileOp;
|
||||||
protected AssetBundleCreateRequest _createRequest;
|
protected LoadAssetBundleOperation _loadAssetBundleOp;
|
||||||
private AssetBundle _assetBundle;
|
|
||||||
private Stream _managedStream;
|
|
||||||
protected ESteps _steps = ESteps.None;
|
protected ESteps _steps = ESteps.None;
|
||||||
|
|
||||||
|
|
||||||
@@ -46,7 +45,7 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
DownloadProgress = 1f;
|
DownloadProgress = 1f;
|
||||||
DownloadedBytes = _bundle.FileSize;
|
DownloadedBytes = _bundle.FileSize;
|
||||||
_steps = ESteps.LoadAssetBundle;
|
_steps = ESteps.LoadCacheAssetBundle;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -96,7 +95,7 @@ namespace YooAsset
|
|||||||
|
|
||||||
if (_downloadFileOp.Status == EOperationStatus.Succeed)
|
if (_downloadFileOp.Status == EOperationStatus.Succeed)
|
||||||
{
|
{
|
||||||
_steps = ESteps.LoadAssetBundle;
|
_steps = ESteps.LoadCacheAssetBundle;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -123,140 +122,92 @@ namespace YooAsset
|
|||||||
Error = "Abort download file.";
|
Error = "Abort download file.";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_steps == ESteps.LoadAssetBundle)
|
if (_steps == ESteps.LoadCacheAssetBundle)
|
||||||
{
|
{
|
||||||
if (_bundle.Encrypted)
|
var options = new LoadAssetBundleOptions();
|
||||||
{
|
options.FileLoadPath = _fileSystem.GetCacheBundleFileLoadPath(_bundle);
|
||||||
if (_fileSystem.BundleDecryptionServices == null)
|
options.Bundle = _bundle;
|
||||||
{
|
_loadAssetBundleOp = _fileSystem.LoadAssetBundleFactory.Invoke(_bundle.Encrypted, options);
|
||||||
_steps = ESteps.Done;
|
_loadAssetBundleOp.StartOperation();
|
||||||
Status = EOperationStatus.Failed;
|
AddChildOperation(_loadAssetBundleOp);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_steps = ESteps.CheckResult;
|
_steps = ESteps.CheckResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_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)
|
||||||
{
|
{
|
||||||
// 强制挂起主线程(注意:该操作会很耗时)
|
_steps = ESteps.Done;
|
||||||
YooLogger.Warning("Suspend the main thread to load unity bundle.");
|
Status = EOperationStatus.Failed;
|
||||||
_assetBundle = _createRequest.assetBundle;
|
Error = "Loaded cache asset bundle is null.";
|
||||||
|
YooLogger.Error(Error);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_createRequest.isDone == false)
|
_steps = ESteps.Done;
|
||||||
return;
|
Result = new AssetBundleResult(_fileSystem, _bundle, _loadAssetBundleOp.Result, _loadAssetBundleOp.ManagedStream);
|
||||||
_assetBundle = _createRequest.assetBundle;
|
Status = EOperationStatus.Succeed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (_assetBundle != null)
|
|
||||||
{
|
{
|
||||||
_steps = ESteps.Done;
|
if (_loadAssetBundleOp is LoadAssetBundleCompleteOperation)
|
||||||
Result = new AssetBundleResult(_fileSystem, _bundle, _assetBundle, _managedStream);
|
{
|
||||||
Status = EOperationStatus.Succeed;
|
_steps = ESteps.Done;
|
||||||
return;
|
Status = EOperationStatus.Failed;
|
||||||
|
Error = _loadAssetBundleOp.Error;
|
||||||
|
YooLogger.Error(Error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 加载失败,尝试后备加载
|
||||||
|
_steps = ESteps.TryFallback;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_steps == ESteps.TryFallback)
|
||||||
|
{
|
||||||
// 注意:当缓存文件的校验等级为Low的时候,并不能保证缓存文件的完整性。
|
// 注意:当缓存文件的校验等级为Low的时候,并不能保证缓存文件的完整性。
|
||||||
// 说明:在AssetBundle文件加载失败的情况下,我们需要重新验证文件的完整性!
|
// 说明:在AssetBundle文件加载失败的情况下,我们需要重新验证文件的完整性!
|
||||||
EFileVerifyResult verifyResult = _fileSystem.VerifyCacheFile(_bundle);
|
EFileVerifyResult verifyResult = _fileSystem.VerifyCacheFile(_bundle);
|
||||||
if (verifyResult == EFileVerifyResult.Succeed)
|
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);
|
AssetBundle assetBundle = _loadAssetBundleOp.LoadFromMemory();
|
||||||
byte[] fileData = FileUtility.ReadAllBytes(filePath);
|
if (assetBundle != null)
|
||||||
if (fileData != null && fileData.Length > 0)
|
|
||||||
{
|
{
|
||||||
_assetBundle = AssetBundle.LoadFromMemory(fileData);
|
_steps = ESteps.Done;
|
||||||
if (_assetBundle == null)
|
Result = new AssetBundleResult(_fileSystem, _bundle, assetBundle, null);
|
||||||
{
|
Status = EOperationStatus.Succeed;
|
||||||
_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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
Status = EOperationStatus.Failed;
|
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);
|
YooLogger.Error(Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// 文件损坏,删除缓存
|
||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
_fileSystem.DeleteCacheBundleFile(_bundle.BundleGUID);
|
|
||||||
Status = EOperationStatus.Failed;
|
Status = EOperationStatus.Failed;
|
||||||
Error = $"Find corrupted asset bundle file and delete : {_bundle.BundleName}";
|
Error = $"Find corrupted asset bundle file and delete : {_bundle.BundleName}";
|
||||||
YooLogger.Error(Error);
|
YooLogger.Error(Error);
|
||||||
|
_fileSystem.DeleteCacheBundleFile(_bundle.BundleGUID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,12 +226,14 @@ namespace YooAsset
|
|||||||
DownloadFile,
|
DownloadFile,
|
||||||
AbortDownload,
|
AbortDownload,
|
||||||
LoadCacheRawBundle,
|
LoadCacheRawBundle,
|
||||||
|
CheckResult,
|
||||||
Done,
|
Done,
|
||||||
}
|
}
|
||||||
|
|
||||||
protected readonly CacheFileSystem _fileSystem;
|
protected readonly CacheFileSystem _fileSystem;
|
||||||
protected readonly PackageBundle _bundle;
|
protected readonly PackageBundle _bundle;
|
||||||
protected FSDownloadFileOperation _downloadFileOp;
|
protected FSDownloadFileOperation _downloadFileOp;
|
||||||
|
protected LoadRawBundleOperation _loadRawBundleOp;
|
||||||
protected ESteps _steps = ESteps.None;
|
protected ESteps _steps = ESteps.None;
|
||||||
|
|
||||||
|
|
||||||
@@ -309,15 +262,16 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var recordFileElement = _fileSystem.GetRecordFileElement(_bundle);
|
var entry = _fileSystem.GetRecordFileEntry(_bundle);
|
||||||
File.Move(recordFileElement.DataFilePath, filePath);
|
File.Move(entry.DataFilePath, filePath);
|
||||||
|
entry.Modify(filePath);
|
||||||
_steps = ESteps.LoadCacheRawBundle;
|
_steps = ESteps.LoadCacheRawBundle;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
Status = EOperationStatus.Failed;
|
Status = EOperationStatus.Failed;
|
||||||
Error = $"Faild rename raw data file : {ex.Message}";
|
Error = $"Faild rename cached data file : {ex.Message}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -394,18 +348,45 @@ namespace YooAsset
|
|||||||
|
|
||||||
if (_steps == ESteps.LoadCacheRawBundle)
|
if (_steps == ESteps.LoadCacheRawBundle)
|
||||||
{
|
{
|
||||||
string filePath = _fileSystem.GetCacheBundleFileLoadPath(_bundle);
|
var options = new LoadRawBundleOptions();
|
||||||
if (File.Exists(filePath))
|
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;
|
if (_loadRawBundleOp.Result == null)
|
||||||
Result = new RawBundleResult(_fileSystem, _bundle);
|
{
|
||||||
Status = EOperationStatus.Succeed;
|
_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
|
else
|
||||||
{
|
{
|
||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
Status = EOperationStatus.Failed;
|
Status = EOperationStatus.Failed;
|
||||||
Error = $"Can not found cache raw bundle file : {filePath}";
|
Error = _loadRawBundleOp.Error;
|
||||||
YooLogger.Error(Error);
|
YooLogger.Error(Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace YooAsset
|
|||||||
string savePath = _fileSystem.GetCachePackageHashFilePath(_packageVersion);
|
string savePath = _fileSystem.GetCachePackageHashFilePath(_packageVersion);
|
||||||
string fileName = YooAssetSettingsData.GetPackageHashFileName(_fileSystem.PackageName, _packageVersion);
|
string fileName = YooAssetSettingsData.GetPackageHashFileName(_fileSystem.PackageName, _packageVersion);
|
||||||
string webURL = GetWebRequestURL(fileName);
|
string webURL = GetWebRequestURL(fileName);
|
||||||
int watchdogTime = _fileSystem.DownloadWatchDogTime;
|
int watchdogTime = _fileSystem.DownloadWatchDogTimeout;
|
||||||
var args = new DownloadFileRequestArgs(webURL, savePath, _timeout, watchdogTime);
|
var args = new DownloadFileRequestArgs(webURL, savePath, _timeout, watchdogTime);
|
||||||
_webFileRequestOp = _fileSystem.DownloadBackend.CreateFileRequest(args);
|
_webFileRequestOp = _fileSystem.DownloadBackend.CreateFileRequest(args);
|
||||||
_webFileRequestOp.SendRequest();
|
_webFileRequestOp.SendRequest();
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace YooAsset
|
|||||||
string savePath = _fileSystem.GetCachePackageManifestFilePath(_packageVersion);
|
string savePath = _fileSystem.GetCachePackageManifestFilePath(_packageVersion);
|
||||||
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_fileSystem.PackageName, _packageVersion);
|
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_fileSystem.PackageName, _packageVersion);
|
||||||
string webURL = GetDownloadRequestURL(fileName);
|
string webURL = GetDownloadRequestURL(fileName);
|
||||||
int watchdogTime = _fileSystem.DownloadWatchDogTime;
|
int watchdogTime = _fileSystem.DownloadWatchDogTimeout;
|
||||||
var args = new DownloadFileRequestArgs(webURL, savePath, _timeout, watchdogTime);
|
var args = new DownloadFileRequestArgs(webURL, savePath, _timeout, watchdogTime);
|
||||||
_webFileRequestOp = _fileSystem.DownloadBackend.CreateFileRequest(args);
|
_webFileRequestOp = _fileSystem.DownloadBackend.CreateFileRequest(args);
|
||||||
_webFileRequestOp.SendRequest();
|
_webFileRequestOp.SendRequest();
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
string fileName = YooAssetSettingsData.GetPackageVersionFileName(_fileSystem.PackageName);
|
string fileName = YooAssetSettingsData.GetPackageVersionFileName(_fileSystem.PackageName);
|
||||||
string url = GetWebRequestURL(fileName);
|
string url = GetWebRequestURL(fileName);
|
||||||
int watchDogTime = _fileSystem.DownloadWatchDogTime;
|
int watchDogTime = _fileSystem.DownloadWatchDogTimeout;
|
||||||
var args = new DownloadDataRequestArgs(url, _timeout, watchDogTime);
|
var args = new DownloadDataRequestArgs(url, _timeout, watchDogTime);
|
||||||
_webTextRequestOp = _fileSystem.DownloadBackend.CreateTextRequest(args);
|
_webTextRequestOp = _fileSystem.DownloadBackend.CreateTextRequest(args);
|
||||||
_webTextRequestOp.SendRequest();
|
_webTextRequestOp.SendRequest();
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ namespace YooAsset
|
|||||||
// 创建下载请求
|
// 创建下载请求
|
||||||
if (_steps == ESteps.CreateRequest)
|
if (_steps == ESteps.CreateRequest)
|
||||||
{
|
{
|
||||||
int watchdogTime = _fileSystem.DownloadWatchDogTime;
|
int watchdogTime = _fileSystem.DownloadWatchDogTimeout;
|
||||||
int timeout = 0; //注意:文件下载不做超时检测
|
int timeout = 0; //注意:文件下载不做超时检测
|
||||||
var args = new DownloadFileRequestArgs(URL, _tempFilePath, timeout, watchdogTime);
|
var args = new DownloadFileRequestArgs(URL, _tempFilePath, timeout, watchdogTime);
|
||||||
_request = _fileSystem.DownloadBackend.CreateFileRequest(args);
|
_request = _fileSystem.DownloadBackend.CreateFileRequest(args);
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int watchdogTime = _fileSystem.DownloadWatchDogTime;
|
int watchdogTime = _fileSystem.DownloadWatchDogTimeout;
|
||||||
int timeout = 0; //注意:文件下载不做超时检测
|
int timeout = 0; //注意:文件下载不做超时检测
|
||||||
bool appendToFile = true;
|
bool appendToFile = true;
|
||||||
bool removeFileOnAbort = false;
|
bool removeFileOnAbort = false;
|
||||||
@@ -185,7 +185,7 @@ namespace YooAsset
|
|||||||
if (File.Exists(_tempFilePath))
|
if (File.Exists(_tempFilePath))
|
||||||
File.Delete(_tempFilePath);
|
File.Delete(_tempFilePath);
|
||||||
|
|
||||||
int watchdogTime = _fileSystem.DownloadWatchDogTime;
|
int watchdogTime = _fileSystem.DownloadWatchDogTimeout;
|
||||||
int timeout = 0; //注意:文件下载不做超时检测
|
int timeout = 0; //注意:文件下载不做超时检测
|
||||||
var args = new DownloadFileRequestArgs(URL, _tempFilePath, timeout, watchdogTime);
|
var args = new DownloadFileRequestArgs(URL, _tempFilePath, timeout, watchdogTime);
|
||||||
return _fileSystem.DownloadBackend.CreateFileRequest(args);
|
return _fileSystem.DownloadBackend.CreateFileRequest(args);
|
||||||
|
|||||||
@@ -208,7 +208,6 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual string GetBundleFilePath(PackageBundle bundle)
|
public virtual string GetBundleFilePath(PackageBundle bundle)
|
||||||
{
|
{
|
||||||
if (bundle.IncludeMainAssets.Count == 0)
|
if (bundle.IncludeMainAssets.Count == 0)
|
||||||
@@ -217,22 +216,6 @@ namespace YooAsset
|
|||||||
var pacakgeAsset = bundle.IncludeMainAssets[0];
|
var pacakgeAsset = bundle.IncludeMainAssets[0];
|
||||||
return pacakgeAsset.AssetPath;
|
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 内部方法
|
#region 内部方法
|
||||||
public void RecordDownloadFile(PackageBundle bundle)
|
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)
|
if (_loadWebAssetBundleOp == null)
|
||||||
{
|
{
|
||||||
string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
|
var options = new LoadWebAssetBundleOptions();
|
||||||
string fallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
|
options.Bundle = _bundle;
|
||||||
DownloadFileOptions options = new DownloadFileOptions(_bundle, int.MaxValue);
|
options.FailedTryAgain = int.MaxValue;
|
||||||
options.SetURL(mainURL, fallbackURL);
|
options.WatchdogTimeout = _fileSystem.DownloadWatchDogTimeout;
|
||||||
|
options.DownloadBackend = _fileSystem.DownloadBackend;
|
||||||
if (_bundle.Encrypted)
|
options.DisableUnityWebCache = _fileSystem.DisableUnityWebCache;
|
||||||
{
|
options.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
|
||||||
_loadWebAssetBundleOp = new LoadWebEncryptAssetBundleOperation(options, _fileSystem.BundleDecryptionServices, _fileSystem.DownloadBackend);
|
options.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
|
||||||
_loadWebAssetBundleOp.StartOperation();
|
_loadWebAssetBundleOp = _fileSystem.LoadAssetBundleFactory.Invoke(_bundle.Encrypted, options);
|
||||||
AddChildOperation(_loadWebAssetBundleOp);
|
_loadWebAssetBundleOp.StartOperation();
|
||||||
}
|
AddChildOperation(_loadWebAssetBundleOp);
|
||||||
else
|
|
||||||
{
|
|
||||||
_loadWebAssetBundleOp = new LoadWebNormalAssetBundleOperation(options, _fileSystem.DisableUnityWebCache, _fileSystem.DownloadBackend);
|
|
||||||
_loadWebAssetBundleOp.StartOperation();
|
|
||||||
AddChildOperation(_loadWebAssetBundleOp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_loadWebAssetBundleOp.UpdateOperation();
|
_loadWebAssetBundleOp.UpdateOperation();
|
||||||
@@ -62,17 +56,16 @@ namespace YooAsset
|
|||||||
|
|
||||||
if (_loadWebAssetBundleOp.Status == EOperationStatus.Succeed)
|
if (_loadWebAssetBundleOp.Status == EOperationStatus.Succeed)
|
||||||
{
|
{
|
||||||
var assetBundle = _loadWebAssetBundleOp.Result;
|
if (_loadWebAssetBundleOp.Result == null)
|
||||||
if (assetBundle == null)
|
|
||||||
{
|
{
|
||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
Status = EOperationStatus.Failed;
|
Status = EOperationStatus.Failed;
|
||||||
Error = $"{nameof(WRFSLoadAssetBundleOperation)} loaded asset bundle is null.";
|
Error = $"Loaded asset bundle object is null.";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
Result = new AssetBundleResult(_fileSystem, _bundle, assetBundle, null);
|
Result = new AssetBundleResult(_fileSystem, _bundle, _loadWebAssetBundleOp.Result, null);
|
||||||
Status = EOperationStatus.Succeed;
|
Status = EOperationStatus.Succeed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@@ -53,15 +53,20 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool DisableUnityWebCache { private set; get; } = false;
|
public bool DisableUnityWebCache { private set; get; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义参数:下载任务的看门狗机制超时时间
|
||||||
|
/// </summary>
|
||||||
|
public int DownloadWatchDogTimeout { private set; get; } = 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 自定义参数:远程服务接口的实例类(支持跨域下载)
|
/// 自定义参数:远程服务接口的实例类(支持跨域下载)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IRemoteServices RemoteServices { private set; get; }
|
public IRemoteServices RemoteServices { private set; get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 自定义参数:解密服务接口的实例类
|
/// 自定义参数:加载 AssetBundle 的工厂委托
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IWebBundleDecryptionServices BundleDecryptionServices { private set; get; }
|
public LoadWebAssetBundleOperationFactory LoadAssetBundleFactory { private set; get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 自定义参数:资源清单服务类
|
/// 自定义参数:资源清单服务类
|
||||||
@@ -127,13 +132,18 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
DisableUnityWebCache = Convert.ToBoolean(value);
|
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)
|
else if (name == FileSystemParametersDefine.REMOTE_SERVICES)
|
||||||
{
|
{
|
||||||
RemoteServices = (IRemoteServices)value;
|
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)
|
else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES)
|
||||||
{
|
{
|
||||||
@@ -151,6 +161,10 @@ namespace YooAsset
|
|||||||
// 创建默认的下载后台接口
|
// 创建默认的下载后台接口
|
||||||
if (DownloadBackend == null)
|
if (DownloadBackend == null)
|
||||||
DownloadBackend = new UnityWebRequestBackend(WebRequestCreator);
|
DownloadBackend = new UnityWebRequestBackend(WebRequestCreator);
|
||||||
|
|
||||||
|
// 创建默认的 AssetBundle 加载工厂
|
||||||
|
if (LoadAssetBundleFactory == null)
|
||||||
|
LoadAssetBundleFactory = DefaultLoadAssetBundleOperationFactory;
|
||||||
}
|
}
|
||||||
public virtual void OnDestroy()
|
public virtual void OnDestroy()
|
||||||
{
|
{
|
||||||
@@ -181,21 +195,24 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual string GetBundleFilePath(PackageBundle bundle)
|
public virtual string GetBundleFilePath(PackageBundle bundle)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
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 内部方法
|
#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
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,21 +36,18 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
string fileLoadPath = _fileSystem.GetWebFileLoadPath(_bundle);
|
string fileLoadPath = _fileSystem.GetWebFileLoadPath(_bundle);
|
||||||
string mainURL = DownloadSystemTools.ToLocalURL(fileLoadPath);
|
string mainURL = DownloadSystemTools.ToLocalURL(fileLoadPath);
|
||||||
DownloadFileOptions options = new DownloadFileOptions(_bundle, int.MaxValue);
|
|
||||||
options.SetURL(mainURL, mainURL);
|
|
||||||
|
|
||||||
if (_bundle.Encrypted)
|
var options = new LoadWebAssetBundleOptions();
|
||||||
{
|
options.Bundle = _bundle;
|
||||||
_loadWebAssetBundleOp = new LoadWebEncryptAssetBundleOperation(options, _fileSystem.BundleDecryptionServices, _fileSystem.DownloadBackend);
|
options.FailedTryAgain = int.MaxValue;
|
||||||
_loadWebAssetBundleOp.StartOperation();
|
options.WatchdogTimeout = _fileSystem.DownloadWatchDogTimeout;
|
||||||
AddChildOperation(_loadWebAssetBundleOp);
|
options.DownloadBackend = _fileSystem.DownloadBackend;
|
||||||
}
|
options.DisableUnityWebCache = _fileSystem.DisableUnityWebCache;
|
||||||
else
|
options.MainURL = mainURL;
|
||||||
{
|
options.FallbackURL = mainURL;
|
||||||
_loadWebAssetBundleOp = new LoadWebNormalAssetBundleOperation(options, _fileSystem.DisableUnityWebCache, _fileSystem.DownloadBackend);
|
_loadWebAssetBundleOp = _fileSystem.LoadAssetBundleFactory.Invoke(_bundle.Encrypted, options);
|
||||||
_loadWebAssetBundleOp.StartOperation();
|
_loadWebAssetBundleOp.StartOperation();
|
||||||
AddChildOperation(_loadWebAssetBundleOp);
|
AddChildOperation(_loadWebAssetBundleOp);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_loadWebAssetBundleOp.UpdateOperation();
|
_loadWebAssetBundleOp.UpdateOperation();
|
||||||
@@ -62,17 +59,16 @@ namespace YooAsset
|
|||||||
|
|
||||||
if (_loadWebAssetBundleOp.Status == EOperationStatus.Succeed)
|
if (_loadWebAssetBundleOp.Status == EOperationStatus.Succeed)
|
||||||
{
|
{
|
||||||
var assetBundle = _loadWebAssetBundleOp.Result;
|
if (_loadWebAssetBundleOp.Result == null)
|
||||||
if (assetBundle == null)
|
|
||||||
{
|
{
|
||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
Status = EOperationStatus.Failed;
|
Status = EOperationStatus.Failed;
|
||||||
Error = $"{nameof(WSFSLoadAssetBundleOperation)} loaded asset bundle is null.";
|
Error = $"Loaded asset bundle object is null.";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_steps = ESteps.Done;
|
_steps = ESteps.Done;
|
||||||
Result = new AssetBundleResult(_fileSystem, _bundle, assetBundle, null);
|
Result = new AssetBundleResult(_fileSystem, _bundle, _loadWebAssetBundleOp.Result, null);
|
||||||
Status = EOperationStatus.Succeed;
|
Status = EOperationStatus.Succeed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@@ -68,9 +68,14 @@ namespace YooAsset
|
|||||||
public bool DisableUnityWebCache { private set; get; } = false;
|
public bool DisableUnityWebCache { private set; get; } = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 自定义参数:解密服务接口的实例类
|
/// 自定义参数:下载任务的看门狗机制超时时间
|
||||||
/// </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>
|
/// <summary>
|
||||||
/// 自定义参数:资源清单服务类
|
/// 自定义参数:资源清单服务类
|
||||||
@@ -136,9 +141,14 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
DisableUnityWebCache = Convert.ToBoolean(value);
|
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)
|
else if (name == FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES)
|
||||||
{
|
{
|
||||||
@@ -161,6 +171,10 @@ namespace YooAsset
|
|||||||
// 创建默认的下载后台接口
|
// 创建默认的下载后台接口
|
||||||
if (DownloadBackend == null)
|
if (DownloadBackend == null)
|
||||||
DownloadBackend = new UnityWebRequestBackend(WebRequestCreator);
|
DownloadBackend = new UnityWebRequestBackend(WebRequestCreator);
|
||||||
|
|
||||||
|
// 创建默认的 AssetBundle 加载工厂
|
||||||
|
if (LoadAssetBundleFactory == null)
|
||||||
|
LoadAssetBundleFactory = DefaultLoadAssetBundleOperationFactory;
|
||||||
}
|
}
|
||||||
public virtual void OnDestroy()
|
public virtual void OnDestroy()
|
||||||
{
|
{
|
||||||
@@ -191,21 +205,24 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual string GetBundleFilePath(PackageBundle bundle)
|
public virtual string GetBundleFilePath(PackageBundle bundle)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
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 内部方法
|
#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)
|
protected string GetDefaultWebPackageRoot(string packageName)
|
||||||
{
|
{
|
||||||
string rootDirectory = YooAssetSettingsData.GetYooDefaultBuildinRoot();
|
string rootDirectory = YooAssetSettingsData.GetYooDefaultBuildinRoot();
|
||||||
|
|||||||
@@ -91,20 +91,9 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
bool NeedImport(PackageBundle bundle);
|
bool NeedImport(PackageBundle bundle);
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取Bundle文件路径
|
/// 获取资源包本地路径
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string GetBundleFilePath(PackageBundle bundle);
|
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>
|
||||||
/// 下载进度
|
/// 下载进度
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float DownloadProgress { protected set; get; } = 0;
|
public float DownloadProgress { protected set; get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 下载大小
|
/// 下载大小
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long DownloadedBytes { protected set; get; } = 0;
|
public long DownloadedBytes { protected set; get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 终止下载文件
|
/// 终止下载文件
|
||||||
|
|||||||
@@ -45,27 +45,6 @@ namespace YooAsset
|
|||||||
Provider.WaitForAsyncComplete();
|
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>
|
||||||
/// 获取原生文件的路径
|
/// 获取原生文件的路径
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -73,7 +52,7 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
if (IsValidWithWarning == false)
|
if (IsValidWithWarning == false)
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
return Provider.BundleResultObject.GetBundleFilePath();
|
return Provider.LoadedBundleResult.GetBundleFilePath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
if (IsValidWithWarning == false)
|
if (IsValidWithWarning == false)
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
return Provider.SceneName;
|
return Provider.LoadedSceneName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
internal override string InternalGetDescription()
|
internal override string InternalGetDescription()
|
||||||
{
|
{
|
||||||
return $"SceneName : {_provider.SceneName}";
|
return $"SceneName : {_provider.LoadedSceneName}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,7 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
if (_loadAllAssetsOp == null)
|
if (_loadAllAssetsOp == null)
|
||||||
{
|
{
|
||||||
_loadAllAssetsOp = BundleResultObject.LoadAllAssetsAsync(MainAssetInfo);
|
_loadAllAssetsOp = LoadedBundleResult.LoadAllAssetsAsync(MainAssetInfo);
|
||||||
_loadAllAssetsOp.StartOperation();
|
_loadAllAssetsOp.StartOperation();
|
||||||
AddChildOperation(_loadAllAssetsOp);
|
AddChildOperation(_loadAllAssetsOp);
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
if (_loadAssetOp == null)
|
if (_loadAssetOp == null)
|
||||||
{
|
{
|
||||||
_loadAssetOp = BundleResultObject.LoadAssetAsync(MainAssetInfo);
|
_loadAssetOp = LoadedBundleResult.LoadAssetAsync(MainAssetInfo);
|
||||||
_loadAssetOp.StartOperation();
|
_loadAssetOp.StartOperation();
|
||||||
AddChildOperation(_loadAssetOp);
|
AddChildOperation(_loadAssetOp);
|
||||||
|
|
||||||
|
|||||||
@@ -48,14 +48,14 @@ namespace YooAsset
|
|||||||
public UnityEngine.SceneManagement.Scene SceneObject { protected set; get; }
|
public UnityEngine.SceneManagement.Scene SceneObject { protected set; get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取的资源包对象
|
/// 加载的资源包结果
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BundleResult BundleResultObject { protected set; get; }
|
public BundleResult LoadedBundleResult { protected set; get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 加载的场景名称
|
/// 加载的场景名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string SceneName { protected set; get; }
|
public string LoadedSceneName { protected set; get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 引用计数
|
/// 引用计数
|
||||||
@@ -165,8 +165,8 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 检测加载结果
|
// 检测加载结果
|
||||||
BundleResultObject = _mainBundleLoader.Result;
|
LoadedBundleResult = _mainBundleLoader.Result;
|
||||||
if (BundleResultObject == null)
|
if (LoadedBundleResult == null)
|
||||||
{
|
{
|
||||||
string error = $"Loaded bundle result is null.";
|
string error = $"Loaded bundle result is null.";
|
||||||
InvokeCompletion(error, EOperationStatus.Failed);
|
InvokeCompletion(error, EOperationStatus.Failed);
|
||||||
|
|||||||
@@ -16,13 +16,13 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
_loadParams = loadParams;
|
_loadParams = loadParams;
|
||||||
_suspendLoad = suspendLoad;
|
_suspendLoad = suspendLoad;
|
||||||
SceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath);
|
LoadedSceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath);
|
||||||
}
|
}
|
||||||
protected override void ProcessBundleResult()
|
protected override void ProcessBundleResult()
|
||||||
{
|
{
|
||||||
if (_loadSceneOp == null)
|
if (_loadSceneOp == null)
|
||||||
{
|
{
|
||||||
_loadSceneOp = BundleResultObject.LoadSceneOperation(MainAssetInfo, _loadParams, _suspendLoad);
|
_loadSceneOp = LoadedBundleResult.LoadSceneOperation(MainAssetInfo, _loadParams, _suspendLoad);
|
||||||
_loadSceneOp.StartOperation();
|
_loadSceneOp.StartOperation();
|
||||||
AddChildOperation(_loadSceneOp);
|
AddChildOperation(_loadSceneOp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
if (_loadSubAssetsOp == null)
|
if (_loadSubAssetsOp == null)
|
||||||
{
|
{
|
||||||
_loadSubAssetsOp = BundleResultObject.LoadSubAssetsAsync(MainAssetInfo);
|
_loadSubAssetsOp = LoadedBundleResult.LoadSubAssetsAsync(MainAssetInfo);
|
||||||
_loadSubAssetsOp.StartOperation();
|
_loadSubAssetsOp.StartOperation();
|
||||||
AddChildOperation(_loadSubAssetsOp);
|
AddChildOperation(_loadSubAssetsOp);
|
||||||
|
|
||||||
|
|||||||
@@ -723,7 +723,7 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 资源加载 [全部资源]
|
#region 资源加载 [全资源]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 同步加载资源包内所有资源对象
|
/// 同步加载资源包内所有资源对象
|
||||||
/// </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 initParams = new OfflinePlayModeOptions();
|
||||||
var fileDecryption = new TestFileStreamDecryption();
|
|
||||||
var manifestServices = new TestRestoreManifest();
|
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.DISABLE_CATALOG_FILE, true);
|
||||||
initParams.BuildinFileSystemParameters.AddParameter(FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES, manifestServices);
|
initParams.BuildinFileSystemParameters.AddParameter(FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES, manifestServices);
|
||||||
var initializeOp = package.InitializePackageAsync(initParams);
|
var initializeOp = package.InitializePackageAsync(initParams);
|
||||||
@@ -100,7 +99,7 @@ public class T2_TestBuldinFileSystem : IPrebuildSetup, IPostBuildCleanup
|
|||||||
|
|
||||||
// 初始化资源包
|
// 初始化资源包
|
||||||
var initParams = new OfflinePlayModeOptions();
|
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.APPEND_FILE_EXTENSION, true);
|
||||||
initParams.BuildinFileSystemParameters.AddParameter(FileSystemParametersDefine.DISABLE_CATALOG_FILE, true);
|
initParams.BuildinFileSystemParameters.AddParameter(FileSystemParametersDefine.DISABLE_CATALOG_FILE, true);
|
||||||
var initializeOp = package.InitializePackageAsync(initParams);
|
var initializeOp = package.InitializePackageAsync(initParams);
|
||||||
|
|||||||
@@ -45,13 +45,12 @@ public class T3_TestCacheFileSystem : IPrebuildSetup, IPostBuildCleanup
|
|||||||
|
|
||||||
// 初始化资源包
|
// 初始化资源包
|
||||||
var initParams = new HostPlayModeOptions();
|
var initParams = new HostPlayModeOptions();
|
||||||
var fileDecryption = new TestFileStreamDecryption();
|
|
||||||
var manifestServices = new TestRestoreManifest();
|
var manifestServices = new TestRestoreManifest();
|
||||||
|
|
||||||
string hostServerIP = "http://127.0.0.1/CDN/Android/Test/";
|
string hostServerIP = "http://127.0.0.1/CDN/Android/Test/";
|
||||||
var remoteServices = new TestRemoteServices(hostServerIP);
|
var remoteServices = new TestRemoteServices(hostServerIP);
|
||||||
initParams.BuildinFileSystemParameters = null;
|
initParams.BuildinFileSystemParameters = null;
|
||||||
initParams.CacheFileSystemParameters = FileSystemParameters.CreateDefaultCacheFileSystemParameters(remoteServices, fileDecryption);
|
initParams.CacheFileSystemParameters = FileSystemParameters.CreateDefaultCacheFileSystemParameters(remoteServices);
|
||||||
initParams.CacheFileSystemParameters.AddParameter(FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES, manifestServices);
|
initParams.CacheFileSystemParameters.AddParameter(FileSystemParametersDefine.MANIFEST_RESTORE_SERVICES, manifestServices);
|
||||||
var initializeOp = package.InitializePackageAsync(initParams);
|
var initializeOp = package.InitializePackageAsync(initParams);
|
||||||
yield return initializeOp;
|
yield return initializeOp;
|
||||||
|
|||||||
@@ -24,13 +24,6 @@ public class TestLoadRawFile
|
|||||||
|
|
||||||
var filePath = rawFileHandle.GetRawFilePath();
|
var filePath = rawFileHandle.GetRawFilePath();
|
||||||
Assert.IsNotNull(filePath);
|
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();
|
var filePath = rawFileHandle.GetRawFilePath();
|
||||||
Assert.IsNotNull(filePath);
|
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