refactor the runtime code

重构了运行时代码,支持全新的文件系统。
This commit is contained in:
何冠峰
2024-07-04 20:36:26 +08:00
parent 2987d356b6
commit ff02da5c54
313 changed files with 9889 additions and 7234 deletions
@@ -0,0 +1,277 @@
using System;
using System.IO;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
internal class DefaultWebFileSystem : IFileSystem
{
public class FileWrapper
{
public string FileName { private set; get; }
public FileWrapper(string fileName)
{
FileName = fileName;
}
}
protected readonly Dictionary<string, FileWrapper> _wrappers = new Dictionary<string, FileWrapper>(10000);
protected readonly Dictionary<string, string> _webFilePaths = new Dictionary<string, string>(10000);
protected string _webPackageRoot = string.Empty;
/// <summary>
/// 包裹名称
/// </summary>
public string PackageName { private set; get; }
/// <summary>
/// 文件访问权限
/// </summary>
public EFileAccess FileSystemAccess
{
get
{
return EFileAccess.ReadWrite;
}
}
/// <summary>
/// 文件根目录
/// </summary>
public string FileRoot
{
get
{
return _webPackageRoot;
}
}
/// <summary>
/// 文件数量
/// </summary>
public int FileCount
{
get
{
return 0;
}
}
#region 自定义参数
public bool AllowCrossAccess { private set; get; } = false;
/// <summary>
/// 自定义参数:远程服务接口
/// </summary>
public IRemoteServices RemoteServices { private set; get; } = null;
#endregion
public DefaultWebFileSystem()
{
}
public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync()
{
var operation = new DWFSInitializeOperation(this);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(params object[] args)
{
string packageVersion = args[0] as string;
int timeout = (int)args[1];
if (AllowCrossAccess)
{
var operation = new DWFSLoadRemotePackageManifestOperation(this, packageVersion, timeout);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
else
{
var operation = new DWFSLoadWebPackageManifestOperation(this, timeout);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
}
public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(params object[] args)
{
bool appendTimeTicks = (bool)args[0];
int timeout = (int)args[1];
var operation = new DWFSRequestPackageVersionOperation(this, appendTimeTicks, timeout);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSClearAllBundleFilesOperation ClearAllBundleFilesAsync(params object[] args)
{
var operation = new DWFSClearAllBundleFilesOperation(this);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(params object[] args)
{
var operation = new DWFSClearUnusedBundleFilesOperation(this);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSDownloadFileOperation DownloadFileAsync(params object[] args)
{
throw new System.NotImplementedException();
}
public virtual void SetParameter(string name, object value)
{
if (name == "ALLOW_CROSS_ACCESS")
{
AllowCrossAccess = (bool)value;
}
else if (name == "REMOTE_SERVICES")
{
RemoteServices = (IRemoteServices)value;
}
else
{
YooLogger.Warning($"Invalid parameter : {name}");
}
}
public virtual void OnCreate(string packageName, string rootDirectory)
{
PackageName = packageName;
if (string.IsNullOrEmpty(rootDirectory))
rootDirectory = GetDefaultWebRoot();
_webPackageRoot = PathUtility.Combine(rootDirectory, packageName);
}
public virtual void OnUpdate()
{
}
public virtual bool Belong(PackageBundle bundle)
{
return true;
}
public virtual bool Belong(string bundleGUID)
{
return true;
}
public virtual bool Exists(PackageBundle bundle)
{
return false;
}
public virtual bool Exists(string bundleGUID)
{
return false;
}
public virtual bool CheckNeedDownload(PackageBundle bundle)
{
return false;
}
public virtual bool CheckNeedUnpack(PackageBundle bundle)
{
return false;
}
public virtual bool CheckNeedImport(PackageBundle bundle)
{
return false;
}
public virtual bool WriteFile(PackageBundle bundle, string copyPath)
{
throw new System.NotImplementedException();
}
public virtual bool DeleteFile(PackageBundle bundle)
{
throw new System.NotImplementedException();
}
public virtual bool DeleteFile(string bundleGUID)
{
throw new System.NotImplementedException();
}
public virtual EFileVerifyResult VerifyFile(PackageBundle bundle)
{
return EFileVerifyResult.Succeed;
}
public virtual byte[] ReadFileBytes(PackageBundle bundle)
{
throw new System.NotImplementedException();
}
public virtual string ReadFileText(PackageBundle bundle)
{
throw new System.NotImplementedException();
}
public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle)
{
var operation = new DWFSLoadAssetBundleOperation(this, bundle);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual void UnloadBundleFile(PackageBundle bundle, object result)
{
AssetBundle assetBundle = result as AssetBundle;
if (assetBundle == null)
return;
if (assetBundle != null)
assetBundle.Unload(true);
}
#region 内部方法
protected string GetDefaultWebRoot()
{
string path = PathUtility.Combine(UnityEngine.Application.streamingAssetsPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
return path;
}
public string GetWebFileLoadPath(PackageBundle bundle)
{
if (_webFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
filePath = PathUtility.Combine(_webPackageRoot, bundle.FileName);
_webFilePaths.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
public string GetCatalogFileLoadPath()
{
string fileName = Path.GetFileNameWithoutExtension(DefaultBuildinFileSystemDefine.BuildinCatalogFileName);
return PathUtility.Combine(YooAssetSettingsData.Setting.DefaultYooFolderName, PackageName, fileName);
}
public string GetWebPackageVersionFilePath()
{
string fileName = YooAssetSettingsData.GetPackageVersionFileName(PackageName);
return PathUtility.Combine(FileRoot, fileName);
}
public string GetWebPackageHashFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion);
return PathUtility.Combine(FileRoot, fileName);
}
public string GetWebPackageManifestFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion);
return PathUtility.Combine(FileRoot, fileName);
}
/// <summary>
/// 记录缓存信息
/// </summary>
public bool Record(string bundleGUID, FileWrapper wrapper)
{
if (_wrappers.ContainsKey(bundleGUID))
{
YooLogger.Error($"{nameof(DefaultWebFileSystem)} has element : {bundleGUID}");
return false;
}
_wrappers.Add(bundleGUID, wrapper);
return true;
}
#endregion
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0772e17daa1b32b4a80a6211396a50e8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fe53f557bb5cf3242a04b3fce756dd38
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,20 @@
namespace YooAsset
{
internal sealed class DWFSClearAllBundleFilesOperation : FSClearAllBundleFilesOperation
{
private readonly DefaultWebFileSystem _fileSystem;
internal DWFSClearAllBundleFilesOperation(DefaultWebFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 68578d4c5e39a554aa3df2e7ec5218e9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,20 @@
namespace YooAsset
{
internal sealed class DWFSClearUnusedBundleFilesOperation : FSClearUnusedBundleFilesOperation
{
private readonly DefaultWebFileSystem _fileSystem;
internal DWFSClearUnusedBundleFilesOperation(DefaultWebFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1560968379b66d440a94382b2a311a15
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,137 @@
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
namespace YooAsset
{
internal class DWFSDownloadWebFileOperation : DefaultDownloadFileOperation
{
private readonly DefaultWebFileSystem _fileSystem;
private DownloadHandlerAssetBundle _downloadhandler;
private ESteps _steps = ESteps.None;
/// <summary>
/// 下载结果
/// </summary>
public AssetBundle Result { private set; get; }
internal DWFSDownloadWebFileOperation(DefaultWebFileSystem fileSystem, PackageBundle bundle, string mainURL, string fallbackURL, int failedTryAgain, int timeout)
: base(bundle, mainURL, fallbackURL, failedTryAgain, timeout)
{
_fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
_steps = ESteps.CreateRequest;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
// 创建下载器
if (_steps == ESteps.CreateRequest)
{
// 获取请求地址
_requestURL = GetRequestURL();
// 重置变量
_isAbort = false;
_latestDownloadBytes = 0;
_latestDownloadRealtime = Time.realtimeSinceStartup;
DownloadProgress = 0f;
DownloadedBytes = 0;
// 重置计时器
if (_tryAgainTimer > 0f)
YooLogger.Warning($"Try again download : {_requestURL}");
_tryAgainTimer = 0f;
// 创建下载器
CreateWebRequest();
_steps = ESteps.CheckRequest;
}
// 检测下载结果
if (_steps == ESteps.CheckRequest)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = DownloadProgress;
if (_webRequest.isDone == false)
{
CheckRequestTimeout();
return;
}
// 检查网络错误
if (CheckRequestResult())
{
_steps = ESteps.Done;
Result = _downloadhandler.assetBundle;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.TryAgain;
}
// 注意:最终释放请求器
DisposeWebRequest();
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
if (FailedTryAgain <= 0)
{
Status = EOperationStatus.Failed;
_steps = ESteps.Done;
YooLogger.Error(Error);
return;
}
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
FailedTryAgain--;
_steps = ESteps.CreateRequest;
YooLogger.Warning(Error);
}
}
}
internal override void InternalOnAbort()
{
_steps = ESteps.Done;
DisposeWebRequest();
}
private void CreateWebRequest()
{
uint unityCRC = Bundle.UnityCRC;
Hash128 fileHash = Hash128.Parse(Bundle.FileHash);
// 注意:优先从浏览器缓存里获取文件
// The file hash defining the version of the asset bundle.
_webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
_downloadhandler = new DownloadHandlerAssetBundle(_requestURL, fileHash, unityCRC);
#if UNITY_2020_3_OR_NEWER
_downloadhandler.autoLoadAssetBundle = false;
#endif
_webRequest.downloadHandler = _downloadhandler;
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();
}
private void DisposeWebRequest()
{
if (_webRequest != null)
{
//注意:引擎底层会自动调用Abort方法
_webRequest.Dispose();
_webRequest = null;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3b82b4b846083d34b958320b584d8d9b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,49 @@
namespace YooAsset
{
internal partial class DWFSInitializeOperation : FSInitializeFileSystemOperation
{
private enum ESteps
{
None,
LoadCatalogFile,
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private LoadWebCatalogFileOperation _loadCatalogFileOp;
private ESteps _steps = ESteps.None;
public DWFSInitializeOperation(DefaultWebFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
_steps = ESteps.LoadCatalogFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadCatalogFile)
{
if (_loadCatalogFileOp == null)
{
_loadCatalogFileOp = new LoadWebCatalogFileOperation(_fileSystem);
OperationSystem.StartOperation(_fileSystem.PackageName, _loadCatalogFileOp);
}
if (_loadCatalogFileOp.IsDone == false)
return;
// 说明:应用程序内不一定存在序列化文件
// 注意:总是返回成功
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4c7cf2dca805b0b4d91cb5e0782dcb0c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,87 @@
namespace YooAsset
{
internal class DWFSLoadAssetBundleOperation : FSLoadBundleOperation
{
private enum ESteps
{
None,
DownloadFile,
CheckResult,
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private readonly PackageBundle _bundle;
private DWFSDownloadWebFileOperation _downloadWebFileOp;
private ESteps _steps = ESteps.None;
internal DWFSLoadAssetBundleOperation(DefaultWebFileSystem fileSystem, PackageBundle bundle)
{
_fileSystem = fileSystem;
_bundle = bundle;
}
internal override void InternalOnStart()
{
DownloadProgress = 0f;
DownloadedBytes = 0;
_steps = ESteps.DownloadFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.DownloadFile)
{
if (_downloadWebFileOp == null)
{
int failedTryAgain = int.MaxValue;
int timeout = 60;
string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
string fallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
_downloadWebFileOp = new DWFSDownloadWebFileOperation(_fileSystem, _bundle, mainURL, fallbackURL, failedTryAgain, timeout);
}
DownloadProgress = _downloadWebFileOp.DownloadProgress;
DownloadedBytes = _downloadWebFileOp.DownloadedBytes;
Progress = _downloadWebFileOp.Progress;
if (_downloadWebFileOp.IsDone == false)
return;
if (_downloadWebFileOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Result = _downloadWebFileOp.Result;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloadWebFileOp.Error;
}
}
}
public override void WaitForAsyncComplete()
{
if (IsDone == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "WebGL platform not support sync load method !";
UnityEngine.Debug.LogError(Error);
}
}
public override void AbortDownloadOperation()
{
if (_steps == ESteps.DownloadFile)
{
if (_downloadWebFileOp != null)
_downloadWebFileOp.SetAbort();
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a50dacdf7a3ad7c40a4195126425bbec
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,198 @@
namespace YooAsset
{
internal class DWFSLoadWebPackageManifestOperation : FSLoadPackageManifestOperation
{
private enum ESteps
{
None,
RequestWebPackageVersion,
RequestWebPackageHash,
LoadWebPackageManifest,
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private readonly int _timeout;
private RequestWebPackageVersionOperation _requestWebPackageVersionOp;
private RequestWebPackageHashOperation _requestWebPackageHashOp;
private LoadWebPackageManifestOperation _loadWebPackageManifestOp;
private ESteps _steps = ESteps.None;
public DWFSLoadWebPackageManifestOperation(DefaultWebFileSystem fileSystem, int timeout)
{
_fileSystem = fileSystem;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_steps = ESteps.RequestWebPackageVersion;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestWebPackageVersion)
{
if (_requestWebPackageVersionOp == null)
{
_requestWebPackageVersionOp = new RequestWebPackageVersionOperation(_fileSystem, _timeout);
OperationSystem.StartOperation(_fileSystem.PackageName, _requestWebPackageVersionOp);
}
if (_requestWebPackageVersionOp.IsDone == false)
return;
if (_requestWebPackageVersionOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.RequestWebPackageHash;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _requestWebPackageVersionOp.Error;
}
}
if (_steps == ESteps.RequestWebPackageHash)
{
if (_requestWebPackageHashOp == null)
{
string packageVersion = _requestWebPackageVersionOp.PackageVersion;
_requestWebPackageHashOp = new RequestWebPackageHashOperation(_fileSystem, packageVersion, _timeout);
OperationSystem.StartOperation(_fileSystem.PackageName, _requestWebPackageHashOp);
}
if (_requestWebPackageHashOp.IsDone == false)
return;
if (_requestWebPackageHashOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.LoadWebPackageManifest;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _requestWebPackageHashOp.Error;
}
}
if (_steps == ESteps.LoadWebPackageManifest)
{
if (_loadWebPackageManifestOp == null)
{
string packageVersion = _requestWebPackageVersionOp.PackageVersion;
string packageHash = _requestWebPackageHashOp.PackageHash;
_loadWebPackageManifestOp = new LoadWebPackageManifestOperation(_fileSystem, packageVersion, packageHash);
OperationSystem.StartOperation(_fileSystem.PackageName, _loadWebPackageManifestOp);
}
Progress = _loadWebPackageManifestOp.Progress;
if (_loadWebPackageManifestOp.IsDone == false)
return;
if (_loadWebPackageManifestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Result = _loadWebPackageManifestOp.Manifest;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadWebPackageManifestOp.Error;
}
}
}
}
internal class DWFSLoadRemotePackageManifestOperation : FSLoadPackageManifestOperation
{
private enum ESteps
{
None,
RequestRemotePackageHash,
LoadRemotePackageManifest,
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly int _timeout;
private RequestRemotePackageHashOperation _requestRemotePackageHashOp;
private LoadRemotePackageManifestOperation _loadRemotePackageManifestOp;
private ESteps _steps = ESteps.None;
public DWFSLoadRemotePackageManifestOperation(DefaultWebFileSystem fileSystem, string packageVersion, int timeout)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_steps = ESteps.RequestRemotePackageHash;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestRemotePackageHash)
{
if (_requestRemotePackageHashOp == null)
{
_requestRemotePackageHashOp = new RequestRemotePackageHashOperation(_fileSystem, _packageVersion, _timeout);
OperationSystem.StartOperation(_fileSystem.PackageName, _requestRemotePackageHashOp);
}
if (_requestRemotePackageHashOp.IsDone == false)
return;
if (_requestRemotePackageHashOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.LoadRemotePackageManifest;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _requestRemotePackageHashOp.Error;
}
}
if (_steps == ESteps.LoadRemotePackageManifest)
{
if (_loadRemotePackageManifestOp == null)
{
string packageHash = _requestRemotePackageHashOp.PackageHash;
_loadRemotePackageManifestOp = new LoadRemotePackageManifestOperation(_fileSystem, _packageVersion, packageHash, _timeout);
OperationSystem.StartOperation(_fileSystem.PackageName, _loadRemotePackageManifestOp);
}
Progress = _loadRemotePackageManifestOp.Progress;
if (_loadRemotePackageManifestOp.IsDone == false)
return;
if (_loadRemotePackageManifestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Result = _loadRemotePackageManifestOp.Manifest;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadRemotePackageManifestOp.Error;
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0d0f8063cfabb5d40b364f162ce49fc0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,66 @@
namespace YooAsset
{
internal class DWFSRequestPackageVersionOperation : FSRequestPackageVersionOperation
{
private enum ESteps
{
None,
GetPackageVersion,
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private DefaultGetRemotePackageVersionOperation _getRemotePackageVersionOp;
private ESteps _steps = ESteps.None;
internal DWFSRequestPackageVersionOperation(DefaultWebFileSystem fileSystem, bool appendTimeTicks, int timeout)
{
_fileSystem = fileSystem;
_appendTimeTicks = appendTimeTicks;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_steps = ESteps.GetPackageVersion;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.GetPackageVersion)
{
if (_getRemotePackageVersionOp == null)
{
string packageName = _fileSystem.PackageName;
string fileName = YooAssetSettingsData.GetPackageVersionFileName(packageName);
string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(fileName);
string fallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName);
_getRemotePackageVersionOp = new DefaultGetRemotePackageVersionOperation(packageName, mainURL, fallbackURL, _appendTimeTicks, _timeout);
OperationSystem.StartOperation(packageName, _getRemotePackageVersionOp);
}
Progress = _getRemotePackageVersionOp.Progress;
if (_getRemotePackageVersionOp.IsDone == false)
return;
if (_getRemotePackageVersionOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
PackageVersion = _getRemotePackageVersionOp.PackageVersion;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _getRemotePackageVersionOp.Error;
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 212a79e362fe6234c81fa79c3924dd20
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0e91f62e8fc7c1f4592681b7881ad925
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,125 @@
namespace YooAsset
{
internal class LoadRemotePackageManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
RequestFileData,
VerifyFileData,
LoadManifest,
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly string _packageHash;
private readonly int _timeout;
private UnityWebDataRequestOperation _webDataRequestOp;
private DeserializeManifestOperation _deserializer;
private int _requestCount = 0;
private ESteps _steps = ESteps.None;
/// <summary>
/// 加载的清单实例
/// </summary>
public PackageManifest Manifest { private set; get; }
internal LoadRemotePackageManifestOperation(DefaultWebFileSystem fileSystem, string packageVersion, string packageHash, int timeout)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;
_packageHash = packageHash;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(LoadRemotePackageManifestOperation));
_steps = ESteps.RequestFileData;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestFileData)
{
if (_webDataRequestOp == null)
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_fileSystem.PackageName, _packageVersion);
string url = GetDownloadRequestURL(fileName);
_webDataRequestOp = new UnityWebDataRequestOperation(url, _timeout);
OperationSystem.StartOperation(_fileSystem.PackageName, _webDataRequestOp);
}
Progress = _webDataRequestOp.Progress;
if (_webDataRequestOp.IsDone == false)
return;
if (_webDataRequestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.VerifyFileData;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _webDataRequestOp.Error;
WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(LoadRemotePackageManifestOperation));
}
}
if (_steps == ESteps.VerifyFileData)
{
string fileHash = HashUtility.BytesMD5(_webDataRequestOp.Result);
if (fileHash == _packageHash)
{
_steps = ESteps.LoadManifest;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Failed to verify remote package manifest file!";
}
}
if (_steps == ESteps.LoadManifest)
{
if (_deserializer == null)
{
_deserializer = new DeserializeManifestOperation(_webDataRequestOp.Result);
OperationSystem.StartOperation(_fileSystem.PackageName, _deserializer);
}
Progress = _deserializer.Progress;
if (_deserializer.IsDone == false)
return;
if (_deserializer.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Manifest = _deserializer.Manifest;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _deserializer.Error;
}
}
}
private string GetDownloadRequestURL(string fileName)
{
// 轮流返回请求地址
if (_requestCount % 2 == 0)
return _fileSystem.RemoteServices.GetRemoteMainURL(fileName);
else
return _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2c2153284d246964fb2146f9fdda311c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,72 @@
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
internal sealed class LoadWebCatalogFileOperation : AsyncOperationBase
{
private enum ESteps
{
None,
LoadCatalog,
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private ESteps _steps = ESteps.None;
/// <summary>
/// 内置清单版本
/// </summary>
public string PackageVersion { private set; get; }
internal LoadWebCatalogFileOperation(DefaultWebFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
_steps = ESteps.LoadCatalog;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadCatalog)
{
string catalogFilePath = _fileSystem.GetCatalogFileLoadPath();
var catalog = Resources.Load<DefaultBuildinFileCatalog>(catalogFilePath);
if (catalog == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed to load catalog file : {catalogFilePath}";
return;
}
if (catalog.PackageName != _fileSystem.PackageName)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"The catalog file package name {catalog.PackageName} cannot match the file system package name {_fileSystem.PackageName}";
return;
}
PackageVersion = catalog.PackageVersion;
foreach (var wrapper in catalog.Wrappers)
{
var fileWrapper = new DefaultWebFileSystem.FileWrapper(wrapper.FileName);
_fileSystem.Record(wrapper.BundleGUID, fileWrapper);
}
YooLogger.Log($"Package '{_fileSystem.PackageName}' catalog files count : {catalog.Wrappers.Count}");
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4c34c01e10454c842819e066eef488cf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,109 @@
namespace YooAsset
{
internal class LoadWebPackageManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
RequestFileData,
VerifyFileData,
LoadManifest,
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly string _packageHash;
private UnityWebDataRequestOperation _webDataRequestOp;
private DeserializeManifestOperation _deserializer;
private ESteps _steps = ESteps.None;
/// <summary>
/// 加载的清单实例
/// </summary>
public PackageManifest Manifest { private set; get; }
internal LoadWebPackageManifestOperation(DefaultWebFileSystem fileSystem, string packageVersion, string packageHash)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;
_packageHash = packageHash;
}
internal override void InternalOnStart()
{
_steps = ESteps.RequestFileData;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestFileData)
{
if (_webDataRequestOp == null)
{
string filePath = _fileSystem.GetWebPackageManifestFilePath(_packageVersion);
string url = DownloadSystemHelper.ConvertToWWWPath(filePath);
_webDataRequestOp = new UnityWebDataRequestOperation(url);
OperationSystem.StartOperation(_fileSystem.PackageName, _webDataRequestOp);
}
if (_webDataRequestOp.IsDone == false)
return;
if (_webDataRequestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.VerifyFileData;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _webDataRequestOp.Error;
}
}
if (_steps == ESteps.VerifyFileData)
{
string fileHash = HashUtility.BytesMD5(_webDataRequestOp.Result);
if (fileHash == _packageHash)
{
_steps = ESteps.LoadManifest;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Failed to verify web package manifest file!";
}
}
if (_steps == ESteps.LoadManifest)
{
if (_deserializer == null)
{
_deserializer = new DeserializeManifestOperation(_webDataRequestOp.Result);
OperationSystem.StartOperation(_fileSystem.PackageName, _deserializer);
}
Progress = _deserializer.Progress;
if (_deserializer.IsDone == false)
return;
if (_deserializer.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Manifest = _deserializer.Manifest;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _deserializer.Error;
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 04a60c61990d93b4cb934ab1901a44f5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,90 @@
namespace YooAsset
{
internal class RequestRemotePackageHashOperation : AsyncOperationBase
{
private enum ESteps
{
None,
RequestPackageHash,
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly int _timeout;
private UnityWebTextRequestOperation _webTextRequestOp;
private int _requestCount = 0;
private ESteps _steps = ESteps.None;
/// <summary>
/// 包裹哈希值
/// </summary>
public string PackageHash { private set; get; }
public RequestRemotePackageHashOperation(DefaultWebFileSystem fileSystem, string packageVersion, int timeout)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(RequestRemotePackageHashOperation));
_steps = ESteps.RequestPackageHash;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestPackageHash)
{
if (_webTextRequestOp == null)
{
string fileName = YooAssetSettingsData.GetPackageHashFileName(_fileSystem.PackageName, _packageVersion);
string url = GetDownloadRequestURL(fileName);
_webTextRequestOp = new UnityWebTextRequestOperation(url, _timeout);
OperationSystem.StartOperation(_fileSystem.PackageName, _webTextRequestOp);
}
Progress = _webTextRequestOp.Progress;
if (_webTextRequestOp.IsDone == false)
return;
if (_webTextRequestOp.Status != EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _webTextRequestOp.Error;
WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(RequestRemotePackageHashOperation));
}
else
{
PackageHash = _webTextRequestOp.Result;
if (string.IsNullOrEmpty(PackageHash))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Remote package hash file content is empty !";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}
private string GetDownloadRequestURL(string fileName)
{
// 轮流返回请求地址
if (_requestCount % 2 == 0)
return _fileSystem.RemoteServices.GetRemoteMainURL(fileName);
else
return _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3f8269507a575884f935f9fbc71396ea
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,78 @@
namespace YooAsset
{
internal class RequestWebPackageHashOperation : AsyncOperationBase
{
private enum ESteps
{
None,
RequestPackageHash,
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly int _timeout;
private UnityWebTextRequestOperation _webTextRequestOp;
private ESteps _steps = ESteps.None;
/// <summary>
/// 包裹哈希值
/// </summary>
public string PackageHash { private set; get; }
public RequestWebPackageHashOperation(DefaultWebFileSystem fileSystem, string packageVersion, int timeout)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_steps = ESteps.RequestPackageHash;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestPackageHash)
{
if (_webTextRequestOp == null)
{
string filePath = _fileSystem.GetWebPackageHashFilePath(_packageVersion);
string url = DownloadSystemHelper.ConvertToWWWPath(filePath);
_webTextRequestOp = new UnityWebTextRequestOperation(url, _timeout);
OperationSystem.StartOperation(_fileSystem.PackageName, _webTextRequestOp);
}
Progress = _webTextRequestOp.Progress;
if (_webTextRequestOp.IsDone == false)
return;
if (_webTextRequestOp.Status != EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _webTextRequestOp.Error;
}
else
{
PackageHash = _webTextRequestOp.Result;
if (string.IsNullOrEmpty(PackageHash))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Web package hash file content is empty !";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ead93dc6c4d5ed942b209ec2202087dc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,75 @@
namespace YooAsset
{
internal class RequestWebPackageVersionOperation : AsyncOperationBase
{
private enum ESteps
{
None,
RequestPackageVersion,
Done,
}
private readonly DefaultWebFileSystem _fileSystem;
private readonly int _timeout;
private UnityWebTextRequestOperation _webTextRequestOp;
private ESteps _steps = ESteps.None;
/// <summary>
/// 包裹版本
/// </summary>
public string PackageVersion { private set; get; }
internal RequestWebPackageVersionOperation(DefaultWebFileSystem fileSystem, int timeout)
{
_fileSystem = fileSystem;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_steps = ESteps.RequestPackageVersion;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestPackageVersion)
{
if (_webTextRequestOp == null)
{
string filePath = _fileSystem.GetWebPackageVersionFilePath();
string url = DownloadSystemHelper.ConvertToWWWPath(filePath);
_webTextRequestOp = new UnityWebTextRequestOperation(url, _timeout);
OperationSystem.StartOperation(_fileSystem.PackageName, _webTextRequestOp);
}
if (_webTextRequestOp.IsDone == false)
return;
if (_webTextRequestOp.Status != EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _webTextRequestOp.Error;
}
else
{
PackageVersion = _webTextRequestOp.Result;
if (string.IsNullOrEmpty(PackageVersion))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Web package version file content is empty !";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bfa0e562b63f31141bbf04d4d5336d87
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: