mirror of
https://github.com/tuyoogame/YooAsset.git
synced 2026-05-28 11:38:47 +00:00
feat : add WebNetwork file system
This commit is contained in:
@@ -50,7 +50,8 @@ namespace YooAsset
|
|||||||
watchdogTimeout: _options.WatchdogTimeout,
|
watchdogTimeout: _options.WatchdogTimeout,
|
||||||
disableUnityWebCache: _options.DisableUnityWebCache,
|
disableUnityWebCache: _options.DisableUnityWebCache,
|
||||||
fileHash: _options.Bundle.FileHash,
|
fileHash: _options.Bundle.FileHash,
|
||||||
unityCrc: _options.Bundle.UnityCrc);
|
unityCrc: _options.Bundle.UnityCrc,
|
||||||
|
platformStrategy : null);
|
||||||
_downloadAssetBundleRequest = _options.DownloadBackend.CreateAssetBundleRequest(args);
|
_downloadAssetBundleRequest = _options.DownloadBackend.CreateAssetBundleRequest(args);
|
||||||
_downloadAssetBundleRequest.SendRequest();
|
_downloadAssetBundleRequest.SendRequest();
|
||||||
_steps = ESteps.CheckRequest;
|
_steps = ESteps.CheckRequest;
|
||||||
@@ -125,216 +126,4 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 从网络加载加密的 AssetBundle 操作
|
|
||||||
/// </summary>
|
|
||||||
internal sealed class LoadWebEncryptedAssetBundleOperation : BCLoadBundleOperation
|
|
||||||
{
|
|
||||||
private enum ESteps
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Prepare,
|
|
||||||
DataRequest,
|
|
||||||
CheckRequest,
|
|
||||||
VerifyData,
|
|
||||||
LoadBundle,
|
|
||||||
CheckResult,
|
|
||||||
TryAgain,
|
|
||||||
Done,
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly LoadWebAssetBundleOptions _options;
|
|
||||||
private readonly DownloadRetryController _downloadRetryController;
|
|
||||||
private IDownloadBytesRequest _downloadBytesRequest;
|
|
||||||
private IBundleMemoryDecryptor _decryptor;
|
|
||||||
private AssetBundleCreateRequest _createRequest;
|
|
||||||
private ESteps _steps = ESteps.None;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建网络 AssetBundle 加载操作实例
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="options">从网络加载 AssetBundle 的操作选项</param>
|
|
||||||
public LoadWebEncryptedAssetBundleOperation(LoadWebAssetBundleOptions options)
|
|
||||||
{
|
|
||||||
_options = options;
|
|
||||||
|
|
||||||
// 注意:网络原因失败后,重新尝试直到成功
|
|
||||||
_downloadRetryController = new DownloadRetryController(int.MaxValue, options.DownloadRetryPolicy);
|
|
||||||
}
|
|
||||||
protected override void InternalStart()
|
|
||||||
{
|
|
||||||
_steps = ESteps.Prepare;
|
|
||||||
}
|
|
||||||
protected override void InternalUpdate()
|
|
||||||
{
|
|
||||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (_steps == ESteps.Prepare)
|
|
||||||
{
|
|
||||||
var decryptor = _options.AssetBundleDecryptor;
|
|
||||||
if (decryptor == null)
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
SetError($"{_options.CacheName} asset bundle decryptor is null.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decryptor is IBundleMemoryDecryptor)
|
|
||||||
{
|
|
||||||
_decryptor = decryptor as IBundleMemoryDecryptor;
|
|
||||||
_steps = ESteps.DataRequest;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
SetError($"{_options.CacheName} does not support '{decryptor.GetType().Name}'.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_steps == ESteps.DataRequest)
|
|
||||||
{
|
|
||||||
string url = _options.DownloadUrlPolicy.SelectUrl(_options.CandidateUrls);
|
|
||||||
var args = new DownloadDataRequestArgs(
|
|
||||||
url: url,
|
|
||||||
timeout: 0,
|
|
||||||
watchdogTimeout: _options.WatchdogTimeout);
|
|
||||||
_downloadBytesRequest = _options.DownloadBackend.CreateBytesRequest(args);
|
|
||||||
_downloadBytesRequest.SendRequest();
|
|
||||||
_steps = ESteps.CheckRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_steps == ESteps.CheckRequest)
|
|
||||||
{
|
|
||||||
Progress = _downloadBytesRequest.DownloadProgress;
|
|
||||||
if (_downloadBytesRequest.IsDone == false)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (_downloadBytesRequest.Status == EDownloadRequestStatus.Succeeded)
|
|
||||||
{
|
|
||||||
_options.DownloadUrlPolicy.OnRequestSucceeded(_downloadBytesRequest.Url);
|
|
||||||
_steps = ESteps.VerifyData;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string url = _downloadBytesRequest.Url;
|
|
||||||
long httpCode = _downloadBytesRequest.HttpCode;
|
|
||||||
string httpError = _downloadBytesRequest.HttpError;
|
|
||||||
_options.DownloadUrlPolicy.OnRequestFailed(url, httpCode, httpError);
|
|
||||||
if (IsWaitForCompletion == false && _downloadRetryController.CanRetryRequest(url, httpCode, httpError))
|
|
||||||
{
|
|
||||||
_downloadRetryController.StartRetryDelay();
|
|
||||||
_steps = ESteps.TryAgain;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
SetError(_downloadBytesRequest.Error);
|
|
||||||
YooLogger.LogError(Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_steps == ESteps.VerifyData)
|
|
||||||
{
|
|
||||||
// 注意:网络/代理/服务器异常导致内容不完整但请求仍成功
|
|
||||||
EFileVerifyResult verifyResult;
|
|
||||||
if (_options.DownloadVerifyLevel == EFileVerifyLevel.Low || _options.DownloadVerifyLevel == EFileVerifyLevel.Middle)
|
|
||||||
verifyResult = FileVerifyHelper.VerifyFile(_downloadBytesRequest.Result, _options.Bundle.FileSize, 0);
|
|
||||||
else if (_options.DownloadVerifyLevel == EFileVerifyLevel.High)
|
|
||||||
verifyResult = FileVerifyHelper.VerifyFile(_downloadBytesRequest.Result, _options.Bundle.FileSize, _options.Bundle.FileCrc);
|
|
||||||
else
|
|
||||||
throw new YooInternalException($"Unexpected verify level: {_options.DownloadVerifyLevel}.");
|
|
||||||
|
|
||||||
if (verifyResult == EFileVerifyResult.Succeed)
|
|
||||||
{
|
|
||||||
_steps = ESteps.LoadBundle;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string error = $"Verify failed. Url: '{_downloadBytesRequest.Url}' Level: {_options.DownloadVerifyLevel} Result: {verifyResult}.";
|
|
||||||
YooLogger.LogWarning(error);
|
|
||||||
|
|
||||||
if (IsWaitForCompletion == false && _downloadRetryController.HasRetriesRemaining())
|
|
||||||
{
|
|
||||||
_downloadRetryController.StartRetryDelay();
|
|
||||||
_steps = ESteps.TryAgain;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
SetError(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_steps == ESteps.LoadBundle)
|
|
||||||
{
|
|
||||||
LoadResult result = LoadFromMemory(_decryptor, _downloadBytesRequest.Result);
|
|
||||||
if (result.Succeeded == false)
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
SetError(result.Error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_steps = ESteps.CheckResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_steps == ESteps.CheckResult)
|
|
||||||
{
|
|
||||||
if (_createRequest.isDone == false)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var assetBundle = _createRequest.assetBundle;
|
|
||||||
if (assetBundle == null)
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
SetError("Unity engine load failed.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_steps = ESteps.Done;
|
|
||||||
SetResult();
|
|
||||||
BundleHandle = new AssetBundleHandle(_options.Bundle, assetBundle, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_steps == ESteps.TryAgain)
|
|
||||||
{
|
|
||||||
// 注意:失败后释放网络请求
|
|
||||||
if (_downloadBytesRequest != null)
|
|
||||||
{
|
|
||||||
_downloadBytesRequest.Dispose();
|
|
||||||
_downloadBytesRequest = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_downloadRetryController.TickRetryDelay())
|
|
||||||
{
|
|
||||||
Progress = 0f;
|
|
||||||
_steps = ESteps.DataRequest;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
protected override void InternalDispose()
|
|
||||||
{
|
|
||||||
if (_downloadBytesRequest != null)
|
|
||||||
{
|
|
||||||
_downloadBytesRequest.Dispose();
|
|
||||||
_downloadBytesRequest = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private LoadResult LoadFromMemory(IBundleMemoryDecryptor decryptor, byte[] fileData)
|
|
||||||
{
|
|
||||||
var args = new BundleDecryptArgs(_options.Bundle, fileData, null);
|
|
||||||
var binaryData = decryptor.GetDecryptedData(args);
|
|
||||||
if (binaryData == null)
|
|
||||||
return LoadResult.Failure($"{_options.CacheName} decryptor returned null data.");
|
|
||||||
|
|
||||||
_createRequest = AssetBundle.LoadFromMemoryAsync(binaryData);
|
|
||||||
return LoadResult.Default();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,213 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace YooAsset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// WebGL 平台加载加密 AssetBundle 操作
|
||||||
|
/// </summary>
|
||||||
|
internal sealed class LoadWebEncryptedAssetBundleOperation : BCLoadBundleOperation
|
||||||
|
{
|
||||||
|
private enum ESteps
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Prepare,
|
||||||
|
DataRequest,
|
||||||
|
CheckRequest,
|
||||||
|
VerifyData,
|
||||||
|
LoadBundle,
|
||||||
|
CheckResult,
|
||||||
|
TryAgain,
|
||||||
|
Done,
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly LoadWebEncryptedAssetBundleOptions _options;
|
||||||
|
private readonly DownloadRetryController _downloadRetryController;
|
||||||
|
private IDownloadBytesRequest _downloadBytesRequest;
|
||||||
|
private IBundleMemoryDecryptor _decryptor;
|
||||||
|
private AssetBundleCreateRequest _createRequest;
|
||||||
|
private ESteps _steps = ESteps.None;
|
||||||
|
|
||||||
|
public LoadWebEncryptedAssetBundleOperation(LoadWebEncryptedAssetBundleOptions options)
|
||||||
|
{
|
||||||
|
_options = options;
|
||||||
|
|
||||||
|
// 注意:网络原因失败后,重新尝试直到成功
|
||||||
|
_downloadRetryController = new DownloadRetryController(int.MaxValue, options.DownloadRetryPolicy);
|
||||||
|
}
|
||||||
|
protected override void InternalStart()
|
||||||
|
{
|
||||||
|
_steps = ESteps.Prepare;
|
||||||
|
}
|
||||||
|
protected override void InternalUpdate()
|
||||||
|
{
|
||||||
|
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_steps == ESteps.Prepare)
|
||||||
|
{
|
||||||
|
var decryptor = _options.AssetBundleDecryptor;
|
||||||
|
if (decryptor == null)
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError($"{_options.CacheName} asset bundle decryptor is null.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decryptor is IBundleMemoryDecryptor)
|
||||||
|
{
|
||||||
|
_decryptor = decryptor as IBundleMemoryDecryptor;
|
||||||
|
_steps = ESteps.DataRequest;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError($"{_options.CacheName} does not support '{decryptor.GetType().Name}'.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_steps == ESteps.DataRequest)
|
||||||
|
{
|
||||||
|
string url = _options.DownloadUrlPolicy.SelectUrl(_options.CandidateUrls);
|
||||||
|
var args = new DownloadDataRequestArgs(
|
||||||
|
url: url,
|
||||||
|
timeout: 0,
|
||||||
|
watchdogTimeout: _options.WatchdogTimeout);
|
||||||
|
_downloadBytesRequest = _options.DownloadBackend.CreateBytesRequest(args);
|
||||||
|
_downloadBytesRequest.SendRequest();
|
||||||
|
_steps = ESteps.CheckRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_steps == ESteps.CheckRequest)
|
||||||
|
{
|
||||||
|
Progress = _downloadBytesRequest.DownloadProgress;
|
||||||
|
if (_downloadBytesRequest.IsDone == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_downloadBytesRequest.Status == EDownloadRequestStatus.Succeeded)
|
||||||
|
{
|
||||||
|
_options.DownloadUrlPolicy.OnRequestSucceeded(_downloadBytesRequest.Url);
|
||||||
|
_steps = ESteps.VerifyData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string url = _downloadBytesRequest.Url;
|
||||||
|
long httpCode = _downloadBytesRequest.HttpCode;
|
||||||
|
string httpError = _downloadBytesRequest.HttpError;
|
||||||
|
_options.DownloadUrlPolicy.OnRequestFailed(url, httpCode, httpError);
|
||||||
|
if (IsWaitForCompletion == false && _downloadRetryController.CanRetryRequest(url, httpCode, httpError))
|
||||||
|
{
|
||||||
|
_downloadRetryController.StartRetryDelay();
|
||||||
|
_steps = ESteps.TryAgain;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError(_downloadBytesRequest.Error);
|
||||||
|
YooLogger.LogError(Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_steps == ESteps.VerifyData)
|
||||||
|
{
|
||||||
|
// 注意:网络/代理/服务器异常导致内容不完整但请求仍成功
|
||||||
|
EFileVerifyResult verifyResult;
|
||||||
|
if (_options.DownloadVerifyLevel == EFileVerifyLevel.Low || _options.DownloadVerifyLevel == EFileVerifyLevel.Middle)
|
||||||
|
verifyResult = FileVerifyHelper.VerifyFile(_downloadBytesRequest.Result, _options.Bundle.FileSize, 0);
|
||||||
|
else if (_options.DownloadVerifyLevel == EFileVerifyLevel.High)
|
||||||
|
verifyResult = FileVerifyHelper.VerifyFile(_downloadBytesRequest.Result, _options.Bundle.FileSize, _options.Bundle.FileCrc);
|
||||||
|
else
|
||||||
|
throw new YooInternalException($"Unexpected verify level: {_options.DownloadVerifyLevel}.");
|
||||||
|
|
||||||
|
if (verifyResult == EFileVerifyResult.Succeed)
|
||||||
|
{
|
||||||
|
_steps = ESteps.LoadBundle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string error = $"Verify failed. Url: '{_downloadBytesRequest.Url}' Level: {_options.DownloadVerifyLevel} Result: {verifyResult}.";
|
||||||
|
YooLogger.LogWarning(error);
|
||||||
|
|
||||||
|
if (IsWaitForCompletion == false && _downloadRetryController.HasRetriesRemaining())
|
||||||
|
{
|
||||||
|
_downloadRetryController.StartRetryDelay();
|
||||||
|
_steps = ESteps.TryAgain;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_steps == ESteps.LoadBundle)
|
||||||
|
{
|
||||||
|
LoadResult result = LoadFromMemory(_decryptor, _downloadBytesRequest.Result);
|
||||||
|
if (result.Succeeded == false)
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError(result.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_steps = ESteps.CheckResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_steps == ESteps.CheckResult)
|
||||||
|
{
|
||||||
|
if (_createRequest.isDone == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var assetBundle = _createRequest.assetBundle;
|
||||||
|
if (assetBundle == null)
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError("Unity engine load asset bundle failed.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetResult();
|
||||||
|
BundleHandle = new AssetBundleHandle(_options.Bundle, assetBundle, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_steps == ESteps.TryAgain)
|
||||||
|
{
|
||||||
|
// 注意:失败后释放网络请求
|
||||||
|
if (_downloadBytesRequest != null)
|
||||||
|
{
|
||||||
|
_downloadBytesRequest.Dispose();
|
||||||
|
_downloadBytesRequest = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_downloadRetryController.TickRetryDelay())
|
||||||
|
{
|
||||||
|
Progress = 0f;
|
||||||
|
_steps = ESteps.DataRequest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected override void InternalDispose()
|
||||||
|
{
|
||||||
|
if (_downloadBytesRequest != null)
|
||||||
|
{
|
||||||
|
_downloadBytesRequest.Dispose();
|
||||||
|
_downloadBytesRequest = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private LoadResult LoadFromMemory(IBundleMemoryDecryptor decryptor, byte[] fileData)
|
||||||
|
{
|
||||||
|
var args = new BundleDecryptArgs(_options.Bundle, fileData, null);
|
||||||
|
var binaryData = decryptor.GetDecryptedData(args);
|
||||||
|
if (binaryData == null)
|
||||||
|
return LoadResult.Failure($"{_options.CacheName} decryptor returned null data.");
|
||||||
|
|
||||||
|
_createRequest = AssetBundle.LoadFromMemoryAsync(binaryData);
|
||||||
|
return LoadResult.Default();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 559636cb5e3e48e4bb79e14a70a1ea4f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace YooAsset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// WebGL 平台加载加密 AssetBundle 的操作选项
|
||||||
|
/// </summary>
|
||||||
|
internal readonly struct LoadWebEncryptedAssetBundleOptions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 文件缓存名称
|
||||||
|
/// </summary>
|
||||||
|
public string CacheName { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源包描述
|
||||||
|
/// </summary>
|
||||||
|
public PackageBundle Bundle { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 候选下载地址列表
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<string> CandidateUrls { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// AssetBundle 解密器
|
||||||
|
/// </summary>
|
||||||
|
public IBundleDecryptor AssetBundleDecryptor { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下载后台接口
|
||||||
|
/// </summary>
|
||||||
|
public IDownloadBackend DownloadBackend { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下载数据校验级别
|
||||||
|
/// </summary>
|
||||||
|
public EFileVerifyLevel DownloadVerifyLevel { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 看门狗超时时间
|
||||||
|
/// </summary>
|
||||||
|
public int WatchdogTimeout { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下载重试判定策略
|
||||||
|
/// </summary>
|
||||||
|
public IDownloadRetryPolicy DownloadRetryPolicy { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// URL 选择策略
|
||||||
|
/// </summary>
|
||||||
|
public IDownloadUrlPolicy DownloadUrlPolicy { get; }
|
||||||
|
|
||||||
|
public LoadWebEncryptedAssetBundleOptions(string cacheName, PackageBundle bundle, IReadOnlyList<string> candidateUrls,
|
||||||
|
IBundleDecryptor assetBundleDecryptor, IDownloadBackend downloadBackend, EFileVerifyLevel downloadVerifyLevel,
|
||||||
|
int watchdogTimeout, IDownloadRetryPolicy downloadRetryPolicy, IDownloadUrlPolicy downloadUrlPolicy)
|
||||||
|
{
|
||||||
|
CacheName = cacheName;
|
||||||
|
Bundle = bundle;
|
||||||
|
CandidateUrls = candidateUrls;
|
||||||
|
AssetBundleDecryptor = assetBundleDecryptor;
|
||||||
|
DownloadBackend = downloadBackend;
|
||||||
|
DownloadVerifyLevel = downloadVerifyLevel;
|
||||||
|
WatchdogTimeout = watchdogTimeout;
|
||||||
|
DownloadRetryPolicy = downloadRetryPolicy;
|
||||||
|
DownloadUrlPolicy = downloadUrlPolicy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e98882b2de6b0644fab7549b1a19eb76
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
namespace YooAsset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// WebGL 平台加载非加密 AssetBundle 操作
|
||||||
|
/// </summary>
|
||||||
|
internal sealed class LoadWebPlatformAssetBundleOperation : BCLoadBundleOperation
|
||||||
|
{
|
||||||
|
private enum ESteps
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
BundleRequest,
|
||||||
|
CheckRequest,
|
||||||
|
TryAgain,
|
||||||
|
Done,
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly LoadWebPlatformAssetBundleOptions _options;
|
||||||
|
private readonly DownloadRetryController _downloadRetryController;
|
||||||
|
private IDownloadAssetBundleRequest _downloadAssetBundleRequest;
|
||||||
|
private ESteps _steps = ESteps.None;
|
||||||
|
|
||||||
|
internal LoadWebPlatformAssetBundleOperation(LoadWebPlatformAssetBundleOptions options)
|
||||||
|
{
|
||||||
|
_options = options;
|
||||||
|
|
||||||
|
// 注意:网络原因失败后,重新尝试直到成功
|
||||||
|
_downloadRetryController = new DownloadRetryController(int.MaxValue, options.DownloadRetryPolicy);
|
||||||
|
}
|
||||||
|
protected override void InternalStart()
|
||||||
|
{
|
||||||
|
_steps = ESteps.BundleRequest;
|
||||||
|
}
|
||||||
|
protected override void InternalUpdate()
|
||||||
|
{
|
||||||
|
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_steps == ESteps.BundleRequest)
|
||||||
|
{
|
||||||
|
string url = _options.DownloadUrlPolicy.SelectUrl(_options.CandidateUrls);
|
||||||
|
var args = new DownloadAssetBundleRequestArgs(
|
||||||
|
url: url,
|
||||||
|
timeout: 0,
|
||||||
|
watchdogTimeout: _options.WatchdogTimeout,
|
||||||
|
disableUnityWebCache: _options.DisableUnityWebCache,
|
||||||
|
fileHash: _options.Bundle.FileHash,
|
||||||
|
unityCrc: _options.Bundle.UnityCrc,
|
||||||
|
platformStrategy: _options.PlatformStrategy);
|
||||||
|
_downloadAssetBundleRequest = _options.DownloadBackend.CreateAssetBundleRequest(args);
|
||||||
|
_downloadAssetBundleRequest.SendRequest();
|
||||||
|
_steps = ESteps.CheckRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_steps == ESteps.CheckRequest)
|
||||||
|
{
|
||||||
|
//TODO 部分小游戏平台的 downloadProgress 始终返回 0,导致进度条无法正确显示。
|
||||||
|
Progress = _downloadAssetBundleRequest.DownloadProgress;
|
||||||
|
if (_downloadAssetBundleRequest.IsDone == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_downloadAssetBundleRequest.Status == EDownloadRequestStatus.Succeeded)
|
||||||
|
{
|
||||||
|
_options.DownloadUrlPolicy.OnRequestSucceeded(_downloadAssetBundleRequest.Url);
|
||||||
|
var assetBundle = _downloadAssetBundleRequest.Result;
|
||||||
|
if (assetBundle == null)
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError($"Downloaded asset bundle is null. URL: {_downloadAssetBundleRequest.Url}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetResult();
|
||||||
|
BundleHandle = new WebAssetBundleHandle(_options.Bundle, assetBundle, _options.PlatformStrategy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string url = _downloadAssetBundleRequest.Url;
|
||||||
|
long httpCode = _downloadAssetBundleRequest.HttpCode;
|
||||||
|
string httpError = _downloadAssetBundleRequest.HttpError;
|
||||||
|
_options.DownloadUrlPolicy.OnRequestFailed(url, httpCode, httpError);
|
||||||
|
|
||||||
|
if (IsWaitForCompletion == false && _downloadRetryController.CanRetryRequest(url, httpCode, httpError))
|
||||||
|
{
|
||||||
|
_downloadRetryController.StartRetryDelay();
|
||||||
|
_steps = ESteps.TryAgain;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError(_downloadAssetBundleRequest.Error);
|
||||||
|
YooLogger.LogError(Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_steps == ESteps.TryAgain)
|
||||||
|
{
|
||||||
|
// 注意:失败后释放网络请求
|
||||||
|
if (_downloadAssetBundleRequest != null)
|
||||||
|
{
|
||||||
|
_downloadAssetBundleRequest.Dispose();
|
||||||
|
_downloadAssetBundleRequest = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_downloadRetryController.TickRetryDelay())
|
||||||
|
{
|
||||||
|
Progress = 0f;
|
||||||
|
_steps = ESteps.BundleRequest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected override void InternalDispose()
|
||||||
|
{
|
||||||
|
if (_downloadAssetBundleRequest != null)
|
||||||
|
{
|
||||||
|
_downloadAssetBundleRequest.Dispose();
|
||||||
|
_downloadAssetBundleRequest = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dc432c9fb60357e4f985284caae506f6
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace YooAsset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// WebGL 平台加载非加密 AssetBundle 的操作选项
|
||||||
|
/// </summary>
|
||||||
|
internal readonly struct LoadWebPlatformAssetBundleOptions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 资源包描述
|
||||||
|
/// </summary>
|
||||||
|
public PackageBundle Bundle { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 候选下载地址列表
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<string> CandidateUrls { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 平台策略
|
||||||
|
/// </summary>
|
||||||
|
public IWebPlatformStrategy PlatformStrategy { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下载后台接口
|
||||||
|
/// </summary>
|
||||||
|
public IDownloadBackend DownloadBackend { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 看门狗超时时间
|
||||||
|
/// </summary>
|
||||||
|
public int WatchdogTimeout { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 禁用 Unity 内置网络缓存
|
||||||
|
/// </summary>
|
||||||
|
public bool DisableUnityWebCache { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下载重试判定策略
|
||||||
|
/// </summary>
|
||||||
|
public IDownloadRetryPolicy DownloadRetryPolicy { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// URL 选择策略
|
||||||
|
/// </summary>
|
||||||
|
public IDownloadUrlPolicy DownloadUrlPolicy { get; }
|
||||||
|
|
||||||
|
public LoadWebPlatformAssetBundleOptions(PackageBundle bundle, IReadOnlyList<string> candidateUrls,
|
||||||
|
IWebPlatformStrategy platformStrategy, IDownloadBackend downloadBackend, int watchdogTimeout, bool disableUnityWebCache,
|
||||||
|
IDownloadRetryPolicy downloadRetryPolicy, IDownloadUrlPolicy downloadUrlPolicy)
|
||||||
|
{
|
||||||
|
Bundle = bundle;
|
||||||
|
CandidateUrls = candidateUrls;
|
||||||
|
PlatformStrategy = platformStrategy;
|
||||||
|
DownloadBackend = downloadBackend;
|
||||||
|
WatchdogTimeout = watchdogTimeout;
|
||||||
|
DisableUnityWebCache = disableUnityWebCache;
|
||||||
|
DownloadRetryPolicy = downloadRetryPolicy;
|
||||||
|
DownloadUrlPolicy = downloadUrlPolicy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 28cb5372ae5766e409aab15dfe109e95
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -38,7 +38,7 @@ namespace YooAsset
|
|||||||
var urls = _fileCache.Config.RemoteService.GetRemoteUrls(_options.Bundle.GetFileName());
|
var urls = _fileCache.Config.RemoteService.GetRemoteUrls(_options.Bundle.GetFileName());
|
||||||
if (_options.Bundle.IsEncrypted)
|
if (_options.Bundle.IsEncrypted)
|
||||||
{
|
{
|
||||||
var options = new LoadWebAssetBundleOptions(
|
var encryptedOptions = new LoadWebEncryptedAssetBundleOptions(
|
||||||
cacheName: _fileCache.GetType().Name,
|
cacheName: _fileCache.GetType().Name,
|
||||||
bundle: _options.Bundle,
|
bundle: _options.Bundle,
|
||||||
candidateUrls: urls,
|
candidateUrls: urls,
|
||||||
@@ -46,10 +46,9 @@ namespace YooAsset
|
|||||||
downloadBackend: _fileCache.Config.DownloadBackend,
|
downloadBackend: _fileCache.Config.DownloadBackend,
|
||||||
downloadVerifyLevel: _fileCache.Config.DownloadVerifyLevel,
|
downloadVerifyLevel: _fileCache.Config.DownloadVerifyLevel,
|
||||||
watchdogTimeout: _fileCache.Config.WatchdogTimeout,
|
watchdogTimeout: _fileCache.Config.WatchdogTimeout,
|
||||||
disableUnityWebCache: _fileCache.Config.DisableUnityWebCache,
|
|
||||||
downloadRetryPolicy: _fileCache.Config.DownloadRetryPolicy,
|
downloadRetryPolicy: _fileCache.Config.DownloadRetryPolicy,
|
||||||
downloadUrlPolicy: _fileCache.Config.DownloadUrlPolicy);
|
downloadUrlPolicy: _fileCache.Config.DownloadUrlPolicy);
|
||||||
_loadBundleOp = new LoadWebEncryptedAssetBundleOperation(options);
|
_loadBundleOp = new LoadWebEncryptedAssetBundleOperation(encryptedOptions);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c284033155b7a7f4f9bcd7fa16e8f169
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9494c5da1a02a7b43b40729e88fbda21
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
namespace YooAsset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// WebGL 平台网络缓存初始化操作
|
||||||
|
/// </summary>
|
||||||
|
internal sealed class WNBCInitializeOperation : BCInitializeOperation
|
||||||
|
{
|
||||||
|
protected override void InternalStart()
|
||||||
|
{
|
||||||
|
SetResult();
|
||||||
|
}
|
||||||
|
protected override void InternalUpdate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8a286ded9b4bbc340959221a542c8885
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
|
||||||
|
namespace YooAsset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// WebGL 平台网络缓存加载 AssetBundle 操作
|
||||||
|
/// </summary>
|
||||||
|
internal sealed class WNBCLoadAssetBundleOperation : BCLoadBundleOperation
|
||||||
|
{
|
||||||
|
private enum ESteps
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
LoadBundle,
|
||||||
|
Done,
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly WebNetworkBundleCache _fileCache;
|
||||||
|
private readonly BCLoadBundleOptions _options;
|
||||||
|
private BCLoadBundleOperation _loadBundleOp;
|
||||||
|
private ESteps _steps = ESteps.None;
|
||||||
|
|
||||||
|
internal WNBCLoadAssetBundleOperation(WebNetworkBundleCache fileCache, BCLoadBundleOptions options)
|
||||||
|
{
|
||||||
|
_fileCache = fileCache;
|
||||||
|
_options = options;
|
||||||
|
}
|
||||||
|
protected override void InternalStart()
|
||||||
|
{
|
||||||
|
_steps = ESteps.LoadBundle;
|
||||||
|
}
|
||||||
|
protected override void InternalUpdate()
|
||||||
|
{
|
||||||
|
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_steps == ESteps.LoadBundle)
|
||||||
|
{
|
||||||
|
if (_loadBundleOp == null)
|
||||||
|
{
|
||||||
|
var urls = _fileCache.Config.RemoteService.GetRemoteUrls(_options.Bundle.GetFileName());
|
||||||
|
if (_options.Bundle.IsEncrypted)
|
||||||
|
{
|
||||||
|
var encryptedOptions = new LoadWebEncryptedAssetBundleOptions(
|
||||||
|
cacheName: _fileCache.GetType().Name,
|
||||||
|
bundle: _options.Bundle,
|
||||||
|
candidateUrls: urls,
|
||||||
|
assetBundleDecryptor: _fileCache.Config.AssetBundleDecryptor,
|
||||||
|
downloadBackend: _fileCache.Config.DownloadBackend,
|
||||||
|
downloadVerifyLevel: _fileCache.Config.DownloadVerifyLevel,
|
||||||
|
watchdogTimeout: _fileCache.Config.WatchdogTimeout,
|
||||||
|
downloadRetryPolicy: _fileCache.Config.DownloadRetryPolicy,
|
||||||
|
downloadUrlPolicy: _fileCache.Config.DownloadUrlPolicy);
|
||||||
|
_loadBundleOp = new LoadWebEncryptedAssetBundleOperation(encryptedOptions);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var platformOptions = new LoadWebPlatformAssetBundleOptions(
|
||||||
|
bundle: _options.Bundle,
|
||||||
|
candidateUrls: urls,
|
||||||
|
platformStrategy: _fileCache.Config.PlatformStrategy,
|
||||||
|
downloadBackend: _fileCache.Config.DownloadBackend,
|
||||||
|
watchdogTimeout: _fileCache.Config.WatchdogTimeout,
|
||||||
|
disableUnityWebCache: _fileCache.Config.DisableUnityWebCache,
|
||||||
|
downloadRetryPolicy: _fileCache.Config.DownloadRetryPolicy,
|
||||||
|
downloadUrlPolicy: _fileCache.Config.DownloadUrlPolicy);
|
||||||
|
_loadBundleOp = new LoadWebPlatformAssetBundleOperation(platformOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
_loadBundleOp.StartOperation();
|
||||||
|
AddChildOperation(_loadBundleOp);
|
||||||
|
}
|
||||||
|
|
||||||
|
_loadBundleOp.UpdateOperation();
|
||||||
|
Progress = _loadBundleOp.Progress;
|
||||||
|
if (_loadBundleOp.IsDone == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_loadBundleOp.Status == EOperationStatus.Succeeded)
|
||||||
|
{
|
||||||
|
if (_loadBundleOp.BundleHandle == null)
|
||||||
|
throw new YooInternalException("Loaded bundle handle is null.");
|
||||||
|
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetResult();
|
||||||
|
BundleHandle = _loadBundleOp.BundleHandle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError(_loadBundleOp.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected override void InternalWaitForCompletion()
|
||||||
|
{
|
||||||
|
if (_steps != ESteps.Done)
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError("WebGL platform does not support synchronous loading.");
|
||||||
|
YooLogger.LogError(Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d23033bab8f508240af14aea1d1c9776
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
|
||||||
|
namespace YooAsset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// WebGL 平台网络缓存加载 RawBundle 操作
|
||||||
|
/// </summary>
|
||||||
|
internal sealed class WNBCLoadRawBundleOperation : BCLoadBundleOperation
|
||||||
|
{
|
||||||
|
private enum ESteps
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
LoadBundle,
|
||||||
|
Done,
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly WebNetworkBundleCache _fileCache;
|
||||||
|
private readonly BCLoadBundleOptions _options;
|
||||||
|
private BCLoadBundleOperation _loadBundleOp;
|
||||||
|
private ESteps _steps = ESteps.None;
|
||||||
|
|
||||||
|
internal WNBCLoadRawBundleOperation(WebNetworkBundleCache fileCache, BCLoadBundleOptions options)
|
||||||
|
{
|
||||||
|
_fileCache = fileCache;
|
||||||
|
_options = options;
|
||||||
|
}
|
||||||
|
protected override void InternalStart()
|
||||||
|
{
|
||||||
|
_steps = ESteps.LoadBundle;
|
||||||
|
}
|
||||||
|
protected override void InternalUpdate()
|
||||||
|
{
|
||||||
|
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_steps == ESteps.LoadBundle)
|
||||||
|
{
|
||||||
|
if (_loadBundleOp == null)
|
||||||
|
{
|
||||||
|
var urls = _fileCache.Config.RemoteService.GetRemoteUrls(_options.Bundle.GetFileName());
|
||||||
|
var options = new LoadWebRawBundleOptions(
|
||||||
|
cacheName: _fileCache.GetType().Name,
|
||||||
|
bundle: _options.Bundle,
|
||||||
|
candidateUrls: urls,
|
||||||
|
rawBundleDecryptor: _fileCache.Config.RawBundleDecryptor,
|
||||||
|
downloadBackend: _fileCache.Config.DownloadBackend,
|
||||||
|
downloadVerifyLevel: _fileCache.Config.DownloadVerifyLevel,
|
||||||
|
watchdogTimeout: _fileCache.Config.WatchdogTimeout,
|
||||||
|
downloadRetryPolicy: _fileCache.Config.DownloadRetryPolicy,
|
||||||
|
downloadUrlPolicy: _fileCache.Config.DownloadUrlPolicy);
|
||||||
|
_loadBundleOp = new LoadWebRawBundleOperation(options);
|
||||||
|
_loadBundleOp.StartOperation();
|
||||||
|
AddChildOperation(_loadBundleOp);
|
||||||
|
}
|
||||||
|
|
||||||
|
_loadBundleOp.UpdateOperation();
|
||||||
|
Progress = _loadBundleOp.Progress;
|
||||||
|
if (_loadBundleOp.IsDone == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_loadBundleOp.Status == EOperationStatus.Succeeded)
|
||||||
|
{
|
||||||
|
if (_loadBundleOp.BundleHandle == null)
|
||||||
|
throw new YooInternalException("Loaded bundle handle is null.");
|
||||||
|
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetResult();
|
||||||
|
BundleHandle = _loadBundleOp.BundleHandle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError(_loadBundleOp.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected override void InternalWaitForCompletion()
|
||||||
|
{
|
||||||
|
if (_steps != ESteps.Done)
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError("WebGL platform does not support synchronous loading.");
|
||||||
|
YooLogger.LogError(Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2757bc29c7400b24c8bd4f250e414b65
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
namespace YooAsset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// WebGL 平台网络缓存系统
|
||||||
|
/// </summary>
|
||||||
|
internal class WebNetworkBundleCache : IBundleCache
|
||||||
|
{
|
||||||
|
internal readonly struct Configuration
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 看门狗超时时间
|
||||||
|
/// </summary>
|
||||||
|
public int WatchdogTimeout { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 禁用 Unity 内置网络缓存
|
||||||
|
/// </summary>
|
||||||
|
public bool DisableUnityWebCache { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下载数据校验级别
|
||||||
|
/// </summary>
|
||||||
|
public EFileVerifyLevel DownloadVerifyLevel { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// AssetBundle 解密器
|
||||||
|
/// </summary>
|
||||||
|
public IBundleDecryptor AssetBundleDecryptor { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// RawBundle 解密器
|
||||||
|
/// </summary>
|
||||||
|
public IBundleDecryptor RawBundleDecryptor { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 平台策略接口
|
||||||
|
/// </summary>
|
||||||
|
public IWebPlatformStrategy PlatformStrategy { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 远程服务接口
|
||||||
|
/// </summary>
|
||||||
|
public IRemoteService RemoteService { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下载后台接口
|
||||||
|
/// </summary>
|
||||||
|
public IDownloadBackend DownloadBackend { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下载重试判定策略
|
||||||
|
/// </summary>
|
||||||
|
public IDownloadRetryPolicy DownloadRetryPolicy { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// URL 选择策略
|
||||||
|
/// </summary>
|
||||||
|
public IDownloadUrlPolicy DownloadUrlPolicy { get; }
|
||||||
|
|
||||||
|
public Configuration(int watchdogTimeout, bool disableUnityWebCache,
|
||||||
|
EFileVerifyLevel downloadVerifyLevel, IBundleDecryptor assetBundleDecryptor, IBundleDecryptor rawBundleDecryptor,
|
||||||
|
IWebPlatformStrategy platformStrategy, IRemoteService remoteService, IDownloadBackend downloadBackend,
|
||||||
|
IDownloadRetryPolicy downloadRetryPolicy, IDownloadUrlPolicy downloadUrlPolicy)
|
||||||
|
{
|
||||||
|
WatchdogTimeout = watchdogTimeout;
|
||||||
|
DisableUnityWebCache = disableUnityWebCache;
|
||||||
|
DownloadVerifyLevel = downloadVerifyLevel;
|
||||||
|
AssetBundleDecryptor = assetBundleDecryptor;
|
||||||
|
RawBundleDecryptor = rawBundleDecryptor;
|
||||||
|
PlatformStrategy = platformStrategy;
|
||||||
|
RemoteService = remoteService;
|
||||||
|
DownloadBackend = downloadBackend;
|
||||||
|
DownloadRetryPolicy = downloadRetryPolicy;
|
||||||
|
DownloadUrlPolicy = downloadUrlPolicy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 缓存配置
|
||||||
|
/// </summary>
|
||||||
|
internal readonly Configuration Config;
|
||||||
|
|
||||||
|
#region 接口属性
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public string PackageName { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public string RootPath { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool IsReadOnly { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public int FileCount { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public long SpaceOccupied { get; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public WebNetworkBundleCache(string packageName, Configuration config)
|
||||||
|
{
|
||||||
|
PackageName = packageName;
|
||||||
|
Config = config;
|
||||||
|
IsReadOnly = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public BCInitializeOperation InitializeAsync()
|
||||||
|
{
|
||||||
|
var operation = new WNBCInitializeOperation();
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public BCWriteCacheOperation WriteCacheAsync(BCWriteCacheOptions options)
|
||||||
|
{
|
||||||
|
var operation = new BCWriteCacheCompleteOperation($"{nameof(WebNetworkBundleCache)} is readonly.");
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public BCClearCacheOperation ClearCacheAsync(BCClearCacheOptions options)
|
||||||
|
{
|
||||||
|
var operation = new BCClearCacheCompleteOperation();
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public BCVerifyCacheOperation VerifyCacheAsync(BCVerifyCacheOptions options)
|
||||||
|
{
|
||||||
|
var operation = new BCVerifyCacheCompleteOperation();
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public BCLoadBundleOperation LoadBundleAsync(BCLoadBundleOptions options)
|
||||||
|
{
|
||||||
|
if (options.Bundle.GetBundleType() == (int)EBundleType.AssetBundle)
|
||||||
|
{
|
||||||
|
var operation = new WNBCLoadAssetBundleOperation(this, options);
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
else if (options.Bundle.GetBundleType() == (int)EBundleType.RawBundle)
|
||||||
|
{
|
||||||
|
var operation = new WNBCLoadRawBundleOperation(this, options);
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string error = $"{nameof(WebNetworkBundleCache)} does not support bundle type: {options.Bundle.GetBundleType()}.";
|
||||||
|
var operation = new BCLoadBundleErrorOperation(error);
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool IsCached(string bundleGuid)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string GetCacheFilePath(string bundleGuid)
|
||||||
|
{
|
||||||
|
YooLogger.LogWarning($"{nameof(WebNetworkBundleCache)} does not support local cache file path.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ea8b93fb2515f5b49b16486f87be98d7
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -42,6 +42,22 @@ namespace YooAsset
|
|||||||
if (_loadBundleOp == null)
|
if (_loadBundleOp == null)
|
||||||
{
|
{
|
||||||
var urls = _fileCache.Config.RemoteService.GetRemoteUrls(_options.Bundle.GetFileName());
|
var urls = _fileCache.Config.RemoteService.GetRemoteUrls(_options.Bundle.GetFileName());
|
||||||
|
if (_options.Bundle.IsEncrypted)
|
||||||
|
{
|
||||||
|
var encryptedOptions = new LoadWebEncryptedAssetBundleOptions(
|
||||||
|
cacheName: _fileCache.GetType().Name,
|
||||||
|
bundle: _options.Bundle,
|
||||||
|
candidateUrls: urls,
|
||||||
|
assetBundleDecryptor: _fileCache.Config.AssetBundleDecryptor,
|
||||||
|
downloadBackend: _fileCache.Config.DownloadBackend,
|
||||||
|
downloadVerifyLevel: _fileCache.Config.DownloadVerifyLevel,
|
||||||
|
watchdogTimeout: _fileCache.Config.WatchdogTimeout,
|
||||||
|
downloadRetryPolicy: _fileCache.Config.DownloadRetryPolicy,
|
||||||
|
downloadUrlPolicy: _fileCache.Config.DownloadUrlPolicy);
|
||||||
|
_loadBundleOp = new LoadWebEncryptedAssetBundleOperation(encryptedOptions);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
var options = new LoadWebAssetBundleOptions(
|
var options = new LoadWebAssetBundleOptions(
|
||||||
cacheName: _fileCache.GetType().Name,
|
cacheName: _fileCache.GetType().Name,
|
||||||
bundle: _options.Bundle,
|
bundle: _options.Bundle,
|
||||||
@@ -53,11 +69,8 @@ namespace YooAsset
|
|||||||
disableUnityWebCache: _fileCache.Config.DisableUnityWebCache,
|
disableUnityWebCache: _fileCache.Config.DisableUnityWebCache,
|
||||||
downloadRetryPolicy: _fileCache.Config.DownloadRetryPolicy,
|
downloadRetryPolicy: _fileCache.Config.DownloadRetryPolicy,
|
||||||
downloadUrlPolicy: _fileCache.Config.DownloadUrlPolicy);
|
downloadUrlPolicy: _fileCache.Config.DownloadUrlPolicy);
|
||||||
|
|
||||||
if (_options.Bundle.IsEncrypted)
|
|
||||||
_loadBundleOp = new LoadWebEncryptedAssetBundleOperation(options);
|
|
||||||
else
|
|
||||||
_loadBundleOp = new LoadWebNormalAssetBundleOperation(options);
|
_loadBundleOp = new LoadWebNormalAssetBundleOperation(options);
|
||||||
|
}
|
||||||
|
|
||||||
_loadBundleOp.StartOperation();
|
_loadBundleOp.StartOperation();
|
||||||
AddChildOperation(_loadBundleOp);
|
AddChildOperation(_loadBundleOp);
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ namespace YooAsset
|
|||||||
if (_loadBundleOp == null)
|
if (_loadBundleOp == null)
|
||||||
{
|
{
|
||||||
string url = DownloadUrlHelper.ToLocalFileUrl(_cacheEntry.FilePath);
|
string url = DownloadUrlHelper.ToLocalFileUrl(_cacheEntry.FilePath);
|
||||||
var options = new LoadWebAssetBundleOptions(
|
if (_options.Bundle.IsEncrypted)
|
||||||
|
{
|
||||||
|
var encryptedOptions = new LoadWebEncryptedAssetBundleOptions(
|
||||||
cacheName: _fileCache.GetType().Name,
|
cacheName: _fileCache.GetType().Name,
|
||||||
bundle: _options.Bundle,
|
bundle: _options.Bundle,
|
||||||
candidateUrls: new[] { url },
|
candidateUrls: new[] { url },
|
||||||
@@ -66,14 +68,23 @@ namespace YooAsset
|
|||||||
downloadBackend: _fileCache.Config.DownloadBackend,
|
downloadBackend: _fileCache.Config.DownloadBackend,
|
||||||
downloadVerifyLevel: _fileCache.Config.DownloadVerifyLevel,
|
downloadVerifyLevel: _fileCache.Config.DownloadVerifyLevel,
|
||||||
watchdogTimeout: _fileCache.Config.WatchdogTimeout,
|
watchdogTimeout: _fileCache.Config.WatchdogTimeout,
|
||||||
|
downloadRetryPolicy: _fileCache.Config.DownloadRetryPolicy,
|
||||||
|
downloadUrlPolicy: _fileCache.Config.DownloadUrlPolicy);
|
||||||
|
_loadBundleOp = new LoadWebEncryptedAssetBundleOperation(encryptedOptions);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var platformOptions = new LoadWebPlatformAssetBundleOptions(
|
||||||
|
bundle: _options.Bundle,
|
||||||
|
candidateUrls: new[] { url },
|
||||||
|
platformStrategy: _fileCache.Config.PlatformStrategy,
|
||||||
|
downloadBackend: _fileCache.Config.DownloadBackend,
|
||||||
|
watchdogTimeout: _fileCache.Config.WatchdogTimeout,
|
||||||
disableUnityWebCache: _fileCache.Config.DisableUnityWebCache,
|
disableUnityWebCache: _fileCache.Config.DisableUnityWebCache,
|
||||||
downloadRetryPolicy: _fileCache.Config.DownloadRetryPolicy,
|
downloadRetryPolicy: _fileCache.Config.DownloadRetryPolicy,
|
||||||
downloadUrlPolicy: _fileCache.Config.DownloadUrlPolicy);
|
downloadUrlPolicy: _fileCache.Config.DownloadUrlPolicy);
|
||||||
|
_loadBundleOp = new LoadWebPlatformAssetBundleOperation(platformOptions);
|
||||||
if (_options.Bundle.IsEncrypted)
|
}
|
||||||
_loadBundleOp = new LoadWebEncryptedAssetBundleOperation(options);
|
|
||||||
else
|
|
||||||
_loadBundleOp = new LoadWebNormalAssetBundleOperation(options);
|
|
||||||
|
|
||||||
_loadBundleOp.StartOperation();
|
_loadBundleOp.StartOperation();
|
||||||
AddChildOperation(_loadBundleOp);
|
AddChildOperation(_loadBundleOp);
|
||||||
|
|||||||
@@ -35,6 +35,11 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IBundleDecryptor RawBundleDecryptor { get; }
|
public IBundleDecryptor RawBundleDecryptor { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Web 平台策略
|
||||||
|
/// </summary>
|
||||||
|
public IWebPlatformStrategy PlatformStrategy { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 下载后台
|
/// 下载后台
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -52,13 +57,15 @@ namespace YooAsset
|
|||||||
|
|
||||||
public Configuration(int watchdogTimeout, bool disableUnityWebCache,
|
public Configuration(int watchdogTimeout, bool disableUnityWebCache,
|
||||||
EFileVerifyLevel downloadVerifyLevel, IBundleDecryptor assetBundleDecryptor, IBundleDecryptor rawBundleDecryptor,
|
EFileVerifyLevel downloadVerifyLevel, IBundleDecryptor assetBundleDecryptor, IBundleDecryptor rawBundleDecryptor,
|
||||||
IDownloadBackend downloadBackend, IDownloadRetryPolicy downloadRetryPolicy, IDownloadUrlPolicy downloadUrlPolicy)
|
IWebPlatformStrategy platformStrategy, IDownloadBackend downloadBackend,
|
||||||
|
IDownloadRetryPolicy downloadRetryPolicy, IDownloadUrlPolicy downloadUrlPolicy)
|
||||||
{
|
{
|
||||||
WatchdogTimeout = watchdogTimeout;
|
WatchdogTimeout = watchdogTimeout;
|
||||||
DisableUnityWebCache = disableUnityWebCache;
|
DisableUnityWebCache = disableUnityWebCache;
|
||||||
DownloadVerifyLevel = downloadVerifyLevel;
|
DownloadVerifyLevel = downloadVerifyLevel;
|
||||||
AssetBundleDecryptor = assetBundleDecryptor;
|
AssetBundleDecryptor = assetBundleDecryptor;
|
||||||
RawBundleDecryptor = rawBundleDecryptor;
|
RawBundleDecryptor = rawBundleDecryptor;
|
||||||
|
PlatformStrategy = platformStrategy;
|
||||||
DownloadBackend = downloadBackend;
|
DownloadBackend = downloadBackend;
|
||||||
DownloadRetryPolicy = downloadRetryPolicy;
|
DownloadRetryPolicy = downloadRetryPolicy;
|
||||||
DownloadUrlPolicy = downloadUrlPolicy;
|
DownloadUrlPolicy = downloadUrlPolicy;
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 29b3c05632aeb95478e36ada3bc2a07e
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.SceneManagement;
|
||||||
|
|
||||||
|
namespace YooAsset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// WebGL 平台 AssetBundle 资源包句柄
|
||||||
|
/// </summary>
|
||||||
|
internal sealed class WebAssetBundleHandle : IBundleHandle
|
||||||
|
{
|
||||||
|
private readonly PackageBundle _packageBundle;
|
||||||
|
private readonly AssetBundle _assetBundle;
|
||||||
|
private readonly IWebPlatformStrategy _platformStrategy;
|
||||||
|
|
||||||
|
public WebAssetBundleHandle(PackageBundle packageBundle, AssetBundle assetBundle, IWebPlatformStrategy platformStrategy)
|
||||||
|
{
|
||||||
|
_packageBundle = packageBundle;
|
||||||
|
_assetBundle = assetBundle;
|
||||||
|
_platformStrategy = platformStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void UnloadBundle()
|
||||||
|
{
|
||||||
|
if (_assetBundle != null)
|
||||||
|
{
|
||||||
|
if (_packageBundle.IsEncrypted)
|
||||||
|
_assetBundle.Unload(true);
|
||||||
|
else
|
||||||
|
_platformStrategy.UnloadAssetBundle(_assetBundle, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public BHLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo)
|
||||||
|
{
|
||||||
|
var operation = new ABHLoadAssetOperation(_packageBundle, _assetBundle, assetInfo);
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public BHLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo)
|
||||||
|
{
|
||||||
|
var operation = new ABHLoadAllAssetsOperation(_packageBundle, _assetBundle, assetInfo);
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public BHLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo)
|
||||||
|
{
|
||||||
|
var operation = new ABHLoadSubAssetsOperation(_packageBundle, _assetBundle, assetInfo);
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public BHLoadSceneOperation LoadSceneAsync(AssetInfo assetInfo, LoadSceneParameters loadSceneParams, bool allowSceneActivation)
|
||||||
|
{
|
||||||
|
var operation = new ABHLoadSceneOperation(assetInfo, loadSceneParams, allowSceneActivation);
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dc2af916aca72044b82ff66552707214
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -107,9 +107,9 @@ namespace YooAsset
|
|||||||
int timeout,
|
int timeout,
|
||||||
int watchdogTimeout,
|
int watchdogTimeout,
|
||||||
string savePath,
|
string savePath,
|
||||||
bool appendToFile = false,
|
bool appendToFile,
|
||||||
bool removeFileOnAbort = true,
|
bool removeFileOnAbort,
|
||||||
long resumeOffset = 0,
|
long resumeOffset,
|
||||||
IReadOnlyDictionary<string, string> headers = null)
|
IReadOnlyDictionary<string, string> headers = null)
|
||||||
{
|
{
|
||||||
RequestArgs = new DownloadRequestArgs(
|
RequestArgs = new DownloadRequestArgs(
|
||||||
@@ -122,6 +122,32 @@ namespace YooAsset
|
|||||||
RemoveFileOnAbort = removeFileOnAbort;
|
RemoveFileOnAbort = removeFileOnAbort;
|
||||||
ResumeOffset = resumeOffset;
|
ResumeOffset = resumeOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造文件下载请求参数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="url">请求地址</param>
|
||||||
|
/// <param name="timeout">响应超时时间(秒),0 表示不应用超时。</param>
|
||||||
|
/// <param name="watchdogTimeout">看门狗超时时间(秒),0 表示禁用。</param>
|
||||||
|
/// <param name="savePath">文件保存路径</param>
|
||||||
|
/// <param name="headers">自定义请求头(可选)</param>
|
||||||
|
public DownloadFileRequestArgs(
|
||||||
|
string url,
|
||||||
|
int timeout,
|
||||||
|
int watchdogTimeout,
|
||||||
|
string savePath,
|
||||||
|
IReadOnlyDictionary<string, string> headers = null)
|
||||||
|
{
|
||||||
|
RequestArgs = new DownloadRequestArgs(
|
||||||
|
url: url,
|
||||||
|
timeout: timeout,
|
||||||
|
watchdogTimeout: watchdogTimeout,
|
||||||
|
headers: headers);
|
||||||
|
SavePath = savePath;
|
||||||
|
AppendToFile = false;
|
||||||
|
RemoveFileOnAbort = true;
|
||||||
|
ResumeOffset = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -185,6 +211,11 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public uint UnityCrc { get; }
|
public uint UnityCrc { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Web 平台策略
|
||||||
|
/// </summary>
|
||||||
|
public IWebPlatformStrategy PlatformStrategy { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 构造 AssetBundle 下载请求参数
|
/// 构造 AssetBundle 下载请求参数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -194,14 +225,16 @@ namespace YooAsset
|
|||||||
/// <param name="disableUnityWebCache">是否禁用 Unity 内置缓存</param>
|
/// <param name="disableUnityWebCache">是否禁用 Unity 内置缓存</param>
|
||||||
/// <param name="fileHash">文件哈希(启用缓存时必须提供)</param>
|
/// <param name="fileHash">文件哈希(启用缓存时必须提供)</param>
|
||||||
/// <param name="unityCrc">Unity CRC 校验值</param>
|
/// <param name="unityCrc">Unity CRC 校验值</param>
|
||||||
|
/// <param name="platformStrategy">WebGL 平台策略</param>
|
||||||
/// <param name="headers">自定义请求头(可选)</param>
|
/// <param name="headers">自定义请求头(可选)</param>
|
||||||
public DownloadAssetBundleRequestArgs(
|
public DownloadAssetBundleRequestArgs(
|
||||||
string url,
|
string url,
|
||||||
int timeout,
|
int timeout,
|
||||||
int watchdogTimeout,
|
int watchdogTimeout,
|
||||||
bool disableUnityWebCache = true,
|
bool disableUnityWebCache,
|
||||||
string fileHash = null,
|
string fileHash,
|
||||||
uint unityCrc = 0,
|
uint unityCrc,
|
||||||
|
IWebPlatformStrategy platformStrategy,
|
||||||
IReadOnlyDictionary<string, string> headers = null)
|
IReadOnlyDictionary<string, string> headers = null)
|
||||||
{
|
{
|
||||||
RequestArgs = new DownloadRequestArgs(
|
RequestArgs = new DownloadRequestArgs(
|
||||||
@@ -212,6 +245,7 @@ namespace YooAsset
|
|||||||
DisableUnityWebCache = disableUnityWebCache;
|
DisableUnityWebCache = disableUnityWebCache;
|
||||||
FileHash = fileHash;
|
FileHash = fileHash;
|
||||||
UnityCrc = unityCrc;
|
UnityCrc = unityCrc;
|
||||||
|
PlatformStrategy = platformStrategy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,12 +277,12 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="url">请求地址(仅用于标识)</param>
|
/// <param name="url">请求地址(仅用于标识)</param>
|
||||||
/// <param name="fileSize">模拟的文件大小(字节)</param>
|
/// <param name="fileSize">模拟的文件大小(字节)</param>
|
||||||
/// <param name="downloadSpeed">模拟的下载速度(字节/秒),默认 1MB/s</param>
|
/// <param name="downloadSpeed">模拟的下载速度(字节/秒)</param>
|
||||||
public SimulatedDownloadRequestArgs(string url, long fileSize, long downloadSpeed = 1024 * 1024)
|
public SimulatedDownloadRequestArgs(string url, long fileSize, long downloadSpeed)
|
||||||
{
|
{
|
||||||
Url = url;
|
Url = url;
|
||||||
FileSize = Math.Max(fileSize, 0);
|
FileSize = Math.Max(fileSize, 0);
|
||||||
DownloadSpeed = downloadSpeed > 0 ? downloadSpeed : 1024 * 1024;
|
DownloadSpeed = downloadSpeed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Networking;
|
using UnityEngine.Networking;
|
||||||
|
|
||||||
@@ -7,21 +6,10 @@ namespace YooAsset
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// UnityWebRequest AssetBundle 下载器
|
/// UnityWebRequest AssetBundle 下载器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// <para>下载并加载 Unity AssetBundle 资源包</para>
|
|
||||||
/// <para>支持 Unity 内置缓存机制和 CRC 校验</para>
|
|
||||||
/// </remarks>
|
|
||||||
internal sealed class UnityWebRequestAssetBundle : UnityWebRequestBase, IDownloadAssetBundleRequest
|
internal sealed class UnityWebRequestAssetBundle : UnityWebRequestBase, IDownloadAssetBundleRequest
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// AssetBundle 下载参数
|
|
||||||
/// </summary>
|
|
||||||
private readonly DownloadAssetBundleRequestArgs _args;
|
private readonly DownloadAssetBundleRequestArgs _args;
|
||||||
|
private readonly IWebPlatformStrategy _platformStrategy;
|
||||||
/// <summary>
|
|
||||||
/// AssetBundle 下载处理器
|
|
||||||
/// </summary>
|
|
||||||
private DownloadHandlerAssetBundle _downloadHandler;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 下载结果(AssetBundle 对象)
|
/// 下载结果(AssetBundle 对象)
|
||||||
@@ -37,43 +25,22 @@ namespace YooAsset
|
|||||||
: base(args.RequestArgs, webRequestCreator)
|
: base(args.RequestArgs, webRequestCreator)
|
||||||
{
|
{
|
||||||
_args = args;
|
_args = args;
|
||||||
|
_platformStrategy = args.PlatformStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override UnityWebRequest CreateWebRequest()
|
protected override UnityWebRequest CreateWebRequest()
|
||||||
{
|
{
|
||||||
_downloadHandler = CreateAssetBundleDownloadHandler();
|
var args = new WebAssetBundleRequestArgs(
|
||||||
var request = CreateGetWebRequest(Url);
|
url: _args.RequestArgs.Url,
|
||||||
request.downloadHandler = _downloadHandler;
|
disableUnityWebCache: _args.DisableUnityWebCache,
|
||||||
request.disposeDownloadHandlerOnDispose = true;
|
fileHash: _args.FileHash,
|
||||||
return request;
|
unityCrc: _args.UnityCrc);
|
||||||
|
return _platformStrategy.CreateAssetBundleRequest(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnRequestSucceeded(UnityWebRequest webRequest)
|
protected override void OnRequestSucceeded(UnityWebRequest webRequest)
|
||||||
{
|
{
|
||||||
Result = _downloadHandler.assetBundle;
|
Result = _platformStrategy.ExtractAssetBundle(webRequest);
|
||||||
}
|
|
||||||
|
|
||||||
private DownloadHandlerAssetBundle CreateAssetBundleDownloadHandler()
|
|
||||||
{
|
|
||||||
DownloadHandlerAssetBundle handler;
|
|
||||||
|
|
||||||
if (_args.DisableUnityWebCache)
|
|
||||||
{
|
|
||||||
// 禁用 Unity 缓存
|
|
||||||
handler = new DownloadHandlerAssetBundle(Url, _args.UnityCrc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(_args.FileHash))
|
|
||||||
throw new YooInternalException("FileHash is required when Unity web cache is enabled (DisableUnityWebCache = false).");
|
|
||||||
|
|
||||||
// 使用 Unity 缓存
|
|
||||||
// 说明:The file hash defining the version of the asset bundle.
|
|
||||||
Hash128 fileHash = Hash128.Parse(_args.FileHash);
|
|
||||||
handler = new DownloadHandlerAssetBundle(Url, fileHash, _args.UnityCrc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,5 +135,10 @@ namespace YooAsset
|
|||||||
/// URL 选择策略 <see cref="IDownloadUrlPolicy"/>
|
/// URL 选择策略 <see cref="IDownloadUrlPolicy"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
DownloadUrlPolicy,
|
DownloadUrlPolicy,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// WebGL 平台策略 <see cref="IWebPlatformStrategy"/>
|
||||||
|
/// </summary>
|
||||||
|
WebPlatformStrategy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,20 +102,31 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="packageRoot">文件系统的根目录</param>
|
/// <param name="packageRoot">文件系统的根目录</param>
|
||||||
/// <returns>配置好的文件系统参数实例</returns>
|
/// <returns>配置好的文件系统参数实例</returns>
|
||||||
public static FileSystemParameters CreateDefaultBuiltinFileSystemParameters(string packageRoot = null)
|
public static FileSystemParameters CreateDefaultBuiltinFileSystemParameters(string packageRoot)
|
||||||
{
|
{
|
||||||
string fileSystemClass = typeof(BuiltinFileSystem).FullName;
|
string fileSystemClass = typeof(BuiltinFileSystem).FullName;
|
||||||
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
|
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
|
||||||
return fileSystemParams;
|
return fileSystemParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建默认的内置文件系统参数
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>配置好的文件系统参数实例</returns>
|
||||||
|
public static FileSystemParameters CreateDefaultBuiltinFileSystemParameters()
|
||||||
|
{
|
||||||
|
string fileSystemClass = typeof(BuiltinFileSystem).FullName;
|
||||||
|
var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
|
||||||
|
return fileSystemParams;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建默认的沙盒文件系统参数
|
/// 创建默认的沙盒文件系统参数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="remoteService">远端资源地址查询服务类</param>
|
/// <param name="remoteService">远端资源地址查询服务类</param>
|
||||||
/// <param name="packageRoot">文件系统的根目录</param>
|
/// <param name="packageRoot">文件系统的根目录</param>
|
||||||
/// <returns>配置好的文件系统参数实例</returns>
|
/// <returns>配置好的文件系统参数实例</returns>
|
||||||
public static FileSystemParameters CreateDefaultSandboxFileSystemParameters(IRemoteService remoteService, string packageRoot = null)
|
public static FileSystemParameters CreateDefaultSandboxFileSystemParameters(IRemoteService remoteService, string packageRoot)
|
||||||
{
|
{
|
||||||
string fileSystemClass = typeof(SandboxFileSystem).FullName;
|
string fileSystemClass = typeof(SandboxFileSystem).FullName;
|
||||||
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
|
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
|
||||||
@@ -124,11 +135,24 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建默认的WebServer文件系统参数
|
/// 创建默认的沙盒文件系统参数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="remoteService">远端资源地址查询服务类</param>
|
||||||
|
/// <returns>配置好的文件系统参数实例</returns>
|
||||||
|
public static FileSystemParameters CreateDefaultSandboxFileSystemParameters(IRemoteService remoteService)
|
||||||
|
{
|
||||||
|
string fileSystemClass = typeof(SandboxFileSystem).FullName;
|
||||||
|
var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
|
||||||
|
fileSystemParams.AddParameter(EFileSystemParameter.RemoteService, remoteService);
|
||||||
|
return fileSystemParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建默认的WebGL 服务器文件系统参数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="disableUnityWebCache">禁用Unity的网络缓存</param>
|
/// <param name="disableUnityWebCache">禁用Unity的网络缓存</param>
|
||||||
/// <returns>配置好的文件系统参数实例</returns>
|
/// <returns>配置好的文件系统参数实例</returns>
|
||||||
public static FileSystemParameters CreateDefaultWebServerFileSystemParameters(bool disableUnityWebCache = false)
|
public static FileSystemParameters CreateDefaultWebServerFileSystemParameters(bool disableUnityWebCache)
|
||||||
{
|
{
|
||||||
string fileSystemClass = typeof(WebServerFileSystem).FullName;
|
string fileSystemClass = typeof(WebServerFileSystem).FullName;
|
||||||
var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
|
var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
|
||||||
@@ -137,19 +161,45 @@ namespace YooAsset
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建默认的WebRemote文件系统参数
|
/// 创建默认的WebGL 服务器文件系统参数
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>配置好的文件系统参数实例</returns>
|
||||||
|
public static FileSystemParameters CreateDefaultWebServerFileSystemParameters()
|
||||||
|
{
|
||||||
|
string fileSystemClass = typeof(WebServerFileSystem).FullName;
|
||||||
|
var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
|
||||||
|
fileSystemParams.AddParameter(EFileSystemParameter.DisableUnityWebCache, false);
|
||||||
|
return fileSystemParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建默认的 WebGL 网络文件系统参数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="remoteService">远端资源地址查询服务类</param>
|
/// <param name="remoteService">远端资源地址查询服务类</param>
|
||||||
/// <param name="disableUnityWebCache">禁用Unity的网络缓存</param>
|
/// <param name="disableUnityWebCache">禁用Unity的网络缓存</param>
|
||||||
/// <returns>配置好的文件系统参数实例</returns>
|
/// <returns>配置好的文件系统参数实例</returns>
|
||||||
public static FileSystemParameters CreateDefaultWebRemoteFileSystemParameters(IRemoteService remoteService, bool disableUnityWebCache = false)
|
public static FileSystemParameters CreateDefaultWebNetworkFileSystemParameters(IRemoteService remoteService, bool disableUnityWebCache)
|
||||||
{
|
{
|
||||||
string fileSystemClass = typeof(WebRemoteFileSystem).FullName;
|
string fileSystemClass = typeof(WebNetworkFileSystem).FullName;
|
||||||
var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
|
var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
|
||||||
fileSystemParams.AddParameter(EFileSystemParameter.RemoteService, remoteService);
|
fileSystemParams.AddParameter(EFileSystemParameter.RemoteService, remoteService);
|
||||||
fileSystemParams.AddParameter(EFileSystemParameter.DisableUnityWebCache, disableUnityWebCache);
|
fileSystemParams.AddParameter(EFileSystemParameter.DisableUnityWebCache, disableUnityWebCache);
|
||||||
return fileSystemParams;
|
return fileSystemParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建默认的 WebGL 网络文件系统参数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="remoteService">远端资源地址查询服务类</param>
|
||||||
|
/// <returns>配置好的文件系统参数实例</returns>
|
||||||
|
public static FileSystemParameters CreateDefaultWebNetworkFileSystemParameters(IRemoteService remoteService)
|
||||||
|
{
|
||||||
|
string fileSystemClass = typeof(WebNetworkFileSystem).FullName;
|
||||||
|
var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
|
||||||
|
fileSystemParams.AddParameter(EFileSystemParameter.RemoteService, remoteService);
|
||||||
|
fileSystemParams.AddParameter(EFileSystemParameter.DisableUnityWebCache, false);
|
||||||
|
return fileSystemParams;
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Networking;
|
||||||
|
|
||||||
|
namespace YooAsset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Web 平台 AssetBundle 请求创建参数
|
||||||
|
/// </summary>
|
||||||
|
internal readonly struct WebAssetBundleRequestArgs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 请求地址
|
||||||
|
/// </summary>
|
||||||
|
public string Url { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 禁用 Unity 的网络缓存
|
||||||
|
/// </summary>
|
||||||
|
public bool DisableUnityWebCache { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// AssetBundle 文件哈希(用于 UnityWebRequest 的缓存)
|
||||||
|
/// </summary>
|
||||||
|
public string FileHash { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unity CRC 校验值
|
||||||
|
/// </summary>
|
||||||
|
public uint UnityCrc { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建 <see cref="WebAssetBundleRequestArgs"/> 实例
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="url">请求地址</param>
|
||||||
|
/// <param name="disableUnityWebCache">是否禁用 Unity 内置缓存</param>
|
||||||
|
/// <param name="fileHash">文件哈希(启用缓存时必须提供)</param>
|
||||||
|
/// <param name="unityCrc">Unity CRC 校验值</param>
|
||||||
|
internal WebAssetBundleRequestArgs(string url, bool disableUnityWebCache, string fileHash, uint unityCrc)
|
||||||
|
{
|
||||||
|
Url = url;
|
||||||
|
DisableUnityWebCache = disableUnityWebCache;
|
||||||
|
FileHash = fileHash;
|
||||||
|
UnityCrc = unityCrc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Web 平台策略接口
|
||||||
|
/// </summary>
|
||||||
|
internal interface IWebPlatformStrategy
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 创建平台专用的 AssetBundle 下载请求
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="args">AssetBundle 下载参数</param>
|
||||||
|
/// <returns>已配置的 UnityWebRequest 实例</returns>
|
||||||
|
UnityWebRequest CreateAssetBundleRequest(WebAssetBundleRequestArgs args);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从已完成的请求中提取 AssetBundle 对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">已完成下载的 UnityWebRequest</param>
|
||||||
|
/// <returns>提取到的 AssetBundle,若提取失败则返回 null。</returns>
|
||||||
|
AssetBundle ExtractAssetBundle(UnityWebRequest request);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用平台专用 API 卸载 AssetBundle
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="assetBundle">待卸载的 AssetBundle 实例</param>
|
||||||
|
/// <param name="unloadAll">是否同时卸载所有已加载的资源对象</param>
|
||||||
|
void UnloadAssetBundle(AssetBundle assetBundle, bool unloadAll);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d5217b971ba83444ba8a88e6f7e6bc91
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b53ed2101236bcf4d843b04092551496
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1f5a778803657b4499c84eb940b0f485
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
|
||||||
|
namespace YooAsset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Web 网络文件系统的初始化操作
|
||||||
|
/// </summary>
|
||||||
|
internal sealed class WNFSInitializeOperation : FSInitializeOperation
|
||||||
|
{
|
||||||
|
private enum ESteps
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
CheckPlatform,
|
||||||
|
CheckParameter,
|
||||||
|
InitializeBundleCache,
|
||||||
|
Done,
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly WebNetworkFileSystem _fileSystem;
|
||||||
|
private BCInitializeOperation _initializeBundleCacheOp;
|
||||||
|
private ESteps _steps = ESteps.None;
|
||||||
|
|
||||||
|
public WNFSInitializeOperation(WebNetworkFileSystem fileSystem)
|
||||||
|
{
|
||||||
|
_fileSystem = fileSystem;
|
||||||
|
}
|
||||||
|
protected override void InternalStart()
|
||||||
|
{
|
||||||
|
_steps = ESteps.CheckPlatform;
|
||||||
|
}
|
||||||
|
protected override void InternalUpdate()
|
||||||
|
{
|
||||||
|
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_steps == ESteps.CheckPlatform)
|
||||||
|
{
|
||||||
|
#if !UNITY_WEBGL
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError($"{nameof(WebNetworkFileSystem)} only supports the WebGL platform.");
|
||||||
|
#else
|
||||||
|
_steps = ESteps.CheckParameter;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_steps == ESteps.CheckParameter)
|
||||||
|
{
|
||||||
|
if (_fileSystem.RemoteService == null)
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError($"{nameof(IRemoteService)} is null.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查URL双斜杠
|
||||||
|
// 注意:双斜杠会导致某小游戏平台加载文件失败,但网络请求又不返回失败!
|
||||||
|
var testUrls = _fileSystem.RemoteService.GetRemoteUrls("test.bundle");
|
||||||
|
foreach (var url in testUrls)
|
||||||
|
{
|
||||||
|
if (PathUtility.ContainsDoubleSlashes(url))
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError($"{nameof(IRemoteService)} returned URL contains double slashes: '{url}'.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_steps = ESteps.InitializeBundleCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_steps == ESteps.InitializeBundleCache)
|
||||||
|
{
|
||||||
|
if (_initializeBundleCacheOp == null)
|
||||||
|
{
|
||||||
|
_initializeBundleCacheOp = _fileSystem.BundleCache.InitializeAsync();
|
||||||
|
_initializeBundleCacheOp.StartOperation();
|
||||||
|
AddChildOperation(_initializeBundleCacheOp);
|
||||||
|
}
|
||||||
|
|
||||||
|
_initializeBundleCacheOp.UpdateOperation();
|
||||||
|
Progress = _initializeBundleCacheOp.Progress;
|
||||||
|
if (_initializeBundleCacheOp.IsDone == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_initializeBundleCacheOp.Status == EOperationStatus.Succeeded)
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetResult();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError(_initializeBundleCacheOp.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7bc4d280057c61c41bfee7ad5dd6a2d8
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
|
||||||
|
namespace YooAsset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Web 网络文件系统的加载资源包操作
|
||||||
|
/// </summary>
|
||||||
|
internal sealed class WNFSLoadPackageBundleOperation : FSLoadPackageBundleOperation
|
||||||
|
{
|
||||||
|
private enum ESteps
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
LoadBundle,
|
||||||
|
Done,
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly WebNetworkFileSystem _fileSystem;
|
||||||
|
private readonly FSLoadPackageBundleOptions _options;
|
||||||
|
private BCLoadBundleOperation _loadBundleOp;
|
||||||
|
private ESteps _steps = ESteps.None;
|
||||||
|
|
||||||
|
internal WNFSLoadPackageBundleOperation(WebNetworkFileSystem fileSystem, FSLoadPackageBundleOptions options)
|
||||||
|
{
|
||||||
|
_fileSystem = fileSystem;
|
||||||
|
_options = options;
|
||||||
|
}
|
||||||
|
protected override void InternalStart()
|
||||||
|
{
|
||||||
|
_steps = ESteps.LoadBundle;
|
||||||
|
}
|
||||||
|
protected override void InternalUpdate()
|
||||||
|
{
|
||||||
|
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_steps == ESteps.LoadBundle)
|
||||||
|
{
|
||||||
|
if (_loadBundleOp == null)
|
||||||
|
{
|
||||||
|
_loadBundleOp = _fileSystem.BundleCache.LoadBundleAsync(_options.ConvertTo());
|
||||||
|
_loadBundleOp.StartOperation();
|
||||||
|
AddChildOperation(_loadBundleOp);
|
||||||
|
}
|
||||||
|
|
||||||
|
_loadBundleOp.UpdateOperation();
|
||||||
|
Progress = _loadBundleOp.Progress;
|
||||||
|
if (_loadBundleOp.IsDone == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_loadBundleOp.Status == EOperationStatus.Succeeded)
|
||||||
|
{
|
||||||
|
if (_loadBundleOp.BundleHandle == null)
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError("Fatal error: loaded bundle handle is null.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetResult();
|
||||||
|
BundleHandle = _loadBundleOp.BundleHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError(_loadBundleOp.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected override void InternalWaitForCompletion()
|
||||||
|
{
|
||||||
|
if (_steps != ESteps.Done)
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError("WebGL platform does not support synchronous loading.");
|
||||||
|
YooLogger.LogError(Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 99f15c9a609c8704d9d43f56c6d0b725
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
|
||||||
|
namespace YooAsset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Web 网络文件系统的加载包裹清单操作
|
||||||
|
/// </summary>
|
||||||
|
internal sealed class WNFSLoadPackageManifestOperation : FSLoadPackageManifestOperation
|
||||||
|
{
|
||||||
|
private enum ESteps
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
RequestPackageHash,
|
||||||
|
LoadPackageManifest,
|
||||||
|
Done,
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly WebNetworkFileSystem _fileSystem;
|
||||||
|
private readonly string _packageVersion;
|
||||||
|
private readonly int _timeout;
|
||||||
|
private RequestWebPackageHashOperation _requestWebPackageHashOp;
|
||||||
|
private LoadWebPackageManifestOperation _loadWebPackageManifestOp;
|
||||||
|
private ESteps _steps = ESteps.None;
|
||||||
|
|
||||||
|
public WNFSLoadPackageManifestOperation(WebNetworkFileSystem fileSystem, string packageVersion, int timeout)
|
||||||
|
{
|
||||||
|
_fileSystem = fileSystem;
|
||||||
|
_packageVersion = packageVersion;
|
||||||
|
_timeout = timeout;
|
||||||
|
}
|
||||||
|
protected override void InternalStart()
|
||||||
|
{
|
||||||
|
_steps = ESteps.RequestPackageHash;
|
||||||
|
}
|
||||||
|
protected override void InternalUpdate()
|
||||||
|
{
|
||||||
|
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_steps == ESteps.RequestPackageHash)
|
||||||
|
{
|
||||||
|
if (_requestWebPackageHashOp == null)
|
||||||
|
{
|
||||||
|
var options = new RequestWebPackageHashOptions(
|
||||||
|
packageName: _fileSystem.PackageName,
|
||||||
|
packageVersion: _packageVersion,
|
||||||
|
timeout: _timeout,
|
||||||
|
remoteService: _fileSystem.RemoteService,
|
||||||
|
downloadBackend: _fileSystem.DownloadBackend,
|
||||||
|
downloadUrlPolicy: _fileSystem.DownloadUrlPolicy);
|
||||||
|
_requestWebPackageHashOp = new RequestWebPackageHashOperation(options);
|
||||||
|
_requestWebPackageHashOp.StartOperation();
|
||||||
|
AddChildOperation(_requestWebPackageHashOp);
|
||||||
|
}
|
||||||
|
|
||||||
|
_requestWebPackageHashOp.UpdateOperation();
|
||||||
|
if (_requestWebPackageHashOp.IsDone == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_requestWebPackageHashOp.Status == EOperationStatus.Succeeded)
|
||||||
|
{
|
||||||
|
_steps = ESteps.LoadPackageManifest;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError(_requestWebPackageHashOp.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_steps == ESteps.LoadPackageManifest)
|
||||||
|
{
|
||||||
|
if (_loadWebPackageManifestOp == null)
|
||||||
|
{
|
||||||
|
var options = new LoadWebPackageManifestOptions(
|
||||||
|
packageName: _fileSystem.PackageName,
|
||||||
|
packageVersion: _packageVersion,
|
||||||
|
packageHash: _requestWebPackageHashOp.PackageHash,
|
||||||
|
timeout: _timeout,
|
||||||
|
remoteService: _fileSystem.RemoteService,
|
||||||
|
manifestDecryptor: _fileSystem.ManifestDecryptor,
|
||||||
|
downloadBackend: _fileSystem.DownloadBackend,
|
||||||
|
downloadUrlPolicy: _fileSystem.DownloadUrlPolicy);
|
||||||
|
_loadWebPackageManifestOp = new LoadWebPackageManifestOperation(options);
|
||||||
|
_loadWebPackageManifestOp.StartOperation();
|
||||||
|
AddChildOperation(_loadWebPackageManifestOp);
|
||||||
|
}
|
||||||
|
|
||||||
|
_loadWebPackageManifestOp.UpdateOperation();
|
||||||
|
Progress = _loadWebPackageManifestOp.Progress;
|
||||||
|
if (_loadWebPackageManifestOp.IsDone == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_loadWebPackageManifestOp.Status == EOperationStatus.Succeeded)
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
Manifest = _loadWebPackageManifestOp.Manifest;
|
||||||
|
SetResult();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError(_loadWebPackageManifestOp.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ede4746ef2339a046abb55f8bb6208b3
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
|
||||||
|
namespace YooAsset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Web 网络文件系统的查询包裹版本操作
|
||||||
|
/// </summary>
|
||||||
|
internal sealed class WNFSRequestPackageVersionOperation : FSRequestPackageVersionOperation
|
||||||
|
{
|
||||||
|
private enum ESteps
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
RequestPackageVersion,
|
||||||
|
Done,
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly WebNetworkFileSystem _fileSystem;
|
||||||
|
private readonly bool _appendTimeTicks;
|
||||||
|
private readonly int _timeout;
|
||||||
|
private RequestWebPackageVersionOperation _requestWebPackageVersionOp;
|
||||||
|
private ESteps _steps = ESteps.None;
|
||||||
|
|
||||||
|
internal WNFSRequestPackageVersionOperation(WebNetworkFileSystem fileSystem, bool appendTimeTicks, int timeout)
|
||||||
|
{
|
||||||
|
_fileSystem = fileSystem;
|
||||||
|
_appendTimeTicks = appendTimeTicks;
|
||||||
|
_timeout = timeout;
|
||||||
|
}
|
||||||
|
protected override void InternalStart()
|
||||||
|
{
|
||||||
|
_steps = ESteps.RequestPackageVersion;
|
||||||
|
}
|
||||||
|
protected override void InternalUpdate()
|
||||||
|
{
|
||||||
|
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_steps == ESteps.RequestPackageVersion)
|
||||||
|
{
|
||||||
|
if (_requestWebPackageVersionOp == null)
|
||||||
|
{
|
||||||
|
var options = new RequestWebPackageVersionOptions(
|
||||||
|
packageName: _fileSystem.PackageName,
|
||||||
|
appendTimeTicks: _appendTimeTicks,
|
||||||
|
timeout: _timeout,
|
||||||
|
remoteService: _fileSystem.RemoteService,
|
||||||
|
downloadBackend: _fileSystem.DownloadBackend,
|
||||||
|
downloadUrlPolicy: _fileSystem.DownloadUrlPolicy);
|
||||||
|
_requestWebPackageVersionOp = new RequestWebPackageVersionOperation(options);
|
||||||
|
_requestWebPackageVersionOp.StartOperation();
|
||||||
|
AddChildOperation(_requestWebPackageVersionOp);
|
||||||
|
}
|
||||||
|
|
||||||
|
_requestWebPackageVersionOp.UpdateOperation();
|
||||||
|
Progress = _requestWebPackageVersionOp.Progress;
|
||||||
|
if (_requestWebPackageVersionOp.IsDone == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_requestWebPackageVersionOp.Status == EOperationStatus.Succeeded)
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
PackageVersion = _requestWebPackageVersionOp.PackageVersion;
|
||||||
|
SetResult();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
SetError(_requestWebPackageVersionOp.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e9a998b8662b7aa4f93027060239f864
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,261 @@
|
|||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace YooAsset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Web 网络文件系统,统一管理普通 Web 和 Mini Game 平台的远程资源加载。
|
||||||
|
/// 通过 IWebPlatformStrategy 隔离不同平台的 AssetBundle 请求、提取和卸载行为。
|
||||||
|
/// </summary>
|
||||||
|
internal class WebNetworkFileSystem : IFileSystem
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 包裹名称
|
||||||
|
/// </summary>
|
||||||
|
public string PackageName { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Web 文件缓存系统
|
||||||
|
/// </summary>
|
||||||
|
public IBundleCache BundleCache { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下载后台接口
|
||||||
|
/// </summary>
|
||||||
|
public IDownloadBackend DownloadBackend { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 平台策略
|
||||||
|
/// </summary>
|
||||||
|
public IWebPlatformStrategy PlatformStrategy { get; private set; }
|
||||||
|
|
||||||
|
#region 自定义参数
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义参数:UnityWebRequest 创建委托
|
||||||
|
/// </summary>
|
||||||
|
public UnityWebRequestCreator WebRequestCreator { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义参数:禁用 Unity 内置网络缓存
|
||||||
|
/// </summary>
|
||||||
|
public bool DisableUnityWebCache { get; private set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义参数:下载任务的看门狗机制超时时间
|
||||||
|
/// </summary>
|
||||||
|
public int DownloadWatchdogTimeout { get; private set; } = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义参数:下载的资源包数据的校验级别
|
||||||
|
/// </summary>
|
||||||
|
public EFileVerifyLevel DownloadVerifyLevel { get; private set; } = EFileVerifyLevel.Middle;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 远程服务接口
|
||||||
|
/// </summary>
|
||||||
|
public IRemoteService RemoteService { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义参数:AssetBundle 解密器
|
||||||
|
/// </summary>
|
||||||
|
public IBundleDecryptor AssetBundleDecryptor { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义参数:RawBundle 解密器
|
||||||
|
/// </summary>
|
||||||
|
public IBundleDecryptor RawBundleDecryptor { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义参数:资源清单解密器
|
||||||
|
/// </summary>
|
||||||
|
public IManifestDecryptor ManifestDecryptor { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义参数:下载重试判定策略
|
||||||
|
/// </summary>
|
||||||
|
public IDownloadRetryPolicy DownloadRetryPolicy { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义参数:URL 选择策略
|
||||||
|
/// </summary>
|
||||||
|
public IDownloadUrlPolicy DownloadUrlPolicy { get; private set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public WebNetworkFileSystem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual FSInitializeOperation InitializeAsync()
|
||||||
|
{
|
||||||
|
var operation = new WNFSInitializeOperation(this);
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(FSRequestPackageVersionOptions options)
|
||||||
|
{
|
||||||
|
var operation = new WNFSRequestPackageVersionOperation(this, options.AppendTimeTicks, options.Timeout);
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(FSLoadPackageManifestOptions options)
|
||||||
|
{
|
||||||
|
var operation = new WNFSLoadPackageManifestOperation(this, options.PackageVersion, options.Timeout);
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual FSLoadPackageBundleOperation LoadPackageBundleAsync(FSLoadPackageBundleOptions options)
|
||||||
|
{
|
||||||
|
var operation = new WNFSLoadPackageBundleOperation(this, options);
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual FSEnsurePackageBundleOperation EnsurePackageBundleAsync(FSEnsurePackageBundleOptions options)
|
||||||
|
{
|
||||||
|
var operation = new FSEnsurePackageBundleFailureOperation($"{nameof(WebNetworkFileSystem)} does not support ensure bundle file operation.");
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual FSDownloadBundleOperation DownloadBundleAsync(FSDownloadBundleOptions options)
|
||||||
|
{
|
||||||
|
var operation = new FSDownloadBundleCompleteOperation($"{nameof(WebNetworkFileSystem)} does not support download operation.");
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual FSClearCacheOperation ClearCacheAsync(FSClearCacheOptions options)
|
||||||
|
{
|
||||||
|
var operation = new FSClearCacheCompleteOperation();
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual void SetParameter(string paramName, object value)
|
||||||
|
{
|
||||||
|
if (paramName == nameof(EFileSystemParameter.DownloadBackend))
|
||||||
|
{
|
||||||
|
DownloadBackend = FileSystemHelper.CastParameter<IDownloadBackend>(paramName, value);
|
||||||
|
}
|
||||||
|
else if (paramName == nameof(EFileSystemParameter.UnityWebRequestCreator))
|
||||||
|
{
|
||||||
|
WebRequestCreator = FileSystemHelper.CastParameter<UnityWebRequestCreator>(paramName, value);
|
||||||
|
}
|
||||||
|
else if (paramName == nameof(EFileSystemParameter.DisableUnityWebCache))
|
||||||
|
{
|
||||||
|
DisableUnityWebCache = FileSystemHelper.CastParameter<bool>(paramName, value);
|
||||||
|
}
|
||||||
|
else if (paramName == nameof(EFileSystemParameter.DownloadWatchdogTimeout))
|
||||||
|
{
|
||||||
|
int convertValue = FileSystemHelper.CastParameter<int>(paramName, value);
|
||||||
|
DownloadWatchdogTimeout = Mathf.Max(convertValue, 0);
|
||||||
|
}
|
||||||
|
else if (paramName == nameof(EFileSystemParameter.FileVerifyLevel))
|
||||||
|
{
|
||||||
|
DownloadVerifyLevel = FileSystemHelper.CastParameter<EFileVerifyLevel>(paramName, value);
|
||||||
|
}
|
||||||
|
else if (paramName == nameof(EFileSystemParameter.RemoteService))
|
||||||
|
{
|
||||||
|
RemoteService = FileSystemHelper.CastParameter<IRemoteService>(paramName, value);
|
||||||
|
}
|
||||||
|
else if (paramName == nameof(EFileSystemParameter.AssetbundleDecryptor))
|
||||||
|
{
|
||||||
|
AssetBundleDecryptor = FileSystemHelper.CastParameter<IBundleDecryptor>(paramName, value);
|
||||||
|
}
|
||||||
|
else if (paramName == nameof(EFileSystemParameter.RawbundleDecryptor))
|
||||||
|
{
|
||||||
|
RawBundleDecryptor = FileSystemHelper.CastParameter<IBundleDecryptor>(paramName, value);
|
||||||
|
}
|
||||||
|
else if (paramName == nameof(EFileSystemParameter.ManifestDecryptor))
|
||||||
|
{
|
||||||
|
ManifestDecryptor = FileSystemHelper.CastParameter<IManifestDecryptor>(paramName, value);
|
||||||
|
}
|
||||||
|
else if (paramName == nameof(EFileSystemParameter.DownloadRetryPolicy))
|
||||||
|
{
|
||||||
|
DownloadRetryPolicy = FileSystemHelper.CastParameter<IDownloadRetryPolicy>(paramName, value);
|
||||||
|
}
|
||||||
|
else if (paramName == nameof(EFileSystemParameter.DownloadUrlPolicy))
|
||||||
|
{
|
||||||
|
DownloadUrlPolicy = FileSystemHelper.CastParameter<IDownloadUrlPolicy>(paramName, value);
|
||||||
|
}
|
||||||
|
else if (paramName == nameof(EFileSystemParameter.WebPlatformStrategy))
|
||||||
|
{
|
||||||
|
PlatformStrategy = FileSystemHelper.CastParameter<IWebPlatformStrategy>(paramName, value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"Unrecognized parameter name: '{paramName}'.", nameof(paramName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual void OnCreate(string packageName, string packageRoot)
|
||||||
|
{
|
||||||
|
PackageName = packageName;
|
||||||
|
|
||||||
|
// 创建默认的下载后台接口
|
||||||
|
if (DownloadBackend == null)
|
||||||
|
DownloadBackend = new UnityWebRequestBackend(WebRequestCreator);
|
||||||
|
|
||||||
|
// 创建默认的下载重试策略
|
||||||
|
if (DownloadRetryPolicy == null)
|
||||||
|
DownloadRetryPolicy = new DefaultDownloadRetryPolicy();
|
||||||
|
|
||||||
|
// 创建默认的 URL 选择策略
|
||||||
|
if (DownloadUrlPolicy == null)
|
||||||
|
DownloadUrlPolicy = new DefaultDownloadUrlPolicy();
|
||||||
|
|
||||||
|
// 创建默认的平台策略
|
||||||
|
if (PlatformStrategy == null)
|
||||||
|
PlatformStrategy = new DefaultWebPlatformStrategy(WebRequestCreator);
|
||||||
|
|
||||||
|
// 创建文件缓存系统
|
||||||
|
var cacheConfig = new WebNetworkBundleCache.Configuration(
|
||||||
|
watchdogTimeout: DownloadWatchdogTimeout,
|
||||||
|
disableUnityWebCache: DisableUnityWebCache,
|
||||||
|
downloadVerifyLevel: DownloadVerifyLevel,
|
||||||
|
assetBundleDecryptor: AssetBundleDecryptor,
|
||||||
|
rawBundleDecryptor: RawBundleDecryptor,
|
||||||
|
platformStrategy: PlatformStrategy,
|
||||||
|
remoteService: RemoteService,
|
||||||
|
downloadBackend: DownloadBackend,
|
||||||
|
downloadRetryPolicy: DownloadRetryPolicy,
|
||||||
|
downloadUrlPolicy: DownloadUrlPolicy);
|
||||||
|
BundleCache = new WebNetworkBundleCache(packageName, cacheConfig);
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual void OnDestroy()
|
||||||
|
{
|
||||||
|
if (BundleCache != null)
|
||||||
|
{
|
||||||
|
BundleCache.Dispose();
|
||||||
|
BundleCache = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DownloadBackend != null)
|
||||||
|
{
|
||||||
|
DownloadBackend.Dispose();
|
||||||
|
DownloadBackend = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual bool CanAcceptBundle(PackageBundle bundle)
|
||||||
|
{
|
||||||
|
// 注意:保底加载!
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual bool IsDownloadRequired(PackageBundle bundle)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual bool IsUnpackRequired(PackageBundle bundle)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual bool IsImportRequired(PackageBundle bundle)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f94fe3b8c3221ca46a231841876d1f44
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -30,6 +30,11 @@ namespace YooAsset
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IDownloadBackend DownloadBackend { get; private set; }
|
public IDownloadBackend DownloadBackend { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 平台策略
|
||||||
|
/// </summary>
|
||||||
|
public IWebPlatformStrategy PlatformStrategy { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 包裹名称
|
/// 包裹名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -175,6 +180,10 @@ namespace YooAsset
|
|||||||
{
|
{
|
||||||
DownloadUrlPolicy = FileSystemHelper.CastParameter<IDownloadUrlPolicy>(paramName, value);
|
DownloadUrlPolicy = FileSystemHelper.CastParameter<IDownloadUrlPolicy>(paramName, value);
|
||||||
}
|
}
|
||||||
|
else if (paramName == nameof(EFileSystemParameter.WebPlatformStrategy))
|
||||||
|
{
|
||||||
|
PlatformStrategy = FileSystemHelper.CastParameter<IWebPlatformStrategy>(paramName, value);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new ArgumentException($"Unrecognized parameter name: '{paramName}'.", nameof(paramName));
|
throw new ArgumentException($"Unrecognized parameter name: '{paramName}'.", nameof(paramName));
|
||||||
@@ -202,6 +211,10 @@ namespace YooAsset
|
|||||||
if (DownloadUrlPolicy == null)
|
if (DownloadUrlPolicy == null)
|
||||||
DownloadUrlPolicy = new DefaultDownloadUrlPolicy();
|
DownloadUrlPolicy = new DefaultDownloadUrlPolicy();
|
||||||
|
|
||||||
|
// 创建默认的平台策略
|
||||||
|
if (PlatformStrategy == null)
|
||||||
|
PlatformStrategy = new DefaultWebPlatformStrategy(WebRequestCreator);
|
||||||
|
|
||||||
// 创建Web文件缓存系统
|
// 创建Web文件缓存系统
|
||||||
var cacheConfig = new WebServerBundleCache.Configuration(
|
var cacheConfig = new WebServerBundleCache.Configuration(
|
||||||
watchdogTimeout: DownloadWatchdogTimeout,
|
watchdogTimeout: DownloadWatchdogTimeout,
|
||||||
@@ -209,6 +222,7 @@ namespace YooAsset
|
|||||||
downloadVerifyLevel: DownloadVerifyLevel,
|
downloadVerifyLevel: DownloadVerifyLevel,
|
||||||
assetBundleDecryptor: AssetBundleDecryptor,
|
assetBundleDecryptor: AssetBundleDecryptor,
|
||||||
rawBundleDecryptor: RawBundleDecryptor,
|
rawBundleDecryptor: RawBundleDecryptor,
|
||||||
|
platformStrategy: PlatformStrategy,
|
||||||
downloadBackend: DownloadBackend,
|
downloadBackend: DownloadBackend,
|
||||||
downloadRetryPolicy: DownloadRetryPolicy,
|
downloadRetryPolicy: DownloadRetryPolicy,
|
||||||
downloadUrlPolicy: DownloadUrlPolicy);
|
downloadUrlPolicy: DownloadUrlPolicy);
|
||||||
|
|||||||
8
Assets/YooAsset/Runtime/FileSystem/Strategies.meta
Normal file
8
Assets/YooAsset/Runtime/FileSystem/Strategies.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b4543ee92e5cdb94199ea3a0e2886467
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Networking;
|
||||||
|
|
||||||
|
namespace YooAsset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 网页端平台策略的默认实现
|
||||||
|
/// </summary>
|
||||||
|
internal sealed class DefaultWebPlatformStrategy : IWebPlatformStrategy
|
||||||
|
{
|
||||||
|
private readonly UnityWebRequestCreator _webRequestCreator;
|
||||||
|
|
||||||
|
public DefaultWebPlatformStrategy(UnityWebRequestCreator webRequestCreator)
|
||||||
|
{
|
||||||
|
_webRequestCreator = webRequestCreator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public UnityWebRequest CreateAssetBundleRequest(WebAssetBundleRequestArgs args)
|
||||||
|
{
|
||||||
|
var downloadHandler = CreateAssetBundleDownloadHandler(args);
|
||||||
|
var request = CreateGetWebRequest(args.Url);
|
||||||
|
request.downloadHandler = downloadHandler;
|
||||||
|
request.disposeDownloadHandlerOnDispose = true;
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public AssetBundle ExtractAssetBundle(UnityWebRequest request)
|
||||||
|
{
|
||||||
|
var handler = (DownloadHandlerAssetBundle)request.downloadHandler;
|
||||||
|
return handler.assetBundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void UnloadAssetBundle(AssetBundle assetBundle, bool unloadAll)
|
||||||
|
{
|
||||||
|
assetBundle.Unload(unloadAll);
|
||||||
|
}
|
||||||
|
|
||||||
|
private UnityWebRequest CreateGetWebRequest(string url)
|
||||||
|
{
|
||||||
|
if (_webRequestCreator != null)
|
||||||
|
return _webRequestCreator.Invoke(url, UnityWebRequest.kHttpVerbGET);
|
||||||
|
|
||||||
|
return new UnityWebRequest(url, UnityWebRequest.kHttpVerbGET);
|
||||||
|
}
|
||||||
|
private DownloadHandlerAssetBundle CreateAssetBundleDownloadHandler(WebAssetBundleRequestArgs args)
|
||||||
|
{
|
||||||
|
if (args.DisableUnityWebCache)
|
||||||
|
{
|
||||||
|
// 禁用 Unity 缓存
|
||||||
|
return new DownloadHandlerAssetBundle(args.Url, args.UnityCrc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(args.FileHash))
|
||||||
|
throw new YooInternalException("FileHash is required when Unity web cache is enabled (DisableUnityWebCache = false).");
|
||||||
|
|
||||||
|
// 使用 Unity 缓存
|
||||||
|
// 说明:The file hash defining the version of the asset bundle.
|
||||||
|
Hash128 fileHash = Hash128.Parse(args.FileHash);
|
||||||
|
return new DownloadHandlerAssetBundle(args.Url, fileHash, args.UnityCrc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1ff4623c14d90d24284e3d10a78a7eb0
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -106,7 +106,7 @@ namespace YooAsset
|
|||||||
else if (_playMode == EPlayMode.WebPlayMode)
|
else if (_playMode == EPlayMode.WebPlayMode)
|
||||||
{
|
{
|
||||||
var initializeParameters = _options as WebPlayModeOptions;
|
var initializeParameters = _options as WebPlayModeOptions;
|
||||||
_initializeFileSystemOp = _fileSystemHost.InitializeAsync(initializeParameters.WebServerFileSystemParameters, initializeParameters.WebRemoteFileSystemParameters);
|
_initializeFileSystemOp = _fileSystemHost.InitializeAsync(initializeParameters.WebServerFileSystemParameters, initializeParameters.WebNetworkFileSystemParameters);
|
||||||
}
|
}
|
||||||
else if (_playMode == EPlayMode.CustomPlayMode)
|
else if (_playMode == EPlayMode.CustomPlayMode)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -72,9 +72,9 @@ namespace YooAsset
|
|||||||
public FileSystemParameters WebServerFileSystemParameters { get; set; }
|
public FileSystemParameters WebServerFileSystemParameters { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Web远程文件系统初始化参数
|
/// Web 网络文件系统初始化参数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public FileSystemParameters WebRemoteFileSystemParameters { get; set; }
|
public FileSystemParameters WebNetworkFileSystemParameters { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user