diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskEncryption.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskEncryption.cs
index d430ae1c..7e9369d7 100644
--- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskEncryption.cs
+++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildPipeline/BaseTasks/TaskEncryption.cs
@@ -26,7 +26,7 @@ namespace YooAsset.Editor
{
EncryptFileInfo fileInfo = new EncryptFileInfo();
fileInfo.BundleName = bundleInfo.BundleName;
- fileInfo.FilePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
+ fileInfo.FileLoadPath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
var encryptResult = encryptionServices.Encrypt(fileInfo);
if (encryptResult.Encrypted)
{
diff --git a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs
index 089bec7d..70cd9770 100644
--- a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs
+++ b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs
@@ -189,7 +189,7 @@ namespace YooAsset.Editor
// Status
StyleColor textColor;
- if (bundleInfo.Status == BundleLoaderBase.EStatus.Failed.ToString())
+ if (bundleInfo.Status == BundleFileLoader.EStatus.Failed.ToString())
textColor = new StyleColor(Color.yellow);
else
textColor = label1.style.color;
diff --git a/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs b/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs
deleted file mode 100644
index 0830053d..00000000
--- a/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-
-namespace YooAsset
-{
- public class CacheFileInfo
- {
- public string RemoteFileName { private set; get; }
- public string FilePath { private set; get; }
- public string FileCRC { private set; get; }
- public long FileSize { private set; get; }
-
- public CacheFileInfo(string remoteFileName, string filePath, string fileCRC, long fileSize)
- {
- RemoteFileName = remoteFileName;
- FilePath = filePath;
- FileCRC = fileCRC;
- FileSize = fileSize;
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/CacheSystem/CacheHelper.cs b/Assets/YooAsset/Runtime/CacheSystem/CacheHelper.cs
deleted file mode 100644
index f99cb6e5..00000000
--- a/Assets/YooAsset/Runtime/CacheSystem/CacheHelper.cs
+++ /dev/null
@@ -1,132 +0,0 @@
-using System;
-using System.IO;
-
-namespace YooAsset
-{
- internal static class CacheHelper
- {
- ///
- /// 禁用Unity缓存系统在WebGL平台
- ///
- public static bool DisableUnityCacheOnWebGL = false;
-
- #region 资源信息文件相关
- private static readonly BufferWriter SharedBuffer = new BufferWriter(1024);
-
- ///
- /// 写入资源包信息
- ///
- public static void WriteInfoToFile(string filePath, string dataFileCRC, long dataFileSize)
- {
- using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read))
- {
- SharedBuffer.Clear();
- SharedBuffer.WriteUTF8(dataFileCRC);
- SharedBuffer.WriteInt64(dataFileSize);
- SharedBuffer.WriteToStream(fs);
- fs.Flush();
- }
- }
-
- ///
- /// 读取资源包信息
- ///
- public static void ReadInfoFromFile(string filePath, out string dataFileCRC, out long dataFileSize)
- {
- byte[] binaryData = FileUtility.ReadAllBytes(filePath);
- BufferReader buffer = new BufferReader(binaryData);
- dataFileCRC = buffer.ReadUTF8();
- dataFileSize = buffer.ReadInt64();
- }
- #endregion
-
- #region 资源文件验证相关
- ///
- /// 验证缓存文件(子线程内操作)
- ///
- public static EVerifyResult VerifyingCacheFile(VerifyCacheFileElement element, EVerifyLevel verifyLevel)
- {
- try
- {
- if (verifyLevel == EVerifyLevel.Low)
- {
- if (File.Exists(element.InfoFilePath) == false)
- return EVerifyResult.InfoFileNotExisted;
- if (File.Exists(element.DataFilePath) == false)
- return EVerifyResult.DataFileNotExisted;
- return EVerifyResult.Succeed;
- }
- else
- {
- if (File.Exists(element.InfoFilePath) == false)
- return EVerifyResult.InfoFileNotExisted;
-
- // 解析信息文件获取验证数据
- CacheHelper.ReadInfoFromFile(element.InfoFilePath, out element.DataFileCRC, out element.DataFileSize);
- }
- }
- catch (Exception)
- {
- return EVerifyResult.Exception;
- }
-
- return VerifyingInternal(element.DataFilePath, element.DataFileSize, element.DataFileCRC, verifyLevel);
- }
-
- ///
- /// 验证下载文件(子线程内操作)
- ///
- public static EVerifyResult VerifyingTempFile(VerifyTempFileElement element)
- {
- return VerifyingInternal(element.TempDataFilePath, element.FileSize, element.FileCRC, EVerifyLevel.High);
- }
-
- ///
- /// 验证记录文件(主线程内操作)
- ///
- public static EVerifyResult VerifyingRecordFile(CacheManager cache, string cacheGUID)
- {
- var wrapper = cache.TryGetWrapper(cacheGUID);
- if (wrapper == null)
- return EVerifyResult.CacheNotFound;
-
- EVerifyResult result = VerifyingInternal(wrapper.DataFilePath, wrapper.DataFileSize, wrapper.DataFileCRC, EVerifyLevel.High);
- return result;
- }
-
- private static EVerifyResult VerifyingInternal(string filePath, long fileSize, string fileCRC, EVerifyLevel verifyLevel)
- {
- try
- {
- if (File.Exists(filePath) == false)
- return EVerifyResult.DataFileNotExisted;
-
- // 先验证文件大小
- long size = FileUtility.GetFileSize(filePath);
- if (size < fileSize)
- return EVerifyResult.FileNotComplete;
- else if (size > fileSize)
- return EVerifyResult.FileOverflow;
-
- // 再验证文件CRC
- if (verifyLevel == EVerifyLevel.High)
- {
- string crc = HashUtility.FileCRC32Safely(filePath);
- if (crc == fileCRC)
- return EVerifyResult.Succeed;
- else
- return EVerifyResult.FileCrcError;
- }
- else
- {
- return EVerifyResult.Succeed;
- }
- }
- catch (Exception)
- {
- return EVerifyResult.Exception;
- }
- }
- #endregion
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/CacheSystem/CacheManager.cs b/Assets/YooAsset/Runtime/CacheSystem/CacheManager.cs
deleted file mode 100644
index 9b94fc28..00000000
--- a/Assets/YooAsset/Runtime/CacheSystem/CacheManager.cs
+++ /dev/null
@@ -1,136 +0,0 @@
-using System;
-using System.IO;
-using System.Collections;
-using System.Collections.Generic;
-
-namespace YooAsset
-{
- internal class CacheManager
- {
- internal class RecordWrapper
- {
- public string InfoFilePath { private set; get; }
- public string DataFilePath { private set; get; }
- public string DataFileCRC { private set; get; }
- public long DataFileSize { private set; get; }
-
- public RecordWrapper(string infoFilePath, string dataFilePath, string dataFileCRC, long dataFileSize)
- {
- InfoFilePath = infoFilePath;
- DataFilePath = dataFilePath;
- DataFileCRC = dataFileCRC;
- DataFileSize = dataFileSize;
- }
- }
-
- private readonly Dictionary _wrappers = new Dictionary();
-
- ///
- /// 所属包裹
- ///
- public readonly string PackageName;
-
- ///
- /// 验证级别
- ///
- public readonly EVerifyLevel BootVerifyLevel;
-
-
- public CacheManager(string packageName, EVerifyLevel bootVerifyLevel)
- {
- PackageName = packageName;
- BootVerifyLevel = bootVerifyLevel;
- }
-
- ///
- /// 清空所有数据
- ///
- public void ClearAll()
- {
- _wrappers.Clear();
- }
-
- ///
- /// 查询缓存记录
- ///
- public bool IsCached(string cacheGUID)
- {
- return _wrappers.ContainsKey(cacheGUID);
- }
-
- ///
- /// 记录验证结果
- ///
- public void Record(string cacheGUID, RecordWrapper wrapper)
- {
- if (_wrappers.ContainsKey(cacheGUID) == false)
- {
- _wrappers.Add(cacheGUID, wrapper);
- }
- else
- {
- throw new Exception("Should never get here !");
- }
- }
-
- ///
- /// 丢弃验证结果并删除缓存文件
- ///
- public void Discard(string cacheGUID)
- {
- var wrapper = TryGetWrapper(cacheGUID);
- if (wrapper != null)
- {
- try
- {
- string dataFilePath = wrapper.DataFilePath;
- FileInfo fileInfo = new FileInfo(dataFilePath);
- if (fileInfo.Exists)
- fileInfo.Directory.Delete(true);
- }
- catch (Exception e)
- {
- YooLogger.Error($"Failed to delete cache file ! {e.Message}");
- }
- }
-
- if (_wrappers.ContainsKey(cacheGUID))
- {
- _wrappers.Remove(cacheGUID);
- }
- }
-
- ///
- /// 获取记录对象
- ///
- public RecordWrapper TryGetWrapper(string cacheGUID)
- {
- if (_wrappers.TryGetValue(cacheGUID, out RecordWrapper value))
- return value;
- else
- return null;
- }
-
- ///
- /// 获取缓存文件总数
- ///
- public int GetAllCachedFilesCount()
- {
- return _wrappers.Count;
- }
-
- ///
- /// 获取缓存GUID集合
- ///
- public List GetAllCachedGUIDs()
- {
- List keys = new List(_wrappers.Keys.Count);
- var keyCollection = _wrappers.Keys;
- foreach (var key in keyCollection)
- {
- keys.Add(key);
- }
- return keys;
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs.meta
deleted file mode 100644
index 4060acc1..00000000
--- a/Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 65584a0568d40b14582a3c4aaf947b98
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearAllCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearAllCacheFilesOperation.cs.meta
deleted file mode 100644
index a16ec019..00000000
--- a/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearAllCacheFilesOperation.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 4eb0b0eafee709d478ab6d81faacb304
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearUnusedCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearUnusedCacheFilesOperation.cs.meta
deleted file mode 100644
index 41bfef3b..00000000
--- a/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearUnusedCacheFilesOperation.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 5d188c50fd00bf941b2eeebb374dc0d1
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/GetAllCacheFileInfosOperation.cs b/Assets/YooAsset/Runtime/CacheSystem/Operation/GetAllCacheFileInfosOperation.cs
deleted file mode 100644
index b256812b..00000000
--- a/Assets/YooAsset/Runtime/CacheSystem/Operation/GetAllCacheFileInfosOperation.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-using System;
-using System.IO;
-using System.Collections;
-using System.Collections.Generic;
-
-namespace YooAsset
-{
- public class GetAllCacheFileInfosOperation : AsyncOperationBase
- {
- private enum ESteps
- {
- None,
- TryLoadCacheManifest,
- GetCacheFileInfos,
- Done,
- }
-
- private readonly PersistentManager _persistent;
- private readonly CacheManager _cache;
- private readonly string _packageVersion;
- private LoadCacheManifestOperation _tryLoadCacheManifestOp;
- private PackageManifest _manifest;
- private ESteps _steps = ESteps.None;
-
- private List _cacheFileInfos;
-
- ///
- /// 搜索结果
- ///
- public List Result
- {
- get { return _cacheFileInfos; }
- }
-
-
- internal GetAllCacheFileInfosOperation(PersistentManager persistent, CacheManager cache, string packageVersion)
- {
- _persistent = persistent;
- _cache = cache;
- _packageVersion = packageVersion;
- }
- internal override void InternalOnStart()
- {
- _steps = ESteps.TryLoadCacheManifest;
- }
- internal override void InternalOnUpdate()
- {
- if (_steps == ESteps.None || _steps == ESteps.Done)
- return;
-
- if (_steps == ESteps.TryLoadCacheManifest)
- {
- if (_tryLoadCacheManifestOp == null)
- {
- _tryLoadCacheManifestOp = new LoadCacheManifestOperation(_persistent, _packageVersion);
- OperationSystem.StartOperation(_cache.PackageName, _tryLoadCacheManifestOp);
- }
-
- if (_tryLoadCacheManifestOp.IsDone == false)
- return;
-
- if (_tryLoadCacheManifestOp.Status == EOperationStatus.Succeed)
- {
- _manifest = _tryLoadCacheManifestOp.Manifest;
- _steps = ESteps.GetCacheFileInfos;
- }
- else
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Failed;
- Error = _tryLoadCacheManifestOp.Error;
- }
- }
-
- if (_steps == ESteps.GetCacheFileInfos)
- {
- var allCachedGUIDs = _cache.GetAllCachedGUIDs();
- _cacheFileInfos = new List(allCachedGUIDs.Count);
- for (int i = 0; i < allCachedGUIDs.Count; i++)
- {
- var cachedGUID = allCachedGUIDs[i];
- var wrapper = _cache.TryGetWrapper(cachedGUID);
- if (wrapper != null)
- {
- if (_manifest.TryGetPackageBundleByCacheGUID(cachedGUID, out var packageBundle))
- {
- var cacheFileInfo = new CacheFileInfo(packageBundle.FileName, wrapper.DataFilePath, wrapper.DataFileCRC, wrapper.DataFileSize);
- _cacheFileInfos.Add(cacheFileInfo);
- }
- }
- }
-
- // 注意:总是返回成功
- _steps = ESteps.Done;
- Status = EOperationStatus.Succeed;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/GetAllCacheFileInfosOperation.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/Operation/GetAllCacheFileInfosOperation.cs.meta
deleted file mode 100644
index d029471d..00000000
--- a/Assets/YooAsset/Runtime/CacheSystem/Operation/GetAllCacheFileInfosOperation.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: d37e37f5d78ddf8468adcf2dff1edfbb
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/FindCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/FindCacheFilesOperation.cs.meta
deleted file mode 100644
index 66a2d13a..00000000
--- a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/FindCacheFilesOperation.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 00ec004354d75ac499606d6959192f9b
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyCacheFilesOperation.cs b/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyCacheFilesOperation.cs
deleted file mode 100644
index ef46764f..00000000
--- a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyCacheFilesOperation.cs
+++ /dev/null
@@ -1,254 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.IO;
-using System.Threading;
-
-namespace YooAsset
-{
- internal abstract class VerifyCacheFilesOperation : AsyncOperationBase
- {
- public static VerifyCacheFilesOperation CreateOperation(CacheManager cache, List elements)
- {
-#if UNITY_WEBGL
- var operation = new VerifyCacheFilesWithoutThreadOperation(cache, elements);
-#else
- var operation = new VerifyCacheFilesWithThreadOperation(cache, elements);
-#endif
- return operation;
- }
- }
-
- ///
- /// 本地缓存文件验证(线程版)
- ///
- internal class VerifyCacheFilesWithThreadOperation : VerifyCacheFilesOperation
- {
- private enum ESteps
- {
- None,
- InitVerify,
- UpdateVerify,
- Done,
- }
-
- private readonly ThreadSyncContext _syncContext = new ThreadSyncContext();
- private readonly CacheManager _cache;
- private List _waitingList;
- private List _verifyingList;
- private int _verifyMaxNum;
- private int _verifyTotalCount;
- private float _verifyStartTime;
- private int _succeedCount;
- private int _failedCount;
- private ESteps _steps = ESteps.None;
-
- public VerifyCacheFilesWithThreadOperation(CacheManager cache, List elements)
- {
- _cache = cache;
- _waitingList = elements;
- }
- internal override void InternalOnStart()
- {
- _steps = ESteps.InitVerify;
- _verifyStartTime = UnityEngine.Time.realtimeSinceStartup;
- }
- internal override void InternalOnUpdate()
- {
- if (_steps == ESteps.None || _steps == ESteps.Done)
- return;
-
- if (_steps == ESteps.InitVerify)
- {
- int fileCount = _waitingList.Count;
-
- // 设置同时验证的最大数
- ThreadPool.GetMaxThreads(out int workerThreads, out int ioThreads);
- YooLogger.Log($"Work threads : {workerThreads}, IO threads : {ioThreads}");
- _verifyMaxNum = Math.Min(workerThreads, ioThreads);
- _verifyTotalCount = fileCount;
- if (_verifyMaxNum < 1)
- _verifyMaxNum = 1;
-
- _verifyingList = new List(_verifyMaxNum);
- _steps = ESteps.UpdateVerify;
- }
-
- if (_steps == ESteps.UpdateVerify)
- {
- _syncContext.Update();
-
- Progress = GetProgress();
- if (_waitingList.Count == 0 && _verifyingList.Count == 0)
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Succeed;
- float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime;
- YooLogger.Log($"Verify cache files elapsed time {costTime:f1} seconds");
- }
-
- for (int i = _waitingList.Count - 1; i >= 0; i--)
- {
- if (OperationSystem.IsBusy)
- break;
-
- if (_verifyingList.Count >= _verifyMaxNum)
- break;
-
- var element = _waitingList[i];
- if (BeginVerifyFileWithThread(element))
- {
- _waitingList.RemoveAt(i);
- _verifyingList.Add(element);
- }
- else
- {
- YooLogger.Warning("The thread pool is failed queued.");
- break;
- }
- }
- }
- }
-
- private float GetProgress()
- {
- if (_verifyTotalCount == 0)
- return 1f;
- return (float)(_succeedCount + _failedCount) / _verifyTotalCount;
- }
- private bool BeginVerifyFileWithThread(VerifyCacheFileElement element)
- {
- return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element);
- }
- private void VerifyInThread(object obj)
- {
- VerifyCacheFileElement element = (VerifyCacheFileElement)obj;
- element.Result = CacheHelper.VerifyingCacheFile(element, _cache.BootVerifyLevel);
- _syncContext.Post(VerifyCallback, element);
- }
- private void VerifyCallback(object obj)
- {
- VerifyCacheFileElement element = (VerifyCacheFileElement)obj;
- _verifyingList.Remove(element);
-
- if (element.Result == EVerifyResult.Succeed)
- {
- _succeedCount++;
- var wrapper = new CacheManager.RecordWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize);
- _cache.Record(element.CacheGUID, wrapper);
- }
- else
- {
- _failedCount++;
-
- YooLogger.Warning($"Failed verify file and delete files : {element.FileRootPath}");
- element.DeleteFiles();
- }
- }
- }
-
- ///
- /// 本地缓存文件验证(非线程版)
- ///
- internal class VerifyCacheFilesWithoutThreadOperation : VerifyCacheFilesOperation
- {
- private enum ESteps
- {
- None,
- InitVerify,
- UpdateVerify,
- Done,
- }
-
- private readonly CacheManager _cache;
- private List _waitingList;
- private List _verifyingList;
- private int _verifyMaxNum;
- private int _verifyTotalCount;
- private float _verifyStartTime;
- private int _succeedCount;
- private int _failedCount;
- private ESteps _steps = ESteps.None;
-
- public VerifyCacheFilesWithoutThreadOperation(CacheManager cache, List elements)
- {
- _cache = cache;
- _waitingList = elements;
- }
- internal override void InternalOnStart()
- {
- _steps = ESteps.InitVerify;
- _verifyStartTime = UnityEngine.Time.realtimeSinceStartup;
- }
- internal override void InternalOnUpdate()
- {
- if (_steps == ESteps.None || _steps == ESteps.Done)
- return;
-
- if (_steps == ESteps.InitVerify)
- {
- int fileCount = _waitingList.Count;
-
- // 设置同时验证的最大数
- _verifyMaxNum = fileCount;
- _verifyTotalCount = fileCount;
-
- _verifyingList = new List(_verifyMaxNum);
- _steps = ESteps.UpdateVerify;
- }
-
- if (_steps == ESteps.UpdateVerify)
- {
- Progress = GetProgress();
- if (_waitingList.Count == 0 && _verifyingList.Count == 0)
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Succeed;
- float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime;
- YooLogger.Log($"Package verify elapsed time {costTime:f1} seconds");
- }
-
- for (int i = _waitingList.Count - 1; i >= 0; i--)
- {
- if (OperationSystem.IsBusy)
- break;
-
- if (_verifyingList.Count >= _verifyMaxNum)
- break;
-
- var element = _waitingList[i];
- BeginVerifyFileWithoutThread(element);
- _waitingList.RemoveAt(i);
- _verifyingList.Add(element);
- }
-
- // 主线程内验证,可以清空列表
- _verifyingList.Clear();
- }
- }
-
- private float GetProgress()
- {
- if (_verifyTotalCount == 0)
- return 1f;
- return (float)(_succeedCount + _failedCount) / _verifyTotalCount;
- }
- private void BeginVerifyFileWithoutThread(VerifyCacheFileElement element)
- {
- element.Result = CacheHelper.VerifyingCacheFile(element, _cache.BootVerifyLevel);
- if (element.Result == EVerifyResult.Succeed)
- {
- _succeedCount++;
- var wrapper = new CacheManager.RecordWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize);
- _cache.Record(element.CacheGUID, wrapper);
- }
- else
- {
- _failedCount++;
-
- YooLogger.Warning($"Failed verify file and delete files : {element.FileRootPath}");
- element.DeleteFiles();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyTempFileOperation.cs b/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyTempFileOperation.cs
deleted file mode 100644
index 89ee8df9..00000000
--- a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyTempFileOperation.cs
+++ /dev/null
@@ -1,141 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.IO;
-using System.Threading;
-
-namespace YooAsset
-{
- internal abstract class VerifyTempFileOperation : AsyncOperationBase
- {
- public EVerifyResult VerifyResult { protected set; get; }
-
- public static VerifyTempFileOperation CreateOperation(VerifyTempFileElement element)
- {
-#if UNITY_WEBGL
- var operation = new VerifyTempFileWithoutThreadOperation(element);
-#else
- var operation = new VerifyTempFileWithThreadOperation(element);
-#endif
- return operation;
- }
- }
-
- ///
- /// 下载文件验证(线程版)
- ///
- internal class VerifyTempFileWithThreadOperation : VerifyTempFileOperation
- {
- private enum ESteps
- {
- None,
- VerifyFile,
- Waiting,
- Done,
- }
-
- private readonly VerifyTempFileElement _element;
- private ESteps _steps = ESteps.None;
-
- public VerifyTempFileWithThreadOperation(VerifyTempFileElement element)
- {
- _element = element;
- }
- internal override void InternalOnStart()
- {
- _steps = ESteps.VerifyFile;
- }
- internal override void InternalOnUpdate()
- {
- if (_steps == ESteps.None || _steps == ESteps.Done)
- return;
-
- if (_steps == ESteps.VerifyFile)
- {
- if (BeginVerifyFileWithThread(_element))
- {
- _steps = ESteps.Waiting;
- }
- }
-
- if (_steps == ESteps.Waiting)
- {
- int result = _element.Result;
- if (result == 0)
- return;
-
- VerifyResult = (EVerifyResult)result;
- if (VerifyResult == EVerifyResult.Succeed)
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Succeed;
- }
- else
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Failed;
- Error = $"Failed verify file : {_element.TempDataFilePath} ! ErrorCode : {VerifyResult}";
- }
- }
- }
-
- private bool BeginVerifyFileWithThread(VerifyTempFileElement element)
- {
- return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element);
- }
- private void VerifyInThread(object obj)
- {
- VerifyTempFileElement element = (VerifyTempFileElement)obj;
- int result = (int)CacheHelper.VerifyingTempFile(element);
- element.Result = result;
- }
- }
-
- ///
- /// 下载文件验证(非线程版)
- ///
- internal class VerifyTempFileWithoutThreadOperation : VerifyTempFileOperation
- {
- private enum ESteps
- {
- None,
- VerifyFile,
- Done,
- }
-
- private readonly VerifyTempFileElement _element;
- private ESteps _steps = ESteps.None;
-
- public VerifyTempFileWithoutThreadOperation(VerifyTempFileElement element)
- {
- _element = element;
- }
- internal override void InternalOnStart()
- {
- _steps = ESteps.VerifyFile;
- }
- internal override void InternalOnUpdate()
- {
- if (_steps == ESteps.None || _steps == ESteps.Done)
- return;
-
- if (_steps == ESteps.VerifyFile)
- {
- _element.Result = (int)CacheHelper.VerifyingTempFile(_element);
-
- VerifyResult = (EVerifyResult)_element.Result;
- if (VerifyResult == EVerifyResult.Succeed)
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Succeed;
- }
- else
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Failed;
- Error = $"Failed verify file : {_element.TempDataFilePath} ! ErrorCode : {VerifyResult}";
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/PackageCachingOperation.cs b/Assets/YooAsset/Runtime/CacheSystem/Operation/PackageCachingOperation.cs
deleted file mode 100644
index c8611bf5..00000000
--- a/Assets/YooAsset/Runtime/CacheSystem/Operation/PackageCachingOperation.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using System;
-using System.IO;
-using System.Collections;
-using System.Collections.Generic;
-
-namespace YooAsset
-{
- internal class PackageCachingOperation : AsyncOperationBase
- {
- private enum ESteps
- {
- None,
- FindCacheFiles,
- VerifyCacheFiles,
- Done,
- }
-
- private readonly PersistentManager _persistent;
- private readonly CacheManager _cache;
- private FindCacheFilesOperation _findCacheFilesOp;
- private VerifyCacheFilesOperation _verifyCacheFilesOp;
- private ESteps _steps = ESteps.None;
-
- public PackageCachingOperation(PersistentManager persistent, CacheManager cache)
- {
- _persistent = persistent;
- _cache = cache;
- }
- internal override void InternalOnStart()
- {
- _steps = ESteps.FindCacheFiles;
- }
- internal override void InternalOnUpdate()
- {
- if (_steps == ESteps.None || _steps == ESteps.Done)
- return;
-
- if (_steps == ESteps.FindCacheFiles)
- {
- if (_findCacheFilesOp == null)
- {
- _findCacheFilesOp = new FindCacheFilesOperation(_persistent, _cache);
- OperationSystem.StartOperation(_cache.PackageName, _findCacheFilesOp);
- }
-
- Progress = _findCacheFilesOp.Progress;
- if (_findCacheFilesOp.IsDone == false)
- return;
-
- _steps = ESteps.VerifyCacheFiles;
- }
-
- if (_steps == ESteps.VerifyCacheFiles)
- {
- if (_verifyCacheFilesOp == null)
- {
- _verifyCacheFilesOp = VerifyCacheFilesOperation.CreateOperation(_cache, _findCacheFilesOp.VerifyElements);
- OperationSystem.StartOperation(_cache.PackageName, _verifyCacheFilesOp);
- }
-
- Progress = _verifyCacheFilesOp.Progress;
- if (_verifyCacheFilesOp.IsDone == false)
- return;
-
- // 注意:总是返回成功
- _steps = ESteps.Done;
- Status = EOperationStatus.Succeed;
-
- int totalCount = _cache.GetAllCachedFilesCount();
- YooLogger.Log($"Package '{_cache.PackageName}' cached files count : {totalCount}");
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/PackageCachingOperation.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/Operation/PackageCachingOperation.cs.meta
deleted file mode 100644
index e7c542e6..00000000
--- a/Assets/YooAsset/Runtime/CacheSystem/Operation/PackageCachingOperation.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 4ff95e7516dbfa148b4fe16eaab783fb
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/CacheSystem/PersistentHelper.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/PersistentHelper.cs.meta
deleted file mode 100644
index fe3433d2..00000000
--- a/Assets/YooAsset/Runtime/CacheSystem/PersistentHelper.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 9581e7c53fe081749ab849ec6e2be3d6
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/CacheSystem/PersistentManager.cs b/Assets/YooAsset/Runtime/CacheSystem/PersistentManager.cs
deleted file mode 100644
index fc5f5eb0..00000000
--- a/Assets/YooAsset/Runtime/CacheSystem/PersistentManager.cs
+++ /dev/null
@@ -1,217 +0,0 @@
-using System;
-using System.IO;
-using System.Collections;
-using System.Collections.Generic;
-
-namespace YooAsset
-{
- internal class PersistentManager
- {
- private readonly Dictionary _cachedDataFilePaths = new Dictionary(10000);
- private readonly Dictionary _cachedInfoFilePaths = new Dictionary(10000);
- private readonly Dictionary _tempDataFilePaths = new Dictionary(10000);
- private readonly Dictionary _buildinFilePaths = new Dictionary(10000);
-
- ///
- /// 所属包裹
- ///
- public readonly string PackageName;
-
- public string BuildinRoot { private set; get; }
- public string BuildinPackageRoot { private set; get; }
-
- public string SandboxRoot { private set; get; }
- public string SandboxPackageRoot { private set; get; }
- public string SandboxCacheFilesRoot { private set; get; }
- public string SandboxManifestFilesRoot { private set; get; }
- public string SandboxAppFootPrintFilePath { private set; get; }
-
- public bool AppendFileExtension { private set; get; }
-
-
- public PersistentManager(string packageName)
- {
- PackageName = packageName;
- }
-
- ///
- /// 初始化
- ///
- public void Initialize(string buildinRoot, string sandboxRoot, bool appendFileExtension)
- {
- if (string.IsNullOrEmpty(buildinRoot))
- BuildinRoot = CreateDefaultBuildinRoot();
- else
- BuildinRoot = buildinRoot;
-
- if (string.IsNullOrEmpty(sandboxRoot))
- SandboxRoot = CreateDefaultSandboxRoot();
- else
- SandboxRoot = sandboxRoot;
-
- BuildinPackageRoot = PathUtility.Combine(BuildinRoot, PackageName);
- SandboxPackageRoot = PathUtility.Combine(SandboxRoot, PackageName);
- SandboxCacheFilesRoot = PathUtility.Combine(SandboxPackageRoot, YooAssetSettings.CacheFilesFolderName);
- SandboxManifestFilesRoot = PathUtility.Combine(SandboxPackageRoot, YooAssetSettings.ManifestFolderName);
- SandboxAppFootPrintFilePath = PathUtility.Combine(SandboxPackageRoot, YooAssetSettings.AppFootPrintFileName);
- AppendFileExtension = appendFileExtension;
- }
- private static string CreateDefaultBuildinRoot()
- {
- string path = PathUtility.Combine(UnityEngine.Application.streamingAssetsPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
-#if UNITY_OPENHARMONY
- return $"file://{path}";
-#else
- return path;
-#endif
- }
- private static string CreateDefaultSandboxRoot()
- {
-#if UNITY_EDITOR
- // 注意:为了方便调试查看,编辑器下把存储目录放到项目里。
- string projectPath = Path.GetDirectoryName(UnityEngine.Application.dataPath);
- projectPath = PathUtility.RegularPath(projectPath);
- return PathUtility.Combine(projectPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
-#elif UNITY_STANDALONE
- return PathUtility.Combine(UnityEngine.Application.dataPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
-#else
- return PathUtility.Combine(UnityEngine.Application.persistentDataPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
-#endif
- }
-
- public string GetCachedDataFilePath(PackageBundle bundle)
- {
- if (_cachedDataFilePaths.TryGetValue(bundle.CacheGUID, out string filePath) == false)
- {
- string folderName = bundle.FileHash.Substring(0, 2);
- filePath = PathUtility.Combine(SandboxCacheFilesRoot, folderName, bundle.CacheGUID, YooAssetSettings.CacheBundleDataFileName);
- if (AppendFileExtension)
- filePath += bundle.FileExtension;
- _cachedDataFilePaths.Add(bundle.CacheGUID, filePath);
- }
- return filePath;
- }
- public string GetCachedInfoFilePath(PackageBundle bundle)
- {
- if (_cachedInfoFilePaths.TryGetValue(bundle.CacheGUID, out string filePath) == false)
- {
- string folderName = bundle.FileHash.Substring(0, 2);
- filePath = PathUtility.Combine(SandboxCacheFilesRoot, folderName, bundle.CacheGUID, YooAssetSettings.CacheBundleInfoFileName);
- _cachedInfoFilePaths.Add(bundle.CacheGUID, filePath);
- }
- return filePath;
- }
- public string GetTempDataFilePath(PackageBundle bundle)
- {
- if (_tempDataFilePaths.TryGetValue(bundle.CacheGUID, out string filePath) == false)
- {
- string cachedDataFilePath = GetCachedDataFilePath(bundle);
- filePath = $"{cachedDataFilePath}.temp";
- _tempDataFilePaths.Add(bundle.CacheGUID, filePath);
- }
- return filePath;
- }
- public string GetBuildinFilePath(PackageBundle bundle)
- {
- if (_buildinFilePaths.TryGetValue(bundle.CacheGUID, out string filePath) == false)
- {
- filePath = PathUtility.Combine(BuildinPackageRoot, bundle.FileName);
- _buildinFilePaths.Add(bundle.CacheGUID, filePath);
- }
- return filePath;
- }
-
- ///
- /// 删除沙盒里的包裹目录
- ///
- public void DeleteSandboxPackageFolder()
- {
- if (Directory.Exists(SandboxPackageRoot))
- Directory.Delete(SandboxPackageRoot, true);
- }
-
- ///
- /// 删除沙盒内的缓存文件夹
- ///
- public void DeleteSandboxCacheFilesFolder()
- {
- if (Directory.Exists(SandboxCacheFilesRoot))
- Directory.Delete(SandboxCacheFilesRoot, true);
- }
-
- ///
- /// 删除沙盒内的清单文件夹
- ///
- public void DeleteSandboxManifestFilesFolder()
- {
- if (Directory.Exists(SandboxManifestFilesRoot))
- Directory.Delete(SandboxManifestFilesRoot, true);
- }
-
-
- ///
- /// 获取沙盒内包裹的清单文件的路径
- ///
- public string GetSandboxPackageManifestFilePath(string packageVersion)
- {
- string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion);
- return PathUtility.Combine(SandboxManifestFilesRoot, fileName);
- }
-
- ///
- /// 获取沙盒内包裹的哈希文件的路径
- ///
- public string GetSandboxPackageHashFilePath(string packageVersion)
- {
- string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion);
- return PathUtility.Combine(SandboxManifestFilesRoot, fileName);
- }
-
- ///
- /// 获取沙盒内包裹的版本文件的路径
- ///
- public string GetSandboxPackageVersionFilePath()
- {
- string fileName = YooAssetSettingsData.GetPackageVersionFileName(PackageName);
- return PathUtility.Combine(SandboxManifestFilesRoot, fileName);
- }
-
- ///
- /// 保存沙盒内默认的包裹版本
- ///
- public void SaveSandboxPackageVersionFile(string version)
- {
- YooLogger.Log($"Save package version : {version}");
- string filePath = GetSandboxPackageVersionFilePath();
- FileUtility.WriteAllText(filePath, version);
- }
-
-
- ///
- /// 获取APP内包裹的清单文件的路径
- ///
- public string GetBuildinPackageManifestFilePath(string packageVersion)
- {
- string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion);
- return PathUtility.Combine(BuildinPackageRoot, fileName);
- }
-
- ///
- /// 获取APP内包裹的哈希文件的路径
- ///
- public string GetBuildinPackageHashFilePath(string packageVersion)
- {
- string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion);
- return PathUtility.Combine(BuildinPackageRoot, fileName);
- }
-
- ///
- /// 获取APP内包裹的版本文件的路径
- ///
- public string GetBuildinPackageVersionFilePath()
- {
- string fileName = YooAssetSettingsData.GetPackageVersionFileName(PackageName);
- return PathUtility.Combine(BuildinPackageRoot, fileName);
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/CacheSystem/PersistentManager.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/PersistentManager.cs.meta
deleted file mode 100644
index 0ba0c6d8..00000000
--- a/Assets/YooAsset/Runtime/CacheSystem/PersistentManager.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 62ee5fd2821fe85488efff3f8242b703
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs b/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs
deleted file mode 100644
index c8cbb461..00000000
--- a/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using System.IO;
-
-namespace YooAsset
-{
- ///
- /// 缓存文件验证元素
- ///
- internal class VerifyCacheFileElement
- {
- public string PackageName { private set; get; }
- public string CacheGUID { private set; get; }
- public string FileRootPath { private set; get; }
- public string DataFilePath { private set; get; }
- public string InfoFilePath { private set; get; }
-
- public EVerifyResult Result;
- public string DataFileCRC;
- public long DataFileSize;
-
- public VerifyCacheFileElement(string packageName, string cacheGUID, string fileRootPath, string dataFilePath, string infoFilePath)
- {
- PackageName = packageName;
- CacheGUID = cacheGUID;
- FileRootPath = fileRootPath;
- DataFilePath = dataFilePath;
- InfoFilePath = infoFilePath;
- }
-
- public void DeleteFiles()
- {
- try
- {
- Directory.Delete(FileRootPath, true);
- }
- catch (System.Exception e)
- {
- YooLogger.Warning($"Failed delete cache bundle folder : {e}");
- }
- }
- }
-
- ///
- /// 下载文件验证元素
- ///
- internal class VerifyTempFileElement
- {
- public string TempDataFilePath { private set; get; }
- public string FileCRC { private set; get; }
- public long FileSize { private set; get; }
-
- public int Result = 0; // 注意:原子操作对象
-
- public VerifyTempFileElement(string tempDataFilePath, string fileCRC, long fileSize)
- {
- TempDataFilePath = tempDataFilePath;
- FileCRC = fileCRC;
- FileSize = fileSize;
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs.meta b/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs.meta
deleted file mode 100644
index 8cb15ad2..00000000
--- a/Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 5a4b96484bd701f4289b2f74c38abaa8
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadHelper.cs b/Assets/YooAsset/Runtime/DownloadSystem/DownloadHelper.cs
deleted file mode 100644
index 458529f1..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/DownloadHelper.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System;
-using System.IO;
-using System.Collections;
-using System.Collections.Generic;
-using System.Threading;
-using UnityEngine.Networking;
-
-namespace YooAsset
-{
- ///
- /// 自定义下载器的请求委托
- ///
- public delegate UnityWebRequest DownloadRequestDelegate(string url);
-
-
- internal static class DownloadHelper
- {
- ///
- /// 下载失败后清理文件的HTTP错误码
- ///
- public static List ClearFileResponseCodes { set; get; }
-
- ///
- /// 自定义下载器的请求委托
- ///
- public static DownloadRequestDelegate RequestDelegate = null;
-
- ///
- /// 创建一个新的网络请求
- ///
- public static UnityWebRequest NewRequest(string requestURL)
- {
- UnityWebRequest webRequest;
- if (RequestDelegate != null)
- webRequest = RequestDelegate.Invoke(requestURL);
- else
- webRequest = new UnityWebRequest(requestURL, UnityWebRequest.kHttpVerbGET);
- return webRequest;
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadHelper.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/DownloadHelper.cs.meta
deleted file mode 100644
index 8b9112e2..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/DownloadHelper.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: d19eae1f43ecf6347925a06730a6c846
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadManager.cs b/Assets/YooAsset/Runtime/DownloadSystem/DownloadManager.cs
deleted file mode 100644
index 84993376..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/DownloadManager.cs
+++ /dev/null
@@ -1,150 +0,0 @@
-using System;
-using System.IO;
-using System.Collections;
-using System.Collections.Generic;
-using UnityEngine.Networking;
-
-namespace YooAsset
-{
- ///
- /// 1. 保证每一时刻资源文件只存在一个下载器
- /// 2. 保证下载器下载完成后立刻验证并缓存
- /// 3. 保证资源文件不会被重复下载
- ///
- internal class DownloadManager
- {
- private readonly Dictionary _downloaders = new Dictionary(1000);
- private readonly List _removeList = new List(1000);
-
- private uint _breakpointResumeFileSize;
-
- ///
- /// 所属包裹
- ///
- public readonly string PackageName;
-
-
- public DownloadManager(string packageName)
- {
- PackageName = packageName;
- }
-
- ///
- /// 初始化
- ///
- public void Initialize(uint breakpointResumeFileSize)
- {
- _breakpointResumeFileSize = breakpointResumeFileSize;
- }
-
- ///
- /// 更新下载器
- ///
- public void Update()
- {
- // 更新下载器
- _removeList.Clear();
- foreach (var valuePair in _downloaders)
- {
- var downloader = valuePair.Value;
- downloader.Update();
- if (downloader.IsDone())
- {
- _removeList.Add(valuePair.Key);
- }
- }
-
- // 移除下载器
- foreach (var key in _removeList)
- {
- _downloaders.Remove(key);
- }
- }
-
- ///
- /// 销毁所有下载器
- ///
- public void DestroyAll()
- {
- foreach (var valuePair in _downloaders)
- {
- var downloader = valuePair.Value;
- downloader.Abort();
- }
-
- _downloaders.Clear();
- _removeList.Clear();
- }
-
- ///
- /// 创建下载器
- /// 注意:只有第一次请求的参数才有效
- ///
- public DownloaderBase CreateDownload(BundleInfo bundleInfo, int failedTryAgain, int timeout = 60)
- {
- // 查询存在的下载器
- if (_downloaders.TryGetValue(bundleInfo.CachedDataFilePath, out var downloader))
- {
- downloader.Reference();
- return downloader;
- }
-
- // 如果资源已经缓存
- if (bundleInfo.IsCached())
- {
- var completedDownloader = new CompletedDownloader(bundleInfo);
- return completedDownloader;
- }
-
- // 创建新的下载器
- DownloaderBase newDownloader = null;
- YooLogger.Log($"Beginning to download bundle : {bundleInfo.Bundle.BundleName} URL : {bundleInfo.RemoteMainURL}");
-#if UNITY_WEBGL
- if (bundleInfo.Bundle.Buildpipeline == EDefaultBuildPipeline.RawFileBuildPipeline.ToString())
- {
- FileUtility.CreateFileDirectory(bundleInfo.CachedDataFilePath);
- System.Type requesterType = typeof(FileGeneralRequest);
- newDownloader = new FileDownloader(bundleInfo, requesterType, failedTryAgain, timeout);
- }
- else
- {
- System.Type requesterType = typeof(AssetBundleWebRequest);
- newDownloader = new WebDownloader(bundleInfo, requesterType, failedTryAgain, timeout);
- }
-#else
- FileUtility.CreateFileDirectory(bundleInfo.CachedDataFilePath);
- bool resumeDownload = bundleInfo.Bundle.FileSize >= _breakpointResumeFileSize;
- if (resumeDownload)
- {
- System.Type requesterType = typeof(FileResumeRequest);
- newDownloader = new FileDownloader(bundleInfo, requesterType, failedTryAgain, timeout);
- }
- else
- {
- System.Type requesterType = typeof(FileGeneralRequest);
- newDownloader = new FileDownloader(bundleInfo, requesterType, failedTryAgain, timeout);
- }
-#endif
-
- // 返回新创建的下载器
- _downloaders.Add(bundleInfo.CachedDataFilePath, newDownloader);
- newDownloader.Reference();
- return newDownloader;
- }
-
- ///
- /// 停止不再使用的下载器
- ///
- public void AbortUnusedDownloader()
- {
- foreach (var valuePair in _downloaders)
- {
- var downloader = valuePair.Value;
- if (downloader.RefCount <= 0)
- {
- downloader.Abort();
- }
- }
- }
- }
-}
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadManager.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/DownloadManager.cs.meta
deleted file mode 100644
index dceffc05..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/DownloadManager.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 6fbbbfe01e018b241bf33469f870a4b8
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/CacheSystem/PersistentHelper.cs b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemHelper.cs
similarity index 54%
rename from Assets/YooAsset/Runtime/CacheSystem/PersistentHelper.cs
rename to Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemHelper.cs
index dd757a4f..736ec55c 100644
--- a/Assets/YooAsset/Runtime/CacheSystem/PersistentHelper.cs
+++ b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemHelper.cs
@@ -1,8 +1,25 @@
-
+using UnityEngine.Networking;
+
namespace YooAsset
{
- internal static class PersistentHelper
+ ///
+ /// 自定义下载器的请求委托
+ ///
+ public delegate UnityWebRequest UnityWebRequestDelegate(string url);
+
+ internal class DownloadSystemHelper
{
+ public static UnityWebRequestDelegate UnityWebRequestCreater = null;
+ public static UnityWebRequest NewUnityWebRequestGet(string requestURL)
+ {
+ UnityWebRequest webRequest;
+ if (UnityWebRequestCreater != null)
+ webRequest = UnityWebRequestCreater.Invoke(requestURL);
+ else
+ webRequest = new UnityWebRequest(requestURL, UnityWebRequest.kHttpVerbGET);
+ return webRequest;
+ }
+
///
/// 获取WWW加载本地资源的路径
///
diff --git a/Assets/YooAsset/Runtime/CacheSystem/EVerifyLevel.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemHelper.cs.meta
similarity index 83%
rename from Assets/YooAsset/Runtime/CacheSystem/EVerifyLevel.cs.meta
rename to Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemHelper.cs.meta
index 26f29bbc..03e266c3 100644
--- a/Assets/YooAsset/Runtime/CacheSystem/EVerifyLevel.cs.meta
+++ b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystemHelper.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 02ad351eb8539da47a0c789e2f8c468f
+guid: 5bacfa8c42e283a45a2d21cbb93d6e5d
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/CompletedDownloader.cs b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/CompletedDownloader.cs
deleted file mode 100644
index 44954096..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/CompletedDownloader.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using UnityEngine;
-
-namespace YooAsset
-{
- internal sealed class CompletedDownloader : DownloaderBase
- {
- public CompletedDownloader(BundleInfo bundleInfo) : base(bundleInfo, null, 0, 0)
- {
- DownloadProgress = 1f;
- DownloadedBytes = (ulong)bundleInfo.Bundle.FileSize;
- _status = EStatus.Succeed;
- }
-
- public override void SendRequest(params object[] param)
- {
- }
- public override void Update()
- {
- }
- public override void Abort()
- {
- }
- public override AssetBundle GetAssetBundle()
- {
- throw new System.NotImplementedException();
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/CompletedDownloader.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/CompletedDownloader.cs.meta
deleted file mode 100644
index a225b15f..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/CompletedDownloader.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 3c7907ead85e2f94786308b28c37a8aa
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs
deleted file mode 100644
index df531d5b..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs
+++ /dev/null
@@ -1,182 +0,0 @@
-using System;
-using UnityEngine;
-using UnityEngine.Networking;
-
-namespace YooAsset
-{
- internal abstract class DownloaderBase
- {
- public enum EStatus
- {
- None = 0,
- Succeed,
- Failed
- }
-
- protected readonly BundleInfo _bundleInfo;
- protected readonly System.Type _requesterType;
- protected readonly int _timeout;
- protected int _failedTryAgain;
-
- protected IWebRequester _requester;
- protected EStatus _status = EStatus.None;
- protected string _lastestNetError = string.Empty;
- protected long _lastestHttpCode = 0;
-
- // 请求次数
- protected int _requestCount = 0;
- protected string _requestURL;
-
- // 超时相关
- protected bool _isAbort = false;
- protected ulong _latestDownloadBytes;
- protected float _latestDownloadRealtime;
- protected float _tryAgainTimer;
-
- ///
- /// 是否等待异步结束
- /// 警告:只能用于解压APP内部资源
- ///
- public bool WaitForAsyncComplete = false;
-
- ///
- /// 下载进度(0f~1f)
- ///
- public float DownloadProgress { protected set; get; }
-
- ///
- /// 已经下载的总字节数
- ///
- public ulong DownloadedBytes { protected set; get; }
-
- ///
- /// 引用计数
- ///
- public int RefCount { private set; get; }
-
-
- public DownloaderBase(BundleInfo bundleInfo, System.Type requesterType, int failedTryAgain, int timeout)
- {
- _bundleInfo = bundleInfo;
- _requesterType = requesterType;
- _failedTryAgain = failedTryAgain;
- _timeout = timeout;
- }
- public abstract void SendRequest(params object[] args);
- public abstract void Update();
- public abstract void Abort();
- public abstract AssetBundle GetAssetBundle();
-
- ///
- /// 引用(引用计数递加)
- ///
- public void Reference()
- {
- RefCount++;
- }
-
- ///
- /// 释放(引用计数递减)
- ///
- public void Release()
- {
- RefCount--;
- }
-
- ///
- /// 检测下载器是否已经完成(无论成功或失败)
- ///
- public bool IsDone()
- {
- return _status == EStatus.Succeed || _status == EStatus.Failed;
- }
-
- ///
- /// 下载过程是否发生错误
- ///
- public bool HasError()
- {
- return _status == EStatus.Failed;
- }
-
- ///
- /// 按照错误级别打印错误
- ///
- public void ReportError()
- {
- YooLogger.Error(GetLastError());
- }
-
- ///
- /// 按照警告级别打印错误
- ///
- public void ReportWarning()
- {
- YooLogger.Warning(GetLastError());
- }
-
- ///
- /// 获取最近发生的错误信息
- ///
- public string GetLastError()
- {
- return $"Failed to download : {_requestURL} Error : {_lastestNetError} Code : {_lastestHttpCode}";
- }
-
- ///
- /// 获取下载文件的大小
- ///
- ///
- public long GetDownloadFileSize()
- {
- return _bundleInfo.Bundle.FileSize;
- }
-
- ///
- /// 获取下载的资源包名称
- ///
- public string GetDownloadBundleName()
- {
- return _bundleInfo.Bundle.BundleName;
- }
-
-
- ///
- /// 获取网络请求地址
- ///
- protected string GetRequestURL()
- {
- // 轮流返回请求地址
- _requestCount++;
- if (_requestCount % 2 == 0)
- return _bundleInfo.RemoteFallbackURL;
- else
- return _bundleInfo.RemoteMainURL;
- }
-
- ///
- /// 超时判定方法
- ///
- protected void CheckTimeout()
- {
- // 注意:在连续时间段内无新增下载数据及判定为超时
- if (_isAbort == false)
- {
- if (_latestDownloadBytes != DownloadedBytes)
- {
- _latestDownloadBytes = DownloadedBytes;
- _latestDownloadRealtime = Time.realtimeSinceStartup;
- }
-
- float offset = Time.realtimeSinceStartup - _latestDownloadRealtime;
- if (offset > _timeout)
- {
- YooLogger.Warning($"Web file request timeout : {_requestURL}");
- if (_requester != null)
- _requester.Abort();
- _isAbort = true;
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs.meta
deleted file mode 100644
index 0a530878..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: dda4d1eafa2c9f34fade509f8dae9c04
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs
deleted file mode 100644
index c84f2653..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs
+++ /dev/null
@@ -1,216 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.IO;
-using UnityEngine;
-
-namespace YooAsset
-{
- ///
- /// 文件下载器
- ///
- internal sealed class FileDownloader : DownloaderBase
- {
- private enum ESteps
- {
- None,
- PrepareDownload,
- CreateDownloader,
- CheckDownload,
- VerifyTempFile,
- WaitingVerifyTempFile,
- CachingFile,
- TryAgain,
- Done,
- }
-
- private VerifyTempFileOperation _verifyFileOp = null;
- private ESteps _steps = ESteps.None;
-
- public FileDownloader(BundleInfo bundleInfo, System.Type requesterType, int failedTryAgain, int timeout) : base(bundleInfo, requesterType, failedTryAgain, timeout)
- {
- }
- public override void SendRequest(params object[] args)
- {
- if (_steps == ESteps.None)
- {
- _steps = ESteps.PrepareDownload;
- }
- }
- public override void Update()
- {
- if (_steps == ESteps.None)
- return;
- if (IsDone())
- return;
-
- // 准备下载
- if (_steps == ESteps.PrepareDownload)
- {
- // 获取请求地址
- _requestURL = GetRequestURL();
-
- // 重置变量
- DownloadProgress = 0f;
- DownloadedBytes = 0;
-
- // 重置变量
- _isAbort = false;
- _latestDownloadBytes = 0;
- _latestDownloadRealtime = Time.realtimeSinceStartup;
-
- // 重置计时器
- if (_tryAgainTimer > 0f)
- YooLogger.Warning($"Try again download : {_requestURL}");
- _tryAgainTimer = 0f;
-
- _steps = ESteps.CreateDownloader;
- }
-
- // 创建下载器
- if (_steps == ESteps.CreateDownloader)
- {
- _requester = (IWebRequester)Activator.CreateInstance(_requesterType);
- _requester.Create(_requestURL, _bundleInfo);
- _steps = ESteps.CheckDownload;
- }
-
- // 检测下载结果
- if (_steps == ESteps.CheckDownload)
- {
- _requester.Update();
- DownloadedBytes = _requester.DownloadedBytes;
- DownloadProgress = _requester.DownloadProgress;
- if (_requester.IsDone() == false)
- {
- CheckTimeout();
- return;
- }
-
- _lastestNetError = _requester.RequestNetError;
- _lastestHttpCode = _requester.RequestHttpCode;
- if (_requester.Status != ERequestStatus.Success)
- {
- _steps = ESteps.TryAgain;
- }
- else
- {
- _steps = ESteps.VerifyTempFile;
- }
- }
-
- // 验证下载文件
- if (_steps == ESteps.VerifyTempFile)
- {
- VerifyTempFileElement element = new VerifyTempFileElement(_bundleInfo.TempDataFilePath, _bundleInfo.Bundle.FileCRC, _bundleInfo.Bundle.FileSize);
- _verifyFileOp = VerifyTempFileOperation.CreateOperation(element);
- OperationSystem.StartOperation(_bundleInfo.Bundle.PackageName, _verifyFileOp);
- _steps = ESteps.WaitingVerifyTempFile;
- }
-
- // 等待验证完成
- if (_steps == ESteps.WaitingVerifyTempFile)
- {
- if (WaitForAsyncComplete)
- _verifyFileOp.InternalOnUpdate();
-
- if (_verifyFileOp.IsDone == false)
- return;
-
- if (_verifyFileOp.Status == EOperationStatus.Succeed)
- {
- _steps = ESteps.CachingFile;
- }
- else
- {
- string tempFilePath = _bundleInfo.TempDataFilePath;
- if (File.Exists(tempFilePath))
- File.Delete(tempFilePath);
-
- _lastestNetError = _verifyFileOp.Error;
- _steps = ESteps.TryAgain;
- }
- }
-
- // 缓存下载文件
- if (_steps == ESteps.CachingFile)
- {
- try
- {
- CachingFile();
- _status = EStatus.Succeed;
- _steps = ESteps.Done;
- }
- catch (Exception e)
- {
- _lastestNetError = e.Message;
- _steps = ESteps.TryAgain;
- }
- }
-
- // 重新尝试下载
- if (_steps == ESteps.TryAgain)
- {
- if (_failedTryAgain <= 0)
- {
- ReportError();
- _status = EStatus.Failed;
- _steps = ESteps.Done;
- return;
- }
-
- _tryAgainTimer += Time.unscaledDeltaTime;
- if (_tryAgainTimer > 1f)
- {
- _failedTryAgain--;
- _steps = ESteps.PrepareDownload;
- ReportWarning();
- }
- }
- }
- public override void Abort()
- {
- if (_requester != null)
- _requester.Abort();
-
- if (IsDone() == false)
- {
- _status = EStatus.Failed;
- _steps = ESteps.Done;
- _lastestNetError = "user abort";
- _lastestHttpCode = 0;
- }
- }
- public override AssetBundle GetAssetBundle()
- {
- throw new NotImplementedException();
- }
-
- ///
- /// 缓存下载文件
- ///
- private void CachingFile()
- {
- string tempFilePath = _bundleInfo.TempDataFilePath;
- string infoFilePath = _bundleInfo.CachedInfoFilePath;
- string dataFilePath = _bundleInfo.CachedDataFilePath;
- string dataFileCRC = _bundleInfo.Bundle.FileCRC;
- long dataFileSize = _bundleInfo.Bundle.FileSize;
-
- if (File.Exists(infoFilePath))
- File.Delete(infoFilePath);
- if (File.Exists(dataFilePath))
- File.Delete(dataFilePath);
-
- // 移动临时文件路径
- FileInfo fileInfo = new FileInfo(tempFilePath);
- fileInfo.MoveTo(dataFilePath);
-
- // 写入信息文件记录验证数据
- CacheHelper.WriteInfoToFile(infoFilePath, dataFileCRC, dataFileSize);
-
- // 记录缓存文件
- _bundleInfo.CacheRecord();
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs.meta
deleted file mode 100644
index 54386037..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 4c6e1a8bc8d5e664395395daa772ddd7
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/WebDownloader.cs b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/WebDownloader.cs
deleted file mode 100644
index 83ac7e5d..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/WebDownloader.cs
+++ /dev/null
@@ -1,140 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.IO;
-using UnityEngine;
-
-namespace YooAsset
-{
- internal sealed class WebDownloader : DownloaderBase
- {
- private enum ESteps
- {
- None,
- PrepareDownload,
- CreateDownloader,
- CheckDownload,
- TryAgain,
- Done,
- }
-
- private ESteps _steps = ESteps.None;
- private bool _getAssetBundle = false;
-
- public WebDownloader(BundleInfo bundleInfo, System.Type requesterType, int failedTryAgain, int timeout) : base(bundleInfo, requesterType, failedTryAgain, timeout)
- {
- }
- public override void SendRequest(params object[] args)
- {
- if (_steps == ESteps.None)
- {
- if (args.Length > 0)
- {
- _getAssetBundle = (bool)args[0];
- }
- _steps = ESteps.PrepareDownload;
- }
- }
- public override void Update()
- {
- if (_steps == ESteps.None)
- return;
- if (IsDone())
- return;
-
- // 创建下载器
- if (_steps == ESteps.PrepareDownload)
- {
- // 获取请求地址
- _requestURL = GetRequestURL();
-
- // 重置变量
- DownloadProgress = 0f;
- DownloadedBytes = 0;
-
- // 重置变量
- _isAbort = false;
- _latestDownloadBytes = 0;
- _latestDownloadRealtime = Time.realtimeSinceStartup;
-
- // 重置计时器
- if (_tryAgainTimer > 0f)
- YooLogger.Warning($"Try again download : {_requestURL}");
- _tryAgainTimer = 0f;
-
- _steps = ESteps.CreateDownloader;
- }
-
- // 创建下载器
- if (_steps == ESteps.CreateDownloader)
- {
- _requester = (IWebRequester)Activator.CreateInstance(_requesterType);
- _requester.Create(_requestURL, _bundleInfo, _getAssetBundle);
- _steps = ESteps.CheckDownload;
- }
-
- // 检测下载结果
- if (_steps == ESteps.CheckDownload)
- {
- _requester.Update();
- DownloadedBytes = _requester.DownloadedBytes;
- DownloadProgress = _requester.DownloadProgress;
- if (_requester.IsDone() == false)
- {
- CheckTimeout();
- return;
- }
-
- _lastestNetError = _requester.RequestNetError;
- _lastestHttpCode = _requester.RequestHttpCode;
- if (_requester.Status != ERequestStatus.Success)
- {
- _steps = ESteps.TryAgain;
- }
- else
- {
- _status = EStatus.Succeed;
- _steps = ESteps.Done;
- }
- }
-
- // 重新尝试下载
- if (_steps == ESteps.TryAgain)
- {
- if (_failedTryAgain <= 0)
- {
- ReportError();
- _status = EStatus.Failed;
- _steps = ESteps.Done;
- return;
- }
-
- _tryAgainTimer += Time.unscaledDeltaTime;
- if (_tryAgainTimer > 1f)
- {
- _failedTryAgain--;
- _steps = ESteps.PrepareDownload;
- ReportWarning();
- YooLogger.Warning($"Try again download : {_requestURL}");
- }
- }
- }
- public override void Abort()
- {
- if (_requester != null)
- _requester.Abort();
-
- if (IsDone() == false)
- {
- _status = EStatus.Failed;
- _steps = ESteps.Done;
- _lastestNetError = "user abort";
- _lastestHttpCode = 0;
- }
- }
- public override AssetBundle GetAssetBundle()
- {
- return (AssetBundle)_requester.GetRequestObject();
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/WebDownloader.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/WebDownloader.cs.meta
deleted file mode 100644
index 690ea8f1..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/WebDownloader.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 41bc4bc56f59ddb4b8925f9536bbbfbc
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation.meta b/Assets/YooAsset/Runtime/DownloadSystem/Operation.meta
similarity index 77%
rename from Assets/YooAsset/Runtime/CacheSystem/Operation.meta
rename to Assets/YooAsset/Runtime/DownloadSystem/Operation.meta
index 9b6ba5bf..0587d2ca 100644
--- a/Assets/YooAsset/Runtime/CacheSystem/Operation.meta
+++ b/Assets/YooAsset/Runtime/DownloadSystem/Operation.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: d29a9623b2b346e439b7a7e37fafa781
+guid: a8f060786f8775b4a82cc3f55d9135e2
folderAsset: yes
DefaultImporter:
externalObjects: {}
diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal.meta b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal.meta
similarity index 77%
rename from Assets/YooAsset/Runtime/CacheSystem/Operation/Internal.meta
rename to Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal.meta
index 81927ef8..159e6467 100644
--- a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal.meta
+++ b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: a93a516506b2b5c4492fdefe26eb1175
+guid: 4630dac2050606043bb146325fdce6ad
folderAsset: yes
DefaultImporter:
externalObjects: {}
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebDataRequestOperation.cs b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebDataRequestOperation.cs
new file mode 100644
index 00000000..3a26ffc2
--- /dev/null
+++ b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebDataRequestOperation.cs
@@ -0,0 +1,77 @@
+using UnityEngine.Networking;
+using UnityEngine;
+
+namespace YooAsset
+{
+ internal class UnityWebDataRequestOperation : UnityWebRequestOperation
+ {
+ private UnityWebRequestAsyncOperation _requestOperation;
+
+ ///
+ /// 请求结果
+ ///
+ public byte[] Result { private set; get; }
+
+
+ internal UnityWebDataRequestOperation(string url, int timeout = 60) : base(url, timeout)
+ {
+ }
+ internal override void InternalOnStart()
+ {
+ _steps = ESteps.CreateRequest;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.CreateRequest)
+ {
+ _latestDownloadBytes = 0;
+ _latestDownloadRealtime = Time.realtimeSinceStartup;
+
+ CreateWebRequest();
+ _steps = ESteps.Download;
+ }
+
+ if (_steps == ESteps.Download)
+ {
+ Progress = _requestOperation.progress;
+ if (_requestOperation.isDone == false)
+ {
+ CheckRequestTimeout();
+ return;
+ }
+
+ if (CheckRequestResult())
+ {
+ _steps = ESteps.Done;
+ Result = _webRequest.downloadHandler.data;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ }
+
+ // 注意:最终释放请求器
+ DisposeRequest();
+ }
+ }
+ internal override void InternalOnAbort()
+ {
+ _steps = ESteps.Done;
+ DisposeRequest();
+ }
+
+ private void CreateWebRequest()
+ {
+ _webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
+ DownloadHandlerBuffer handler = new DownloadHandlerBuffer();
+ _webRequest.downloadHandler = handler;
+ _webRequest.disposeDownloadHandlerOnDispose = true;
+ _requestOperation = _webRequest.SendWebRequest();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebDataRequester.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebDataRequestOperation.cs.meta
similarity index 100%
rename from Assets/YooAsset/Runtime/DownloadSystem/UnityWebDataRequester.cs.meta
rename to Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebDataRequestOperation.cs.meta
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebFileRequestOperation.cs b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebFileRequestOperation.cs
new file mode 100644
index 00000000..28936bdf
--- /dev/null
+++ b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebFileRequestOperation.cs
@@ -0,0 +1,73 @@
+using UnityEngine.Networking;
+using UnityEngine;
+
+namespace YooAsset
+{
+ internal class UnityWebFileRequestOperation : UnityWebRequestOperation
+ {
+ private UnityWebRequestAsyncOperation _requestOperation;
+ private readonly string _fileSavePath;
+
+ internal UnityWebFileRequestOperation(string url, string fileSavePath, int timeout = 60) : base(url, timeout)
+ {
+ _fileSavePath = fileSavePath;
+ }
+ internal override void InternalOnStart()
+ {
+ _steps = ESteps.CreateRequest;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.CreateRequest)
+ {
+ _latestDownloadBytes = 0;
+ _latestDownloadRealtime = Time.realtimeSinceStartup;
+
+ CreateWebRequest();
+ _steps = ESteps.Download;
+ }
+
+ if (_steps == ESteps.Download)
+ {
+ Progress = _requestOperation.progress;
+ if (_requestOperation.isDone == false)
+ {
+ CheckRequestTimeout();
+ return;
+ }
+
+ if (CheckRequestResult())
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ }
+
+ // 注意:最终释放请求器
+ DisposeRequest();
+ }
+ }
+ internal override void InternalOnAbort()
+ {
+ _steps = ESteps.Done;
+ DisposeRequest();
+ }
+
+ private void CreateWebRequest()
+ {
+ _webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
+ DownloadHandlerFile handler = new DownloadHandlerFile(_fileSavePath);
+ handler.removeFileOnAbort = true;
+ _webRequest.downloadHandler = handler;
+ _webRequest.disposeDownloadHandlerOnDispose = true;
+ _requestOperation = _webRequest.SendWebRequest();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebFileRequester.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebFileRequestOperation.cs.meta
similarity index 100%
rename from Assets/YooAsset/Runtime/DownloadSystem/UnityWebFileRequester.cs.meta
rename to Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebFileRequestOperation.cs.meta
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequesterBase.cs b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebRequestOperation.cs
similarity index 53%
rename from Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequesterBase.cs
rename to Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebRequestOperation.cs
index 0fb6d6ce..26bd625f 100644
--- a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequesterBase.cs
+++ b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebRequestOperation.cs
@@ -6,94 +6,53 @@ using UnityEngine;
namespace YooAsset
{
- internal abstract class UnityWebRequesterBase
+ internal abstract class UnityWebRequestOperation : AsyncOperationBase
{
+ protected enum ESteps
+ {
+ None,
+ CreateRequest,
+ Download,
+ Done,
+ }
+
protected UnityWebRequest _webRequest;
- protected UnityWebRequestAsyncOperation _operationHandle;
+ protected readonly string _requestURL;
+ protected ESteps _steps = ESteps.None;
// 超时相关
- private float _timeout;
+ protected readonly float _timeout;
+ protected ulong _latestDownloadBytes;
+ protected float _latestDownloadRealtime;
private bool _isAbort = false;
- private ulong _latestDownloadBytes;
- private float _latestDownloadRealtime;
- ///
- /// 请求URL地址
- ///
- public string URL { protected set; get; }
-
-
- protected void ResetTimeout(float timeout)
+ public string URL
{
+ get { return _requestURL; }
+ }
+
+ internal UnityWebRequestOperation(string url, int timeout)
+ {
+ _requestURL = url;
_timeout = timeout;
- _latestDownloadBytes = 0;
- _latestDownloadRealtime = Time.realtimeSinceStartup;
}
///
/// 释放下载器
///
- public void Dispose()
+ protected void DisposeRequest()
{
if (_webRequest != null)
{
_webRequest.Dispose();
_webRequest = null;
- _operationHandle = null;
}
}
- ///
- /// 是否完毕(无论成功失败)
- ///
- public bool IsDone()
- {
- if (_operationHandle == null)
- return false;
- return _operationHandle.isDone;
- }
-
- ///
- /// 下载进度
- ///
- public float Progress()
- {
- if (_operationHandle == null)
- return 0;
- return _operationHandle.progress;
- }
-
- ///
- /// 下载是否发生错误
- ///
- public bool HasError()
- {
-#if UNITY_2020_3_OR_NEWER
- return _webRequest.result != UnityWebRequest.Result.Success;
-#else
- if (_webRequest.isNetworkError || _webRequest.isHttpError)
- return true;
- else
- return false;
-#endif
- }
-
- ///
- /// 获取错误信息
- ///
- public string GetError()
- {
- if (_webRequest != null)
- {
- return $"URL : {URL} Error : {_webRequest.error}";
- }
- return string.Empty;
- }
-
///
/// 检测超时
///
- public void CheckTimeout()
+ protected void CheckRequestTimeout()
{
// 注意:在连续时间段内无新增下载数据及判定为超时
if (_isAbort == false)
@@ -112,5 +71,33 @@ namespace YooAsset
}
}
}
+
+ ///
+ /// 检测请求结果
+ ///
+ protected bool CheckRequestResult()
+ {
+#if UNITY_2020_3_OR_NEWER
+ if (_webRequest.result != UnityWebRequest.Result.Success)
+ {
+ Error = $"URL : {_requestURL} Error : {_webRequest.error}";
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+#else
+ if (_webRequest.isNetworkError || _webRequest.isHttpError)
+ {
+ Error = $"URL : {_requestURL} Error : {_webRequest.error}";
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+#endif
+ }
}
}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequesterBase.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebRequestOperation.cs.meta
similarity index 100%
rename from Assets/YooAsset/Runtime/DownloadSystem/UnityWebRequesterBase.cs.meta
rename to Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebRequestOperation.cs.meta
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebTextRequestOperation.cs b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebTextRequestOperation.cs
new file mode 100644
index 00000000..ee1ae32c
--- /dev/null
+++ b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebTextRequestOperation.cs
@@ -0,0 +1,77 @@
+using UnityEngine.Networking;
+using UnityEngine;
+
+namespace YooAsset
+{
+ internal class UnityWebTextRequestOperation : UnityWebRequestOperation
+ {
+ private UnityWebRequestAsyncOperation _requestOperation;
+
+ ///
+ /// 请求结果
+ ///
+ public string Result { private set; get; }
+
+
+ internal UnityWebTextRequestOperation(string url, int timeout = 60) : base(url, timeout)
+ {
+ }
+ internal override void InternalOnStart()
+ {
+ _steps = ESteps.CreateRequest;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.CreateRequest)
+ {
+ _latestDownloadBytes = 0;
+ _latestDownloadRealtime = Time.realtimeSinceStartup;
+
+ CreateWebRequest();
+ _steps = ESteps.Download;
+ }
+
+ if (_steps == ESteps.Download)
+ {
+ Progress = _requestOperation.progress;
+ if (_requestOperation.isDone == false)
+ {
+ CheckRequestTimeout();
+ return;
+ }
+
+ if (CheckRequestResult())
+ {
+ _steps = ESteps.Done;
+ Result = _webRequest.downloadHandler.text;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ }
+
+ // 注意:最终释放请求器
+ DisposeRequest();
+ }
+ }
+ internal override void InternalOnAbort()
+ {
+ _steps = ESteps.Done;
+ DisposeRequest();
+ }
+
+ private void CreateWebRequest()
+ {
+ _webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
+ DownloadHandlerBuffer handler = new DownloadHandlerBuffer();
+ _webRequest.downloadHandler = handler;
+ _webRequest.disposeDownloadHandlerOnDispose = true;
+ _requestOperation = _webRequest.SendWebRequest();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/CacheSystem/CacheHelper.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebTextRequestOperation.cs.meta
similarity index 83%
rename from Assets/YooAsset/Runtime/CacheSystem/CacheHelper.cs.meta
rename to Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebTextRequestOperation.cs.meta
index 5fbd5e69..14653aeb 100644
--- a/Assets/YooAsset/Runtime/CacheSystem/CacheHelper.cs.meta
+++ b/Assets/YooAsset/Runtime/DownloadSystem/Operation/Internal/UnityWebTextRequestOperation.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8616c7550a7890141af598898a12df1b
+guid: a488de5dcd6f4c448a47c4b574d5c9bc
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester.meta b/Assets/YooAsset/Runtime/DownloadSystem/Requester.meta
deleted file mode 100644
index 451d6c03..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/Requester.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: 8a97534752300584a9b8c60c04c6a6a8
-folderAsset: yes
-DefaultImporter:
- externalObjects: {}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/AssetBundleWebRequest.cs b/Assets/YooAsset/Runtime/DownloadSystem/Requester/AssetBundleWebRequest.cs
deleted file mode 100644
index 20b4ab3f..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/Requester/AssetBundleWebRequest.cs
+++ /dev/null
@@ -1,145 +0,0 @@
-using System.IO;
-using UnityEngine;
-using UnityEngine.Networking;
-
-namespace YooAsset
-{
- internal class AssetBundleWebRequest : IWebRequester
- {
- private UnityWebRequest _webRequest;
- private DownloadHandlerAssetBundle _downloadhandler;
- private AssetBundle _cacheAssetBundle;
- private bool _getAssetBundle = false;
-
- public ERequestStatus Status { private set; get; } = ERequestStatus.None;
- public float DownloadProgress { private set; get; }
- public ulong DownloadedBytes { private set; get; }
- public string RequestNetError { private set; get; }
- public long RequestHttpCode { private set; get; }
-
- public AssetBundleWebRequest() { }
- public void Create(string requestURL, BundleInfo bundleInfo, params object[] args)
- {
- if (Status != ERequestStatus.None)
- throw new System.Exception("Should never get here !");
-
- if (args.Length == 0)
- throw new System.Exception("Not found param value");
-
- // 解析附加参数
- _getAssetBundle = (bool)args[0];
-
- // 创建下载器
- _webRequest = DownloadHelper.NewRequest(requestURL);
- if (CacheHelper.DisableUnityCacheOnWebGL)
- {
- uint crc = bundleInfo.Bundle.UnityCRC;
- _downloadhandler = new DownloadHandlerAssetBundle(requestURL, crc);
- }
- else
- {
- uint crc = bundleInfo.Bundle.UnityCRC;
- var hash = Hash128.Parse(bundleInfo.Bundle.FileHash);
- _downloadhandler = new DownloadHandlerAssetBundle(requestURL, hash, crc);
- }
-#if UNITY_2020_3_OR_NEWER
- _downloadhandler.autoLoadAssetBundle = false;
-#endif
- _webRequest.downloadHandler = _downloadhandler;
- _webRequest.disposeDownloadHandlerOnDispose = true;
- _webRequest.SendWebRequest();
- Status = ERequestStatus.InProgress;
- }
- public void Update()
- {
- if (Status == ERequestStatus.None)
- return;
- if (IsDone())
- return;
-
- DownloadProgress = _webRequest.downloadProgress;
- DownloadedBytes = _webRequest.downloadedBytes;
- if (_webRequest.isDone == false)
- return;
-
- // 检查网络错误
-#if UNITY_2020_3_OR_NEWER
- RequestHttpCode = _webRequest.responseCode;
- if (_webRequest.result != UnityWebRequest.Result.Success)
- {
- RequestNetError = _webRequest.error;
- Status = ERequestStatus.Error;
- }
- else
- {
- Status = ERequestStatus.Success;
- }
-#else
- RequestHttpCode = _webRequest.responseCode;
- if (_webRequest.isNetworkError || _webRequest.isHttpError)
- {
- RequestNetError = _webRequest.error;
- Status = ERequestStatus.Error;
- }
- else
- {
- Status = ERequestStatus.Success;
- }
-#endif
-
- // 缓存加载的AssetBundle对象
- if (Status == ERequestStatus.Success)
- {
- if (_getAssetBundle)
- {
- _cacheAssetBundle = _downloadhandler.assetBundle;
- if (_cacheAssetBundle == null)
- {
- RequestNetError = "assetBundle is null";
- Status = ERequestStatus.Error;
- }
- }
- }
-
- // 最终释放下载器
- DisposeWebRequest();
- }
- public void Abort()
- {
- // 如果下载任务还未开始
- if (Status == ERequestStatus.None)
- {
- RequestNetError = "user cancel";
- Status = ERequestStatus.Error;
- }
- else
- {
- // 注意:为了防止同一个文件强制停止之后立马创建新的请求,应该让进行中的请求自然终止。
- if (_webRequest != null)
- {
- if (_webRequest.isDone == false)
- _webRequest.Abort(); // If in progress, halts the UnityWebRequest as soon as possible.
- }
- }
- }
- public bool IsDone()
- {
- if (Status == ERequestStatus.Success || Status == ERequestStatus.Error)
- return true;
- else
- return false;
- }
- public object GetRequestObject()
- {
- return _cacheAssetBundle;
- }
- private void DisposeWebRequest()
- {
- if (_webRequest != null)
- {
- _webRequest.Dispose();
- _webRequest = null;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/AssetBundleWebRequest.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Requester/AssetBundleWebRequest.cs.meta
deleted file mode 100644
index 2c61d444..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/Requester/AssetBundleWebRequest.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 34efa85440da15247b570a98b0971282
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileGeneralRequest.cs b/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileGeneralRequest.cs
deleted file mode 100644
index 11d49f93..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileGeneralRequest.cs
+++ /dev/null
@@ -1,108 +0,0 @@
-using System.IO;
-using UnityEngine.Networking;
-
-namespace YooAsset
-{
- internal class FileGeneralRequest : IWebRequester
- {
- private UnityWebRequest _webRequest;
-
- public ERequestStatus Status { private set; get; } = ERequestStatus.None;
- public float DownloadProgress { private set; get; }
- public ulong DownloadedBytes { private set; get; }
- public string RequestNetError { private set; get; }
- public long RequestHttpCode { private set; get; }
-
- public FileGeneralRequest() { }
- public void Create(string requestURL, BundleInfo bundleInfo, params object[] args)
- {
- if (Status != ERequestStatus.None)
- throw new System.Exception("Should never get here !");
-
- string tempFilePath = bundleInfo.TempDataFilePath;
-
- // 删除临时文件
- if (File.Exists(tempFilePath))
- File.Delete(tempFilePath);
-
- // 创建下载器
- _webRequest = DownloadHelper.NewRequest(requestURL);
- DownloadHandlerFile handler = new DownloadHandlerFile(tempFilePath);
- handler.removeFileOnAbort = true;
- _webRequest.downloadHandler = handler;
- _webRequest.disposeDownloadHandlerOnDispose = true;
- _webRequest.SendWebRequest();
- Status = ERequestStatus.InProgress;
- }
- public void Update()
- {
- if (Status == ERequestStatus.None)
- return;
- if (IsDone())
- return;
-
- DownloadProgress = _webRequest.downloadProgress;
- DownloadedBytes = _webRequest.downloadedBytes;
- if (_webRequest.isDone == false)
- return;
-
- // 检查网络错误
-#if UNITY_2020_3_OR_NEWER
- RequestHttpCode = _webRequest.responseCode;
- if (_webRequest.result != UnityWebRequest.Result.Success)
- {
- RequestNetError = _webRequest.error;
- Status = ERequestStatus.Error;
- }
- else
- {
- Status = ERequestStatus.Success;
- }
-#else
- RequestHttpCode = _webRequest.responseCode;
- if (_webRequest.isNetworkError || _webRequest.isHttpError)
- {
- RequestNetError = _webRequest.error;
- Status = ERequestStatus.Error;
- }
- else
- {
- Status = ERequestStatus.Success;
- }
-#endif
-
- // 最终释放下载器
- DisposeWebRequest();
- }
- public void Abort()
- {
- DisposeWebRequest();
- if (IsDone() == false)
- {
- RequestNetError = "user abort";
- RequestHttpCode = 0;
- Status = ERequestStatus.Error;
- }
- }
- public bool IsDone()
- {
- if (Status == ERequestStatus.Success || Status == ERequestStatus.Error)
- return true;
- else
- return false;
- }
- public object GetRequestObject()
- {
- throw new System.NotImplementedException();
- }
- private void DisposeWebRequest()
- {
- if (_webRequest != null)
- {
- //注意:引擎底层会自动调用Abort方法
- _webRequest.Dispose();
- _webRequest = null;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileGeneralRequest.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileGeneralRequest.cs.meta
deleted file mode 100644
index 10255323..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileGeneralRequest.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: b2f339136a4269343a3b5ab80450b889
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileResumeRequest.cs b/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileResumeRequest.cs
deleted file mode 100644
index 0936a466..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileResumeRequest.cs
+++ /dev/null
@@ -1,151 +0,0 @@
-using System.IO;
-using UnityEngine.Networking;
-
-namespace YooAsset
-{
- internal class FileResumeRequest : IWebRequester
- {
- private string _tempFilePath;
- private UnityWebRequest _webRequest;
- private DownloadHandlerFileRange _downloadHandle;
- private ulong _fileOriginLength = 0;
-
- public ERequestStatus Status { private set; get; } = ERequestStatus.None;
- public float DownloadProgress { private set; get; }
- public ulong DownloadedBytes { private set; get; }
- public string RequestNetError { private set; get; }
- public long RequestHttpCode { private set; get; }
-
- public FileResumeRequest() { }
- public void Create(string requestURL, BundleInfo bundleInfo, params object[] args)
- {
- if (Status != ERequestStatus.None)
- throw new System.Exception("Should never get here !");
-
- _tempFilePath = bundleInfo.TempDataFilePath;
- long fileBytes = bundleInfo.Bundle.FileSize;
-
- // 获取下载的起始位置
- long fileLength = -1;
- if (File.Exists(_tempFilePath))
- {
- FileInfo fileInfo = new FileInfo(_tempFilePath);
- fileLength = fileInfo.Length;
- _fileOriginLength = (ulong)fileLength;
- DownloadedBytes = _fileOriginLength;
- }
-
- // 检测下载起始位置是否有效
- if (fileLength >= fileBytes)
- {
- if (File.Exists(_tempFilePath))
- File.Delete(_tempFilePath);
- }
-
- // 创建下载器
- _webRequest = DownloadHelper.NewRequest(requestURL);
-#if UNITY_2019_4_OR_NEWER
- var handler = new DownloadHandlerFile(_tempFilePath, true);
- handler.removeFileOnAbort = false;
-#else
- var handler = new DownloadHandlerFileRange(tempFilePath, _bundleInfo.Bundle.FileSize, _webRequest);
- _downloadHandle = handler;
-#endif
- _webRequest.downloadHandler = handler;
- _webRequest.disposeDownloadHandlerOnDispose = true;
- if (fileLength > 0)
- _webRequest.SetRequestHeader("Range", $"bytes={fileLength}-");
- _webRequest.SendWebRequest();
- Status = ERequestStatus.InProgress;
- }
- public void Update()
- {
- if (Status == ERequestStatus.None)
- return;
- if (IsDone())
- return;
-
- DownloadProgress = _webRequest.downloadProgress;
- DownloadedBytes = _fileOriginLength + _webRequest.downloadedBytes;
- if (_webRequest.isDone == false)
- return;
-
- // 检查网络错误
-#if UNITY_2020_3_OR_NEWER
- RequestHttpCode = _webRequest.responseCode;
- if (_webRequest.result != UnityWebRequest.Result.Success)
- {
- RequestNetError = _webRequest.error;
- Status = ERequestStatus.Error;
- }
- else
- {
- Status = ERequestStatus.Success;
- }
-#else
- RequestHttpCode = _webRequest.responseCode;
- if (_webRequest.isNetworkError || _webRequest.isHttpError)
- {
- RequestNetError = _webRequest.error;
- Status = ERequestStatus.Error;
- }
- else
- {
- Status = ERequestStatus.Success;
- }
-#endif
-
- // 注意:下载断点续传文件发生特殊错误码之后删除文件
- if (Status == ERequestStatus.Error)
- {
- if (DownloadHelper.ClearFileResponseCodes != null)
- {
- if (DownloadHelper.ClearFileResponseCodes.Contains(RequestHttpCode))
- {
- if (File.Exists(_tempFilePath))
- File.Delete(_tempFilePath);
- }
- }
- }
-
- // 最终释放下载器
- DisposeWebRequest();
- }
- public void Abort()
- {
- DisposeWebRequest();
- if (IsDone() == false)
- {
- RequestNetError = "user abort";
- RequestHttpCode = 0;
- Status = ERequestStatus.Error;
- }
- }
- public bool IsDone()
- {
- if (Status == ERequestStatus.Success || Status == ERequestStatus.Error)
- return true;
- else
- return false;
- }
- public object GetRequestObject()
- {
- throw new System.NotImplementedException();
- }
- private void DisposeWebRequest()
- {
- if (_downloadHandle != null)
- {
- _downloadHandle.Cleanup();
- _downloadHandle = null;
- }
-
- if (_webRequest != null)
- {
- //注意:引擎底层会自动调用Abort方法
- _webRequest.Dispose();
- _webRequest = null;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileResumeRequest.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileResumeRequest.cs.meta
deleted file mode 100644
index df15a3be..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/Requester/FileResumeRequest.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 816bf5396d7570e4ab28f1af407bc10f
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/IWebRequester.cs b/Assets/YooAsset/Runtime/DownloadSystem/Requester/IWebRequester.cs
deleted file mode 100644
index 1feeee4a..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/Requester/IWebRequester.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-
-namespace YooAsset
-{
- internal enum ERequestStatus
- {
- None,
- InProgress,
- Error,
- Success,
- }
-
- internal interface IWebRequester
- {
- ///
- /// 任务状态
- ///
- ERequestStatus Status { get; }
-
- ///
- /// 下载进度(0f~1f)
- ///
- float DownloadProgress { get; }
-
- ///
- /// 已经下载的总字节数
- ///
- ulong DownloadedBytes { get; }
-
- ///
- /// 返回的网络错误
- ///
- string RequestNetError { get; }
-
- ///
- /// 返回的HTTP CODE
- ///
- long RequestHttpCode { get; }
-
-
- ///
- /// 创建任务
- ///
- void Create(string url, BundleInfo bundleInfo, params object[] args);
-
- ///
- /// 更新任务
- ///
- void Update();
-
- ///
- /// 终止任务
- ///
- void Abort();
-
- ///
- /// 是否已经完成(无论成功或失败)
- ///
- bool IsDone();
-
- ///
- /// 获取请求的对象
- ///
- object GetRequestObject();
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/IWebRequester.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Requester/IWebRequester.cs.meta
deleted file mode 100644
index fffe1950..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/Requester/IWebRequester.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 4d80b965d56870b43af1bf6943015914
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebDataRequester.cs b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebDataRequester.cs
deleted file mode 100644
index fb109dcf..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebDataRequester.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using UnityEngine.Networking;
-using UnityEngine;
-
-namespace YooAsset
-{
- internal class UnityWebDataRequester : UnityWebRequesterBase
- {
- ///
- /// 发送GET请求
- ///
- public void SendRequest(string url, int timeout = 60)
- {
- if (_webRequest == null)
- {
- URL = url;
- ResetTimeout(timeout);
-
- _webRequest = DownloadHelper.NewRequest(URL);
- DownloadHandlerBuffer handler = new DownloadHandlerBuffer();
- _webRequest.downloadHandler = handler;
- _webRequest.disposeDownloadHandlerOnDispose = true;
- _operationHandle = _webRequest.SendWebRequest();
- }
- }
-
- ///
- /// 获取下载的字节数据
- ///
- public byte[] GetData()
- {
- if (_webRequest != null && IsDone())
- return _webRequest.downloadHandler.data;
- else
- return null;
- }
-
- ///
- /// 获取下载的文本数据
- ///
- public string GetText()
- {
- if (_webRequest != null && IsDone())
- return _webRequest.downloadHandler.text;
- else
- return null;
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebFileRequester.cs b/Assets/YooAsset/Runtime/DownloadSystem/UnityWebFileRequester.cs
deleted file mode 100644
index 09e17459..00000000
--- a/Assets/YooAsset/Runtime/DownloadSystem/UnityWebFileRequester.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using UnityEngine.Networking;
-using UnityEngine;
-
-namespace YooAsset
-{
- internal class UnityWebFileRequester : UnityWebRequesterBase
- {
- ///
- /// 发送GET请求
- ///
- public void SendRequest(string url, string fileSavePath, int timeout = 60)
- {
- if (_webRequest == null)
- {
- URL = url;
- ResetTimeout(timeout);
-
- _webRequest = DownloadHelper.NewRequest(URL);
- DownloadHandlerFile handler = new DownloadHandlerFile(fileSavePath);
- handler.removeFileOnAbort = true;
- _webRequest.downloadHandler = handler;
- _webRequest.disposeDownloadHandlerOnDispose = true;
- _operationHandle = _webRequest.SendWebRequest();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/RequestHelper.cs b/Assets/YooAsset/Runtime/DownloadSystem/WebRequestCounter.cs
similarity index 96%
rename from Assets/YooAsset/Runtime/DownloadSystem/RequestHelper.cs
rename to Assets/YooAsset/Runtime/DownloadSystem/WebRequestCounter.cs
index 3f99b6fc..0c962d91 100644
--- a/Assets/YooAsset/Runtime/DownloadSystem/RequestHelper.cs
+++ b/Assets/YooAsset/Runtime/DownloadSystem/WebRequestCounter.cs
@@ -4,7 +4,7 @@ using System.Collections.Generic;
namespace YooAsset
{
- public class RequestHelper
+ internal class WebRequestCounter
{
///
/// 记录网络请求失败事件的次数
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/RequestHelper.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/WebRequestCounter.cs.meta
similarity index 100%
rename from Assets/YooAsset/Runtime/DownloadSystem/RequestHelper.cs.meta
rename to Assets/YooAsset/Runtime/DownloadSystem/WebRequestCounter.cs.meta
diff --git a/Assets/YooAsset/Runtime/CacheSystem.meta b/Assets/YooAsset/Runtime/FileSystem.meta
similarity index 77%
rename from Assets/YooAsset/Runtime/CacheSystem.meta
rename to Assets/YooAsset/Runtime/FileSystem.meta
index 8a548d3b..95647683 100644
--- a/Assets/YooAsset/Runtime/CacheSystem.meta
+++ b/Assets/YooAsset/Runtime/FileSystem.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 96a75a20111d6124696665e7aac3564c
+guid: d7ac605758b151748980942c6d563fed
folderAsset: yes
DefaultImporter:
externalObjects: {}
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem.meta
similarity index 77%
rename from Assets/YooAsset/Runtime/DownloadSystem/Downloader.meta
rename to Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem.meta
index 1b00904c..a1243696 100644
--- a/Assets/YooAsset/Runtime/DownloadSystem/Downloader.meta
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: a82eeb6a47cd02c4cb38e851c8ed8784
+guid: 6f2f046660639e54cb2c40610189a91c
folderAsset: yes
DefaultImporter:
externalObjects: {}
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileCatalog.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileCatalog.cs
new file mode 100644
index 00000000..bc991a86
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileCatalog.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace YooAsset
+{
+ ///
+ /// 内置资源清单目录
+ ///
+ internal class DefaultBuildinFileCatalog : ScriptableObject
+ {
+ [Serializable]
+ public class FileWrapper
+ {
+ public string BundleGUID;
+ public string FileName;
+
+ public FileWrapper(string bundleGUID, string fileName)
+ {
+ BundleGUID = bundleGUID;
+ FileName = fileName;
+ }
+ }
+
+ ///
+ /// 包裹名称
+ ///
+ public string PackageName;
+
+ ///
+ /// 包裹版本
+ ///
+ public string PackageVersion;
+
+ ///
+ /// 文件列表
+ ///
+ public List Wrappers = new List();
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileCatalog.cs.meta
similarity index 83%
rename from Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs.meta
rename to Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileCatalog.cs.meta
index 8d035ba8..36204b3a 100644
--- a/Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs.meta
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileCatalog.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: e4a97c06e069c1146a881fcb359f9b4b
+guid: b05c83971e3dca94f9fa460d396385e5
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystem.cs
new file mode 100644
index 00000000..84b7b4c9
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystem.cs
@@ -0,0 +1,335 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace YooAsset
+{
+ ///
+ /// 内置文件系统
+ ///
+ internal class DefaultBuildinFileSystem : IFileSystem
+ {
+ public class FileWrapper
+ {
+ public string FileName { private set; get; }
+
+ public FileWrapper(string fileName)
+ {
+ FileName = fileName;
+ }
+ }
+
+ protected readonly Dictionary _wrappers = new Dictionary(10000);
+ protected readonly Dictionary _loadedStream = new Dictionary(10000);
+ protected readonly Dictionary _buildinFilePaths = new Dictionary(10000);
+ protected string _packageRoot;
+
+ ///
+ /// 解压文件系统
+ ///
+ public IFileSystem UnpackFileSystem { private set; get; }
+
+
+ ///
+ /// 包裹名称
+ ///
+ public string PackageName { private set; get; }
+
+ ///
+ /// 文件访问权限
+ ///
+ public EFileAccess FileSystemAccess
+ {
+ get
+ {
+ return EFileAccess.Read;
+ }
+ }
+
+ ///
+ /// 文件根目录
+ ///
+ public string FileRoot
+ {
+ get
+ {
+ return _packageRoot;
+ }
+ }
+
+ ///
+ /// 文件数量
+ ///
+ public int FileCount
+ {
+ get
+ {
+ return _wrappers.Count;
+ }
+ }
+
+ #region 自定义参数
+ ///
+ /// 自定义参数:初始化的时候缓存文件校验级别
+ ///
+ public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle;
+
+ ///
+ /// 自定义参数:数据文件追加文件格式
+ ///
+ public bool AppendFileExtension { private set; get; } = false;
+
+ ///
+ /// 自定义参数:原生文件构建管线
+ ///
+ public bool RawFileBuildPipeline { private set; get; } = false;
+ #endregion
+
+
+ public DefaultBuildinFileSystem()
+ {
+ }
+ public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync()
+ {
+#if UNITY_EDITOR
+ var operation = new DBFSInitializeInEditorPlayModeOperation(this);
+ OperationSystem.StartOperation(PackageName, operation);
+ return operation;
+#else
+ var operation = new DBFSInitializeOperation(this);
+ OperationSystem.StartOperation(PackageName, operation);
+ return operation;
+#endif
+ }
+ public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(params object[] args)
+ {
+ var operation = new DBFSLoadPackageManifestOperation(this);
+ OperationSystem.StartOperation(PackageName, operation);
+ return operation;
+ }
+ public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(params object[] args)
+ {
+ throw new System.NotImplementedException();
+ }
+ public virtual FSClearAllBundleFilesOperation ClearAllBundleFilesAsync(params object[] args)
+ {
+ var operation = new DBFSClearAllBundleFilesOperation(this);
+ OperationSystem.StartOperation(PackageName, operation);
+ return operation;
+ }
+ public virtual FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(params object[] args)
+ {
+ PackageManifest manifest = args[0] as PackageManifest;
+ var operation = new DBFSClearUnusedBundleFilesOperation(this, manifest);
+ OperationSystem.StartOperation(PackageName, operation);
+ return operation;
+ }
+ public virtual FSDownloadFileOperation DownloadFileAsync(params object[] args)
+ {
+ PackageBundle bundle = args[0] as PackageBundle;
+ int failedTryAgain = (int)args[2];
+ int timeout = (int)args[3];
+
+ string buidlinFilePath = GetBuildinFileLoadPath(bundle);
+ return UnpackFileSystem.DownloadFileAsync(bundle, buidlinFilePath, failedTryAgain, timeout);
+ }
+
+ public virtual void SetParameter(string name, object value)
+ {
+ if (name == "FILE_VERIFY_LEVEL")
+ {
+ FileVerifyLevel = (EFileVerifyLevel)value;
+ }
+ else if (name == "APPEND_FILE_EXTENSION")
+ {
+ AppendFileExtension = (bool)value;
+ }
+ else if (name == "RAW_FILE_BUILD_PIPELINE")
+ {
+ RawFileBuildPipeline = (bool)value;
+ }
+ else
+ {
+ YooLogger.Warning($"Invalid parameter : {name}");
+ }
+ }
+ public virtual void OnCreate(string packageName, string rootDirectory)
+ {
+ PackageName = packageName;
+
+ if (string.IsNullOrEmpty(rootDirectory))
+ rootDirectory = GetDefaultRoot();
+
+ _packageRoot = PathUtility.Combine(rootDirectory, packageName);
+
+ // 创建解压文件系统
+ UnpackFileSystem = new DefaultUnpackFileSystem();
+ UnpackFileSystem.SetParameter("FILE_VERIFY_LEVEL", FileVerifyLevel);
+ UnpackFileSystem.SetParameter("APPEND_FILE_EXTENSION", AppendFileExtension);
+ UnpackFileSystem.SetParameter("RAW_FILE_BUILD_PIPELINE", RawFileBuildPipeline);
+ UnpackFileSystem.OnCreate(packageName, null);
+ }
+ public virtual void OnUpdate()
+ {
+ }
+
+ public virtual bool Belong(PackageBundle bundle)
+ {
+ return _wrappers.ContainsKey(bundle.BundleGUID);
+ }
+ public virtual bool Belong(string bundleGUID)
+ {
+ return _wrappers.ContainsKey(bundleGUID);
+ }
+ public virtual bool Exists(PackageBundle bundle)
+ {
+ return _wrappers.ContainsKey(bundle.BundleGUID);
+ }
+ public virtual bool Exists(string bundleGUID)
+ {
+ return _wrappers.ContainsKey(bundleGUID);
+ }
+
+ public virtual bool CheckNeedDownload(PackageBundle bundle)
+ {
+ return false;
+ }
+ public virtual bool CheckNeedUnpack(PackageBundle bundle)
+ {
+ if (Belong(bundle) == false)
+ return false;
+
+#if UNITY_ANDROID
+ return RawFileBuildPipeline || bundle.Encrypted;
+#else
+ return false;
+#endif
+ }
+ public virtual bool CheckNeedImport(PackageBundle bundle)
+ {
+ return false;
+ }
+
+ public virtual bool WriteFile(PackageBundle bundle, string copyPath)
+ {
+ return UnpackFileSystem.WriteFile(bundle, copyPath);
+ }
+ public virtual bool DeleteFile(PackageBundle bundle)
+ {
+ return UnpackFileSystem.DeleteFile(bundle);
+ }
+ public virtual bool DeleteFile(string bundleGUID)
+ {
+ return UnpackFileSystem.DeleteFile(bundleGUID);
+ }
+ public virtual EFileVerifyResult VerifyFile(PackageBundle bundle)
+ {
+ return UnpackFileSystem.VerifyFile(bundle);
+ }
+
+ public virtual byte[] ReadFileBytes(PackageBundle bundle)
+ {
+ return UnpackFileSystem.ReadFileBytes(bundle);
+ }
+ public virtual string ReadFileText(PackageBundle bundle)
+ {
+ return UnpackFileSystem.ReadFileText(bundle);
+ }
+
+ public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle)
+ {
+ if (RawFileBuildPipeline)
+ {
+ var operation = new DBFSLoadRawBundleOperation(this, bundle);
+ OperationSystem.StartOperation(PackageName, operation);
+ return operation;
+ }
+ else
+ {
+ var operation = new DBFSLoadAssetBundleOperation(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 (UnpackFileSystem.Exists(bundle))
+ {
+ UnpackFileSystem.UnloadBundleFile(bundle, assetBundle);
+ }
+ else
+ {
+ if (assetBundle != null)
+ assetBundle.Unload(true);
+
+ if (_loadedStream.TryGetValue(bundle.BundleGUID, out Stream managedStream))
+ {
+ managedStream.Close();
+ managedStream.Dispose();
+ _loadedStream.Remove(bundle.BundleGUID);
+ }
+ }
+ }
+
+ #region 内部方法
+ protected string GetDefaultRoot()
+ {
+ string path = PathUtility.Combine(UnityEngine.Application.streamingAssetsPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
+#if UNITY_OPENHARMONY
+ return $"file://{path}";
+#else
+ return path;
+#endif
+ }
+ public string GetBuildinFileLoadPath(PackageBundle bundle)
+ {
+ if (_buildinFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
+ {
+ filePath = PathUtility.Combine(_packageRoot, bundle.FileName);
+ _buildinFilePaths.Add(bundle.BundleGUID, filePath);
+ }
+ return filePath;
+ }
+ public string GetBuildinCatalogFileLoadPath()
+ {
+ string fileName = Path.GetFileNameWithoutExtension(DefaultBuildinFileSystemDefine.BuildinCatalogFileName);
+ return PathUtility.Combine(YooAssetSettingsData.Setting.DefaultYooFolderName, PackageName, fileName);
+ }
+ public string GetBuildinPackageVersionFilePath()
+ {
+ string fileName = YooAssetSettingsData.GetPackageVersionFileName(PackageName);
+ return PathUtility.Combine(FileRoot, fileName);
+ }
+ public string GetBuildinPackageHashFilePath(string packageVersion)
+ {
+ string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion);
+ return PathUtility.Combine(FileRoot, fileName);
+ }
+ public string GetBuildinPackageManifestFilePath(string packageVersion)
+ {
+ string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion);
+ return PathUtility.Combine(FileRoot, fileName);
+ }
+
+ ///
+ /// 记录缓存信息
+ ///
+ public bool Record(string bundleGUID, FileWrapper wrapper)
+ {
+ if (_wrappers.ContainsKey(bundleGUID))
+ {
+ YooLogger.Error($"{nameof(DefaultBuildinFileSystem)} has element : {bundleGUID}");
+ return false;
+ }
+
+ _wrappers.Add(bundleGUID, wrapper);
+ return true;
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/CacheSystem/CacheManager.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystem.cs.meta
similarity index 83%
rename from Assets/YooAsset/Runtime/CacheSystem/CacheManager.cs.meta
rename to Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystem.cs.meta
index 54c9bad7..cfdf8446 100644
--- a/Assets/YooAsset/Runtime/CacheSystem/CacheManager.cs.meta
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystem.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 08f3e92fdbd5d56459d8882be1f54f60
+guid: 98465b987635afc479022ec358477491
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemBuild.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemBuild.cs
new file mode 100644
index 00000000..720983df
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemBuild.cs
@@ -0,0 +1,114 @@
+#if UNITY_EDITOR
+using System.Collections.Generic;
+using System.IO;
+using UnityEngine;
+
+namespace YooAsset
+{
+ internal class DefaultBuildinFileSystemBuild : UnityEditor.Build.IPreprocessBuildWithReport
+ {
+ public int callbackOrder { get { return 0; } }
+
+ ///
+ /// 在构建应用程序前自动生成内置资源清单。
+ /// 原理:搜索StreamingAssets目录下的所有资源文件,然后将这些文件信息写入内置资源清单,并存储在Resources目录下。
+ ///
+ public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report)
+ {
+ string savePath = $"Assets/Resources/{YooAssetSettingsData.Setting.DefaultYooFolderName}";
+ DirectoryInfo saveDirectory = new DirectoryInfo(savePath);
+ if (saveDirectory.Exists)
+ saveDirectory.Delete(true);
+
+ string rootPath = $"{Application.dataPath}/StreamingAssets/{YooAssetSettingsData.Setting.DefaultYooFolderName}";
+ DirectoryInfo rootDirectory = new DirectoryInfo(rootPath);
+ if (rootDirectory.Exists == false)
+ {
+ Debug.LogWarning($"Not found buildin root folder : {rootPath}");
+ return;
+ }
+
+ // 搜索所有Package目录
+ DirectoryInfo[] subDirectories = rootDirectory.GetDirectories();
+ foreach (var subDirectory in subDirectories)
+ {
+ CreateBuildinManifest(subDirectory.Name, subDirectory.FullName);
+ }
+ }
+ private void CreateBuildinManifest(string packageName, string pacakgeDirectory)
+ {
+ // 获取资源清单版本
+ string packageVersion;
+ {
+ string versionFileName = YooAssetSettingsData.GetPackageVersionFileName(packageName);
+ string versionFilePath = $"{pacakgeDirectory}/{versionFileName}";
+ if (File.Exists(versionFilePath) == false)
+ {
+ Debug.LogWarning($"Not found package version file : {versionFilePath}");
+ return;
+ }
+
+ packageVersion = FileUtility.ReadAllText(versionFilePath);
+ }
+
+ // 加载资源清单文件
+ PackageManifest packageManifest;
+ {
+ string manifestFileName = YooAssetSettingsData.GetManifestBinaryFileName(packageName, packageVersion);
+ string manifestFilePath = $"{pacakgeDirectory}/{manifestFileName}";
+ if (File.Exists(manifestFilePath) == false)
+ {
+ Debug.LogWarning($"Not found package manifest file : {manifestFilePath}");
+ return;
+ }
+
+ var binaryData = FileUtility.ReadAllBytes(manifestFilePath);
+ packageManifest = ManifestTools.DeserializeFromBinary(binaryData);
+ }
+
+ // 获取文件名映射关系
+ Dictionary fileMapping = new Dictionary();
+ {
+ foreach (var packageBundle in packageManifest.BundleList)
+ {
+ fileMapping.Add(packageBundle.FileName, packageBundle.BundleGUID);
+ }
+ }
+
+ // 创建内置清单实例
+ var buildinFileCatalog = ScriptableObject.CreateInstance();
+ buildinFileCatalog.PackageName = packageName;
+ buildinFileCatalog.PackageVersion = packageVersion;
+
+ // 记录所有内置资源文件
+ DirectoryInfo rootDirectory = new DirectoryInfo(pacakgeDirectory);
+ FileInfo[] fileInfos = rootDirectory.GetFiles();
+ foreach (var fileInfo in fileInfos)
+ {
+ if (fileInfo.Extension == ".meta" || fileInfo.Extension == ".version" ||
+ fileInfo.Extension == ".hash" || fileInfo.Extension == ".bytes")
+ continue;
+
+ string fileName = fileInfo.Name;
+ if (fileMapping.TryGetValue(fileName, out string bundleGUID))
+ {
+ var wrapper = new DefaultBuildinFileCatalog.FileWrapper(bundleGUID, fileName);
+ buildinFileCatalog.Wrappers.Add(wrapper);
+ }
+ else
+ {
+ Debug.LogWarning($"Failed mapping file : {fileName}");
+ }
+ }
+
+ string saveFilePath = $"Assets/Resources/{YooAssetSettingsData.Setting.DefaultYooFolderName}/{packageName}/{DefaultBuildinFileSystemDefine.BuildinCatalogFileName}";
+ FileUtility.CreateFileDirectory(saveFilePath);
+
+ UnityEditor.AssetDatabase.CreateAsset(buildinFileCatalog, saveFilePath);
+ UnityEditor.AssetDatabase.SaveAssets();
+ UnityEditor.AssetDatabase.Refresh();
+ Debug.Log($"一共记录{buildinFileCatalog.Wrappers.Count}个内置资源文件,内置资源目录文件保存成功 : {saveFilePath}");
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemBuild.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemBuild.cs.meta
new file mode 100644
index 00000000..5400d792
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemBuild.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6b5abe115ebfe1344b674db78b2edf6c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemDefine.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemDefine.cs
new file mode 100644
index 00000000..876e01d2
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemDefine.cs
@@ -0,0 +1,11 @@
+
+namespace YooAsset
+{
+ internal class DefaultBuildinFileSystemDefine
+ {
+ ///
+ /// 内置清单文件名称
+ ///
+ public const string BuildinCatalogFileName = "BuildinCatalog.asset";
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemDefine.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemDefine.cs.meta
new file mode 100644
index 00000000..a0860a97
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/DefaultBuildinFileSystemDefine.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4aa038f71ffd2394abc5daee917fbc66
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation.meta
new file mode 100644
index 00000000..cb776399
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 06f6a75331ed07a4a9e5e8f46dcf157e
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearAllBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearAllBundleFilesOperation.cs
new file mode 100644
index 00000000..b6ad4b3d
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearAllBundleFilesOperation.cs
@@ -0,0 +1,45 @@
+
+namespace YooAsset
+{
+ internal sealed class DBFSClearAllBundleFilesOperation : FSClearAllBundleFilesOperation
+ {
+ private enum ESteps
+ {
+ None,
+ ClearUnpackFileSystem,
+ Done,
+ }
+
+ private readonly DefaultBuildinFileSystem _fileSystem;
+ private FSClearAllBundleFilesOperation _unpackClearAllBundleFilesOp;
+ private ESteps _steps = ESteps.None;
+
+ internal DBFSClearAllBundleFilesOperation(DefaultBuildinFileSystem fileSystem)
+ {
+ _fileSystem = fileSystem;
+ }
+ internal override void InternalOnStart()
+ {
+ _steps = ESteps.ClearUnpackFileSystem;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.ClearUnpackFileSystem)
+ {
+ if (_unpackClearAllBundleFilesOp == null)
+ _unpackClearAllBundleFilesOp = _fileSystem.UnpackFileSystem.ClearAllBundleFilesAsync();
+
+ Progress = _unpackClearAllBundleFilesOp.Progress;
+ if (_unpackClearAllBundleFilesOp.IsDone == false)
+ return;
+
+ _steps = ESteps.Done;
+ Status = _unpackClearAllBundleFilesOp.Status;
+ Error = _unpackClearAllBundleFilesOp.Error;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearAllBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearAllBundleFilesOperation.cs.meta
new file mode 100644
index 00000000..8c0b9743
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearAllBundleFilesOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 624ca0ff2f0c7da4bb9c1a1d58e732b1
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearUnusedBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearUnusedBundleFilesOperation.cs
new file mode 100644
index 00000000..13263b0d
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearUnusedBundleFilesOperation.cs
@@ -0,0 +1,47 @@
+
+namespace YooAsset
+{
+ internal sealed class DBFSClearUnusedBundleFilesOperation : FSClearUnusedBundleFilesOperation
+ {
+ private enum ESteps
+ {
+ None,
+ ClearUnpackFileSystem,
+ Done,
+ }
+
+ private readonly DefaultBuildinFileSystem _fileSystem;
+ private readonly PackageManifest _manifest;
+ private FSClearUnusedBundleFilesOperation _unpackClearUnusedBundleFilesOp;
+ private ESteps _steps = ESteps.None;
+
+ internal DBFSClearUnusedBundleFilesOperation(DefaultBuildinFileSystem fileSystem, PackageManifest manifest)
+ {
+ _fileSystem = fileSystem;
+ _manifest = manifest;
+ }
+ internal override void InternalOnStart()
+ {
+ _steps = ESteps.ClearUnpackFileSystem;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.ClearUnpackFileSystem)
+ {
+ if (_unpackClearUnusedBundleFilesOp == null)
+ _unpackClearUnusedBundleFilesOp = _fileSystem.UnpackFileSystem.ClearUnusedBundleFilesAsync(_manifest);
+
+ Progress = _unpackClearUnusedBundleFilesOp.Progress;
+ if (_unpackClearUnusedBundleFilesOp.IsDone == false)
+ return;
+
+ _steps = ESteps.Done;
+ Status = _unpackClearUnusedBundleFilesOp.Status;
+ Error = _unpackClearUnusedBundleFilesOp.Error;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearUnusedBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearUnusedBundleFilesOperation.cs.meta
new file mode 100644
index 00000000..07c57ba4
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSClearUnusedBundleFilesOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1e0e1c080b28b3c45b401da4ac06f687
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSInitializeOperation.cs
new file mode 100644
index 00000000..2e6f3926
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSInitializeOperation.cs
@@ -0,0 +1,186 @@
+using System;
+using System.IO;
+
+namespace YooAsset
+{
+ internal class DBFSInitializeOperation : FSInitializeFileSystemOperation
+ {
+ private enum ESteps
+ {
+ None,
+ InitUnpackFileSystem,
+ LoadCatalogFile,
+ Done,
+ }
+
+ private readonly DefaultBuildinFileSystem _fileSystem;
+ private FSInitializeFileSystemOperation _initUnpackFIleSystemOp;
+ private LoadBuildinCatalogFileOperation _loadCatalogFileOp;
+ private ESteps _steps = ESteps.None;
+
+ internal DBFSInitializeOperation(DefaultBuildinFileSystem fileSystem)
+ {
+ _fileSystem = fileSystem;
+ }
+ internal override void InternalOnStart()
+ {
+ _steps = ESteps.InitUnpackFileSystem;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.InitUnpackFileSystem)
+ {
+ if (_initUnpackFIleSystemOp == null)
+ _initUnpackFIleSystemOp = _fileSystem.UnpackFileSystem.InitializeFileSystemAsync();
+
+ Progress = _initUnpackFIleSystemOp.Progress;
+ if (_initUnpackFIleSystemOp.IsDone == false)
+ return;
+
+ if (_initUnpackFIleSystemOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.LoadCatalogFile;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _initUnpackFIleSystemOp.Error;
+ }
+ }
+
+ if (_steps == ESteps.LoadCatalogFile)
+ {
+ if (_loadCatalogFileOp == null)
+ {
+ _loadCatalogFileOp = new LoadBuildinCatalogFileOperation(_fileSystem);
+ OperationSystem.StartOperation(_fileSystem.PackageName, _loadCatalogFileOp);
+ }
+
+ if (_loadCatalogFileOp.IsDone == false)
+ return;
+
+ if (_loadCatalogFileOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _loadCatalogFileOp.Error;
+ }
+ }
+ }
+ }
+
+ ///
+ /// 在编辑器下离线模式的兼容性初始化
+ ///
+ internal sealed class DBFSInitializeInEditorPlayModeOperation : FSInitializeFileSystemOperation
+ {
+ private enum ESteps
+ {
+ None,
+ InitUnpackFileSystem,
+ LoadPackageManifest,
+ RecordFiles,
+ Done,
+ }
+
+ private readonly DefaultBuildinFileSystem _fileSystem;
+ private FSInitializeFileSystemOperation _initUnpackFIleSystemOp;
+ private DBFSLoadPackageManifestOperation _loadPackageManifestOp;
+ private ESteps _steps = ESteps.None;
+
+ internal DBFSInitializeInEditorPlayModeOperation(DefaultBuildinFileSystem fileSystem)
+ {
+ _fileSystem = fileSystem;
+ }
+ internal override void InternalOnStart()
+ {
+ _steps = ESteps.InitUnpackFileSystem;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.InitUnpackFileSystem)
+ {
+ if (_initUnpackFIleSystemOp == null)
+ _initUnpackFIleSystemOp = _fileSystem.UnpackFileSystem.InitializeFileSystemAsync();
+
+ Progress = _initUnpackFIleSystemOp.Progress;
+ if (_initUnpackFIleSystemOp.IsDone == false)
+ return;
+
+ if (_initUnpackFIleSystemOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.LoadPackageManifest;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _initUnpackFIleSystemOp.Error;
+ }
+ }
+
+ if (_steps == ESteps.LoadPackageManifest)
+ {
+ if (_loadPackageManifestOp == null)
+ {
+ _loadPackageManifestOp = new DBFSLoadPackageManifestOperation(_fileSystem);
+ OperationSystem.StartOperation(_fileSystem.PackageName, _loadPackageManifestOp);
+ }
+
+ if (_loadPackageManifestOp.IsDone == false)
+ return;
+
+ if (_loadPackageManifestOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.RecordFiles;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _loadPackageManifestOp.Error;
+ }
+ }
+
+ if (_steps == ESteps.RecordFiles)
+ {
+ PackageManifest manifest = _loadPackageManifestOp.Result;
+ string pacakgeDirectory = _fileSystem.FileRoot;
+ DirectoryInfo rootDirectory = new DirectoryInfo(pacakgeDirectory);
+ FileInfo[] fileInfos = rootDirectory.GetFiles();
+ foreach (var fileInfo in fileInfos)
+ {
+ if (fileInfo.Extension == ".meta" || fileInfo.Extension == ".version" ||
+ fileInfo.Extension == ".hash" || fileInfo.Extension == ".bytes")
+ continue;
+
+ string fileName = fileInfo.Name;
+ if (manifest.TryGetPackageBundleByFileName(fileName, out PackageBundle value))
+ {
+ var fileWrapper = new DefaultBuildinFileSystem.FileWrapper(fileName);
+ _fileSystem.Record(value.BundleGUID, fileWrapper);
+ }
+ else
+ {
+ YooLogger.Warning($"Failed mapping file : {fileName}");
+ }
+ }
+
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSInitializeOperation.cs.meta
new file mode 100644
index 00000000..082f0edd
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSInitializeOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a15804d2ba6172a4b91f6c17245495a6
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadBundleOperation.cs
new file mode 100644
index 00000000..75e50424
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadBundleOperation.cs
@@ -0,0 +1,334 @@
+using System.IO;
+using UnityEngine;
+
+namespace YooAsset
+{
+ internal class DBFSLoadAssetBundleOperation : FSLoadBundleOperation
+ {
+ private enum ESteps
+ {
+ None,
+ UnpackAssetBundleFile,
+ LoadUnpackAssetBundle,
+ LoadBuidlinAssetBundle,
+ CheckLoadBuildinResult,
+ Done,
+ }
+
+ private readonly DefaultBuildinFileSystem _fileSystem;
+ private readonly PackageBundle _bundle;
+ private FSLoadBundleOperation _loadUnpackBundleOp;
+ private FSDownloadFileOperation _unpackBundleOp;
+ private AssetBundleCreateRequest _createRequest;
+ private bool _isWaitForAsyncComplete = false;
+ private ESteps _steps = ESteps.None;
+
+
+ internal DBFSLoadAssetBundleOperation(DefaultBuildinFileSystem fileSystem, PackageBundle bundle)
+ {
+ _fileSystem = fileSystem;
+ _bundle = bundle;
+ }
+ internal override void InternalOnStart()
+ {
+ DownloadProgress = 1f;
+ DownloadedBytes = _bundle.FileSize;
+
+ if (_fileSystem.CheckNeedUnpack(_bundle))
+ {
+ _steps = ESteps.UnpackAssetBundleFile;
+ }
+ else
+ {
+ _steps = ESteps.LoadBuidlinAssetBundle;
+ }
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.UnpackAssetBundleFile)
+ {
+ if (_unpackBundleOp == null)
+ {
+ int failedTryAgain = 0;
+ int timeout = int.MaxValue;
+ _unpackBundleOp = _fileSystem.DownloadFileAsync(_bundle, null, failedTryAgain, timeout);
+ }
+
+ if (_unpackBundleOp.IsDone == false)
+ return;
+
+ if (_unpackBundleOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.LoadUnpackAssetBundle;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _unpackBundleOp.Error;
+ }
+ }
+
+ if (_steps == ESteps.LoadUnpackAssetBundle)
+ {
+ if (_loadUnpackBundleOp == null)
+ _loadUnpackBundleOp = _fileSystem.UnpackFileSystem.LoadBundleFile(_bundle);
+
+ if (_loadUnpackBundleOp.IsDone == false)
+ return;
+
+ if (_loadUnpackBundleOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.Done;
+ Result = _loadUnpackBundleOp.Result;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _loadUnpackBundleOp.Error;
+ }
+ }
+
+ if (_steps == ESteps.LoadBuidlinAssetBundle)
+ {
+ string filePath = _fileSystem.GetBuildinFileLoadPath(_bundle);
+ if (_isWaitForAsyncComplete)
+ {
+ Result = AssetBundle.LoadFromFile(filePath);
+ }
+ else
+ {
+ _createRequest = AssetBundle.LoadFromFileAsync(filePath);
+ }
+ _steps = ESteps.CheckLoadBuildinResult;
+ }
+
+ if (_steps == ESteps.CheckLoadBuildinResult)
+ {
+ if (_createRequest != null)
+ {
+ if (_isWaitForAsyncComplete)
+ {
+ // 强制挂起主线程(注意:该操作会很耗时)
+ YooLogger.Warning("Suspend the main thread to load unity bundle.");
+ Result = _createRequest.assetBundle;
+ }
+ else
+ {
+ if (_createRequest.isDone == false)
+ return;
+ Result = _createRequest.assetBundle;
+ }
+ }
+
+ if (Result != null)
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = $"Failed to load buildin asset bundle file : {_bundle.BundleName}";
+ }
+ }
+ }
+
+ public override void WaitForAsyncComplete()
+ {
+ _isWaitForAsyncComplete = true;
+
+ while (true)
+ {
+ if (_unpackBundleOp != null)
+ {
+ if (_unpackBundleOp.IsDone == false)
+ _unpackBundleOp.WaitForAsyncComplete();
+ }
+
+ if (_loadUnpackBundleOp != null)
+ {
+ if (_loadUnpackBundleOp.IsDone == false)
+ _loadUnpackBundleOp.WaitForAsyncComplete();
+ }
+
+ // 驱动流程
+ InternalOnUpdate();
+
+ // 完成后退出
+ if (IsDone)
+ break;
+ }
+ }
+ public override void AbortDownloadOperation()
+ {
+ if (_steps == ESteps.UnpackAssetBundleFile)
+ {
+ if (_unpackBundleOp != null)
+ _unpackBundleOp.SetAbort();
+ }
+ }
+ }
+
+ internal class DBFSLoadRawBundleOperation : FSLoadBundleOperation
+ {
+ private enum ESteps
+ {
+ None,
+ UnpackRawBundleFile,
+ LoadUnpackRawBundle,
+ LoadBuildinRawBundle,
+ CheckLoadBuildinResult,
+ Done,
+ }
+
+ private readonly DefaultBuildinFileSystem _fileSystem;
+ private readonly PackageBundle _bundle;
+ private FSLoadBundleOperation _loadUnpackBundleOp;
+ private FSDownloadFileOperation _unpackBundleOp;
+ private ESteps _steps = ESteps.None;
+
+
+ internal DBFSLoadRawBundleOperation(DefaultBuildinFileSystem fileSystem, PackageBundle bundle)
+ {
+ _fileSystem = fileSystem;
+ _bundle = bundle;
+ }
+ internal override void InternalOnStart()
+ {
+ DownloadProgress = 1f;
+ DownloadedBytes = _bundle.FileSize;
+
+ if (_fileSystem.CheckNeedUnpack(_bundle))
+ {
+ _steps = ESteps.UnpackRawBundleFile;
+ }
+ else
+ {
+ _steps = ESteps.LoadBuildinRawBundle;
+ }
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.UnpackRawBundleFile)
+ {
+ if (_unpackBundleOp == null)
+ {
+ int failedTryAgain = 0;
+ int timeout = int.MaxValue;
+ _unpackBundleOp = _fileSystem.DownloadFileAsync(_bundle, null, failedTryAgain, timeout);
+ }
+
+ if (_unpackBundleOp.IsDone == false)
+ return;
+
+ if (_unpackBundleOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.LoadUnpackRawBundle;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _unpackBundleOp.Error;
+ }
+ }
+
+ if (_steps == ESteps.LoadUnpackRawBundle)
+ {
+ if (_loadUnpackBundleOp == null)
+ _loadUnpackBundleOp = _fileSystem.UnpackFileSystem.LoadBundleFile(_bundle);
+
+ if (_loadUnpackBundleOp.IsDone == false)
+ return;
+
+ if (_loadUnpackBundleOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.Done;
+ Result = _loadUnpackBundleOp.Result;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _loadUnpackBundleOp.Error;
+ }
+ }
+
+ if (_steps == ESteps.LoadBuildinRawBundle)
+ {
+ string filePath = _fileSystem.GetBuildinFileLoadPath(_bundle);
+ Result = filePath;
+ _steps = ESteps.CheckLoadBuildinResult;
+ }
+
+ if (_steps == ESteps.CheckLoadBuildinResult)
+ {
+ if (Result != null)
+ {
+ string filePath = Result as string;
+ if (File.Exists(filePath))
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = $"Can not found buildin raw bundle file : {filePath}";
+ }
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = $"Failed to load buildin raw bundle file : {_bundle.BundleName}";
+ }
+ }
+ }
+
+ public override void WaitForAsyncComplete()
+ {
+ while (true)
+ {
+ if (_unpackBundleOp != null)
+ {
+ if (_unpackBundleOp.IsDone == false)
+ _unpackBundleOp.WaitForAsyncComplete();
+ }
+
+ if (_loadUnpackBundleOp != null)
+ {
+ if (_loadUnpackBundleOp.IsDone == false)
+ _loadUnpackBundleOp.WaitForAsyncComplete();
+ }
+
+ // 驱动流程
+ InternalOnUpdate();
+
+ // 完成后退出
+ if (IsDone)
+ break;
+ }
+ }
+ public override void AbortDownloadOperation()
+ {
+ if (_steps == ESteps.UnpackRawBundleFile)
+ {
+ if (_unpackBundleOp != null)
+ _unpackBundleOp.SetAbort();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadBundleOperation.cs.meta
new file mode 100644
index 00000000..e1546aa9
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadBundleOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 99fc95c784d960c45ba9373f31fbc7fe
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadPackageManifestOperation.cs
new file mode 100644
index 00000000..37772c68
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadPackageManifestOperation.cs
@@ -0,0 +1,110 @@
+
+namespace YooAsset
+{
+ internal class DBFSLoadPackageManifestOperation : FSLoadPackageManifestOperation
+ {
+ private enum ESteps
+ {
+ None,
+ RequestBuildinPackageVersion,
+ RequestBuildinPackageHash,
+ LoadBuildinPackageManifest,
+ Done,
+ }
+
+ private readonly DefaultBuildinFileSystem _fileSystem;
+ private RequestBuildinPackageVersionOperation _requestBuildinPackageVersionOp;
+ private RequestBuildinPackageHashOperation _requestBuildinPackageHashOp;
+ private LoadBuildinPackageManifestOperation _loadBuildinPackageManifestOp;
+ private ESteps _steps = ESteps.None;
+
+
+ public DBFSLoadPackageManifestOperation(DefaultBuildinFileSystem fileSystem)
+ {
+ _fileSystem = fileSystem;
+ }
+ internal override void InternalOnStart()
+ {
+ _steps = ESteps.RequestBuildinPackageVersion;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.RequestBuildinPackageVersion)
+ {
+ if (_requestBuildinPackageVersionOp == null)
+ {
+ _requestBuildinPackageVersionOp = new RequestBuildinPackageVersionOperation(_fileSystem);
+ OperationSystem.StartOperation(_fileSystem.PackageName, _requestBuildinPackageVersionOp);
+ }
+
+ if (_requestBuildinPackageVersionOp.IsDone == false)
+ return;
+
+ if (_requestBuildinPackageVersionOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.RequestBuildinPackageHash;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _requestBuildinPackageVersionOp.Error;
+ }
+ }
+
+ if (_steps == ESteps.RequestBuildinPackageHash)
+ {
+ if (_requestBuildinPackageHashOp == null)
+ {
+ string packageVersion = _requestBuildinPackageVersionOp.PackageVersion;
+ _requestBuildinPackageHashOp = new RequestBuildinPackageHashOperation(_fileSystem, packageVersion);
+ OperationSystem.StartOperation(_fileSystem.PackageName, _requestBuildinPackageHashOp);
+ }
+
+ if (_requestBuildinPackageHashOp.IsDone == false)
+ return;
+
+ if (_requestBuildinPackageHashOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.LoadBuildinPackageManifest;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _requestBuildinPackageHashOp.Error;
+ }
+ }
+
+ if (_steps == ESteps.LoadBuildinPackageManifest)
+ {
+ if (_loadBuildinPackageManifestOp == null)
+ {
+ string packageVersion = _requestBuildinPackageVersionOp.PackageVersion;
+ string packageHash = _requestBuildinPackageHashOp.PackageHash;
+ _loadBuildinPackageManifestOp = new LoadBuildinPackageManifestOperation(_fileSystem, packageVersion, packageHash);
+ OperationSystem.StartOperation(_fileSystem.PackageName, _loadBuildinPackageManifestOp);
+ }
+
+ if (_loadBuildinPackageManifestOp.IsDone == false)
+ return;
+
+ if (_loadBuildinPackageManifestOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.Done;
+ Result = _loadBuildinPackageManifestOp.Manifest;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _loadBuildinPackageManifestOp.Error;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadPackageManifestOperation.cs.meta
new file mode 100644
index 00000000..f5b0c30b
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/DBFSLoadPackageManifestOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b55b3624add2db6489954d999b13a9ec
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal.meta
new file mode 100644
index 00000000..cf359da8
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: be1c19353672bb34ca3e4ddcb462402f
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinCatalogFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinCatalogFileOperation.cs
new file mode 100644
index 00000000..92247a38
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinCatalogFileOperation.cs
@@ -0,0 +1,63 @@
+using UnityEngine;
+
+namespace YooAsset
+{
+ internal sealed class LoadBuildinCatalogFileOperation : AsyncOperationBase
+ {
+ private enum ESteps
+ {
+ None,
+ LoadCatalog,
+ Done,
+ }
+
+ private readonly DefaultBuildinFileSystem _fileSystem;
+ private ESteps _steps = ESteps.None;
+
+
+ internal LoadBuildinCatalogFileOperation(DefaultBuildinFileSystem 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.GetBuildinCatalogFileLoadPath();
+ var catalog = Resources.Load(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;
+ }
+
+ foreach (var wrapper in catalog.Wrappers)
+ {
+ var fileWrapper = new DefaultBuildinFileSystem.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;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinCatalogFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinCatalogFileOperation.cs.meta
new file mode 100644
index 00000000..365df095
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinCatalogFileOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a4113df346bbd1b4ead918b52ac46f55
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinPackageManifestOperation.cs
new file mode 100644
index 00000000..555c6948
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinPackageManifestOperation.cs
@@ -0,0 +1,110 @@
+
+namespace YooAsset
+{
+ internal class LoadBuildinPackageManifestOperation : AsyncOperationBase
+ {
+ private enum ESteps
+ {
+ None,
+ RequestFileData,
+ VerifyFileData,
+ LoadManifest,
+ Done,
+ }
+
+ private readonly DefaultBuildinFileSystem _fileSystem;
+ private readonly string _packageVersion;
+ private readonly string _packageHash;
+ private UnityWebDataRequestOperation _webDataRequestOp;
+ private DeserializeManifestOperation _deserializer;
+ private ESteps _steps = ESteps.None;
+
+ ///
+ /// 加载的清单实例
+ ///
+ public PackageManifest Manifest { private set; get; }
+
+
+ internal LoadBuildinPackageManifestOperation(DefaultBuildinFileSystem 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.GetBuildinPackageManifestFilePath(_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 buildin 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;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinPackageManifestOperation.cs.meta
new file mode 100644
index 00000000..750e80dc
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/LoadBuildinPackageManifestOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8af9b72837c6a01428ee627011f4341b
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageHashOperation.cs
new file mode 100644
index 00000000..661f118d
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageHashOperation.cs
@@ -0,0 +1,75 @@
+
+namespace YooAsset
+{
+ internal class RequestBuildinPackageHashOperation : AsyncOperationBase
+ {
+ private enum ESteps
+ {
+ None,
+ RequestPackageHash,
+ Done,
+ }
+
+ private readonly DefaultBuildinFileSystem _fileSystem;
+ private readonly string _packageVersion;
+ private UnityWebTextRequestOperation _webTextRequestOp;
+ private ESteps _steps = ESteps.None;
+
+ ///
+ /// 包裹哈希值
+ ///
+ public string PackageHash { private set; get; }
+
+
+ internal RequestBuildinPackageHashOperation(DefaultBuildinFileSystem fileSystem, string packageVersion)
+ {
+ _fileSystem = fileSystem;
+ _packageVersion = packageVersion;
+ }
+ 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.GetBuildinPackageHashFilePath(_packageVersion);
+ string url = DownloadSystemHelper.ConvertToWWWPath(filePath);
+ _webTextRequestOp = new UnityWebTextRequestOperation(url);
+ OperationSystem.StartOperation(_fileSystem.PackageName, _webTextRequestOp);
+ }
+
+ if (_webTextRequestOp.IsDone == false)
+ return;
+
+ if (_webTextRequestOp.Status == EOperationStatus.Succeed)
+ {
+ PackageHash = _webTextRequestOp.Result;
+ if (string.IsNullOrEmpty(PackageHash))
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = $"Buildin package hash file content is empty !";
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _webTextRequestOp.Error;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageHashOperation.cs.meta
new file mode 100644
index 00000000..36f56cbc
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageHashOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b2084625d8253164aa71ef934e0690fd
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryBuildinPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageVersionOperation.cs
similarity index 54%
rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryBuildinPackageVersionOperation.cs
rename to Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageVersionOperation.cs
index b072b0cf..3b8b582f 100644
--- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryBuildinPackageVersionOperation.cs
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageVersionOperation.cs
@@ -1,17 +1,17 @@
namespace YooAsset
{
- internal class QueryBuildinPackageVersionOperation : AsyncOperationBase
+ internal class RequestBuildinPackageVersionOperation : AsyncOperationBase
{
private enum ESteps
{
None,
- LoadBuildinPackageVersionFile,
+ RequestPackageVersion,
Done,
}
- private readonly PersistentManager _persistent;
- private UnityWebDataRequester _downloader;
+ private readonly DefaultBuildinFileSystem _fileSystem;
+ private UnityWebTextRequestOperation _webTextRequestOp;
private ESteps _steps = ESteps.None;
///
@@ -20,41 +20,35 @@ namespace YooAsset
public string PackageVersion { private set; get; }
- public QueryBuildinPackageVersionOperation(PersistentManager persistent)
+ internal RequestBuildinPackageVersionOperation(DefaultBuildinFileSystem fileSystem)
{
- _persistent = persistent;
+ _fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
- _steps = ESteps.LoadBuildinPackageVersionFile;
+ _steps = ESteps.RequestPackageVersion;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
- if (_steps == ESteps.LoadBuildinPackageVersionFile)
+ if (_steps == ESteps.RequestPackageVersion)
{
- if (_downloader == null)
+ if (_webTextRequestOp == null)
{
- string filePath = _persistent.GetBuildinPackageVersionFilePath();
- string url = PersistentHelper.ConvertToWWWPath(filePath);
- _downloader = new UnityWebDataRequester();
- _downloader.SendRequest(url);
+ string filePath = _fileSystem.GetBuildinPackageVersionFilePath();
+ string url = DownloadSystemHelper.ConvertToWWWPath(filePath);
+ _webTextRequestOp = new UnityWebTextRequestOperation(url);
+ OperationSystem.StartOperation(_fileSystem.PackageName, _webTextRequestOp);
}
- if (_downloader.IsDone() == false)
+ if (_webTextRequestOp.IsDone == false)
return;
- if (_downloader.HasError())
+ if (_webTextRequestOp.Status == EOperationStatus.Succeed)
{
- _steps = ESteps.Done;
- Status = EOperationStatus.Failed;
- Error = _downloader.GetError();
- }
- else
- {
- PackageVersion = _downloader.GetText();
+ PackageVersion = _webTextRequestOp.Result;
if (string.IsNullOrEmpty(PackageVersion))
{
_steps = ESteps.Done;
@@ -67,8 +61,12 @@ namespace YooAsset
Status = EOperationStatus.Succeed;
}
}
-
- _downloader.Dispose();
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _webTextRequestOp.Error;
+ }
}
}
}
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageVersionOperation.cs.meta
new file mode 100644
index 00000000..b7939834
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultBuildinFileSystem/Operation/internal/RequestBuildinPackageVersionOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6bddb076e377b66488ec28c9dbdd18cd
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem.meta
new file mode 100644
index 00000000..896191a1
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b03f54c14ce3f6041870eaa9317d2e64
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs
new file mode 100644
index 00000000..e1c2a0ae
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs
@@ -0,0 +1,537 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+
+namespace YooAsset
+{
+ ///
+ /// 缓存文件系统
+ /// 说明:正在进行的下载器会在ResourcePackage销毁的时候执行Abort操作!
+ ///
+ internal class DefaultCacheFileSystem : IFileSystem
+ {
+ public class FileWrapper
+ {
+ public string InfoFilePath { private set; get; }
+ public string DataFilePath { private set; get; }
+ public string DataFileCRC { private set; get; }
+ public long DataFileSize { private set; get; }
+
+ public FileWrapper(string infoFilePath, string dataFilePath, string dataFileCRC, long dataFileSize)
+ {
+ InfoFilePath = infoFilePath;
+ DataFilePath = dataFilePath;
+ DataFileCRC = dataFileCRC;
+ DataFileSize = dataFileSize;
+ }
+ }
+
+ protected readonly Dictionary _downloaders = new Dictionary(1000);
+ protected readonly Dictionary _wrappers = new Dictionary(10000);
+ protected readonly Dictionary _loadedStream = new Dictionary(10000);
+ protected readonly Dictionary _dataFilePaths = new Dictionary(10000);
+ protected readonly Dictionary _infoFilePaths = new Dictionary(10000);
+ protected readonly Dictionary _tempFilePaths = new Dictionary(10000);
+ protected readonly List _removeList = new List(1000);
+ protected string _packageRoot;
+ protected string _saveFileRoot;
+ protected string _tempFileRoot;
+ protected string _manifestFileRoot;
+
+
+ ///
+ /// 包裹名称
+ ///
+ public string PackageName { private set; get; }
+
+ ///
+ /// 文件访问权限
+ ///
+ public EFileAccess FileSystemAccess
+ {
+ get
+ {
+ return EFileAccess.ReadWrite;
+ }
+ }
+
+ ///
+ /// 文件根目录
+ ///
+ public string FileRoot
+ {
+ get
+ {
+ return _packageRoot;
+ }
+ }
+
+ ///
+ /// 文件数量
+ ///
+ public int FileCount
+ {
+ get
+ {
+ return _wrappers.Count;
+ }
+ }
+
+ #region 自定义参数
+ ///
+ /// 自定义参数:远程服务接口
+ ///
+ public IRemoteServices RemoteServices { private set; get; } = null;
+
+ ///
+ /// 自定义参数:初始化的时候缓存文件校验级别
+ ///
+ public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle;
+
+ ///
+ /// 自定义参数:数据文件追加文件格式
+ ///
+ public bool AppendFileExtension { private set; get; } = false;
+
+ ///
+ /// 自定义参数:原生文件构建管线
+ ///
+ public bool RawFileBuildPipeline { private set; get; } = false;
+
+ ///
+ /// 自定义参数:启用断点续传的最小尺寸
+ ///
+ public long ResumeDownloadMinimumSize { private set; get; } = long.MaxValue;
+
+ ///
+ /// 自定义参数:断点续传下载器关注的错误码
+ ///
+ public List ResumeDownloadResponseCodes { private set; get; } = null;
+ #endregion
+
+
+ public DefaultCacheFileSystem()
+ {
+ }
+ public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync()
+ {
+ var operation = new DCFSInitializeOperation(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];
+ var operation = new DCFSLoadPackageManifestOperation(this, packageVersion, 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 DCFSRequestPackageVersionOperation(this, appendTimeTicks, timeout);
+ OperationSystem.StartOperation(PackageName, operation);
+ return operation;
+ }
+ public virtual FSClearAllBundleFilesOperation ClearAllBundleFilesAsync(params object[] args)
+ {
+ var operation = new DCFSClearAllBundleFilesOperation(this);
+ OperationSystem.StartOperation(PackageName, operation);
+ return operation;
+ }
+ public virtual FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(params object[] args)
+ {
+ PackageManifest manifest = args[0] as PackageManifest;
+ var operation = new DCFSClearUnusedBundleFilesOperation(this, manifest);
+ OperationSystem.StartOperation(PackageName, operation);
+ return operation;
+ }
+ public virtual FSDownloadFileOperation DownloadFileAsync(params object[] args)
+ {
+ PackageBundle bundle = args[0] as PackageBundle;
+ string localCopyFilePath = (string)args[1];
+ int failedTryAgain = (int)args[2];
+ int timeout = (int)args[3];
+
+ // 查询旧的下载器
+ if (_downloaders.TryGetValue(bundle.BundleGUID, out var oldDownloader))
+ {
+ oldDownloader.Reference();
+ return oldDownloader;
+ }
+
+ // 创建新的下载器
+ {
+ string mainURL;
+ string fallbackURL;
+ if (string.IsNullOrEmpty(localCopyFilePath))
+ {
+ mainURL = RemoteServices.GetRemoteMainURL(bundle.FileName);
+ fallbackURL = RemoteServices.GetRemoteFallbackURL(bundle.FileName);
+ }
+ else
+ {
+ // 注意:把本地文件路径指定为远端下载地址
+ mainURL = DownloadSystemHelper.ConvertToWWWPath(localCopyFilePath);
+ fallbackURL = mainURL;
+ }
+
+ if (bundle.FileSize >= ResumeDownloadMinimumSize)
+ {
+ var newDownloader = new DCFSDownloadResumeFileOperation(this, bundle, mainURL, fallbackURL, failedTryAgain, timeout);
+ newDownloader.Reference();
+ _downloaders.Add(bundle.BundleGUID, newDownloader);
+ OperationSystem.StartOperation(PackageName, newDownloader);
+ return newDownloader;
+ }
+ else
+ {
+ var newDownloader = new DCFSDownloadNormalFileOperation(this, bundle, mainURL, fallbackURL, failedTryAgain, timeout);
+ newDownloader.Reference();
+ _downloaders.Add(bundle.BundleGUID, newDownloader);
+ OperationSystem.StartOperation(PackageName, newDownloader);
+ return newDownloader;
+ }
+ }
+ }
+
+ public virtual void SetParameter(string name, object value)
+ {
+ if (name == "REMOTE_SERVICES")
+ {
+ RemoteServices = (IRemoteServices)value;
+ }
+ else if (name == "FILE_VERIFY_LEVEL")
+ {
+ FileVerifyLevel = (EFileVerifyLevel)value;
+ }
+ else if (name == "APPEND_FILE_EXTENSION")
+ {
+ AppendFileExtension = (bool)value;
+ }
+ else if (name == "RAW_FILE_BUILD_PIPELINE")
+ {
+ RawFileBuildPipeline = (bool)value;
+ }
+ else if (name == "RESUME_DOWNLOAD_MINMUM_SIZE")
+ {
+ ResumeDownloadMinimumSize = (long)value;
+ }
+ else if (name == "RESUME_DOWNLOAD_RESPONSE_CODES")
+ {
+ ResumeDownloadResponseCodes = (List)value;
+ }
+ else
+ {
+ YooLogger.Warning($"Invalid parameter : {name}");
+ }
+ }
+ public virtual void OnCreate(string packageName, string rootDirectory)
+ {
+ PackageName = packageName;
+
+ if (string.IsNullOrEmpty(rootDirectory))
+ rootDirectory = GetDefaultRoot();
+
+ _packageRoot = PathUtility.Combine(rootDirectory, packageName);
+ _saveFileRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.SaveFilesFolderName);
+ _tempFileRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.TempFilesFolderName);
+ _manifestFileRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.ManifestFilesFolderName);
+ }
+ public virtual void OnUpdate()
+ {
+ _removeList.Clear();
+
+ foreach (var valuePair in _downloaders)
+ {
+ var downloader = valuePair.Value;
+
+ // 注意:主动终止引用计数为零的下载任务
+ if (downloader.RefCount <= 0)
+ {
+ _removeList.Add(valuePair.Key);
+ downloader.SetAbort();
+ continue;
+ }
+
+ if (downloader.IsDone)
+ _removeList.Add(valuePair.Key);
+ }
+
+ foreach (var key in _removeList)
+ {
+ _downloaders.Remove(key);
+ }
+ }
+
+ public virtual bool Belong(PackageBundle bundle)
+ {
+ // 注意:缓存文件系统保底加载!
+ return true;
+ }
+ public virtual bool Belong(string bundleGUID)
+ {
+ // 注意:缓存文件系统保底加载!
+ return true;
+ }
+ public virtual bool Exists(PackageBundle packageBundle)
+ {
+ return _wrappers.ContainsKey(packageBundle.BundleGUID);
+ }
+ public virtual bool Exists(string bundleGUID)
+ {
+ return _wrappers.ContainsKey(bundleGUID);
+ }
+
+ public virtual bool CheckNeedDownload(PackageBundle bundle)
+ {
+ if (Belong(bundle) == false)
+ return false;
+
+ return Exists(bundle) == false;
+ }
+ public virtual bool CheckNeedUnpack(PackageBundle bundle)
+ {
+ return false;
+ }
+ public virtual bool CheckNeedImport(PackageBundle bundle)
+ {
+ if (Belong(bundle) == false)
+ return false;
+
+ return Exists(bundle) == false;
+ }
+
+ public virtual bool WriteFile(PackageBundle bundle, string copyPath)
+ {
+ if (_wrappers.ContainsKey(bundle.BundleGUID))
+ {
+ throw new Exception("Should never get here !");
+ }
+
+ string infoFilePath = GetInfoFilePath(bundle);
+ string dataFilePath = GetDataFilePath(bundle);
+
+ try
+ {
+ if (File.Exists(infoFilePath))
+ File.Delete(infoFilePath);
+ if (File.Exists(dataFilePath))
+ File.Delete(dataFilePath);
+
+ FileUtility.CreateFileDirectory(dataFilePath);
+
+ // 拷贝数据文件
+ FileInfo fileInfo = new FileInfo(copyPath);
+ fileInfo.CopyTo(dataFilePath);
+
+ // 写入文件信息
+ WriteInfoFile(infoFilePath, bundle.FileCRC, bundle.FileSize);
+ }
+ catch (Exception e)
+ {
+ YooLogger.Error($"Failed to write cache file ! {e.Message}");
+ return false;
+ }
+
+ FileWrapper wrapper = new FileWrapper(infoFilePath, dataFilePath, bundle.FileCRC, bundle.FileSize);
+ return Record(bundle.BundleGUID, wrapper);
+ }
+ public virtual bool DeleteFile(PackageBundle bundle)
+ {
+ return DeleteFile(bundle.BundleGUID);
+ }
+ public virtual bool DeleteFile(string bundleGUID)
+ {
+ if (_wrappers.TryGetValue(bundleGUID, out FileWrapper wrapper))
+ {
+ try
+ {
+ string dataFilePath = wrapper.DataFilePath;
+ FileInfo fileInfo = new FileInfo(dataFilePath);
+ if (fileInfo.Exists)
+ fileInfo.Directory.Delete(true);
+ _wrappers.Remove(bundleGUID);
+ return true;
+ }
+ catch (Exception e)
+ {
+ YooLogger.Error($"Failed to delete cache file ! {e.Message}");
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ public virtual EFileVerifyResult VerifyFile(PackageBundle bundle)
+ {
+ if (_wrappers.TryGetValue(bundle.BundleGUID, out FileWrapper wrapper) == false)
+ return EFileVerifyResult.CacheNotFound;
+
+ EFileVerifyResult result = FileSystemHelper.FileVerify(wrapper.DataFilePath, wrapper.DataFileSize, wrapper.DataFileCRC, EFileVerifyLevel.High);
+ return result;
+ }
+
+ 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)
+ {
+ if (RawFileBuildPipeline)
+ {
+ var operation = new DCFSLoadRawBundleOperation(this, bundle);
+ OperationSystem.StartOperation(PackageName, operation);
+ return operation;
+ }
+ else
+ {
+ var operation = new DCFSLoadAssetBundleOperation(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);
+
+ if (_loadedStream.TryGetValue(bundle.BundleGUID, out Stream managedStream))
+ {
+ managedStream.Close();
+ managedStream.Dispose();
+ _loadedStream.Remove(bundle.BundleGUID);
+ }
+ }
+
+ #region 内部方法
+ private readonly BufferWriter _sharedBuffer = new BufferWriter(1024);
+ public void WriteInfoFile(string filePath, string dataFileCRC, long dataFileSize)
+ {
+ using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read))
+ {
+ _sharedBuffer.Clear();
+ _sharedBuffer.WriteUTF8(dataFileCRC);
+ _sharedBuffer.WriteInt64(dataFileSize);
+ _sharedBuffer.WriteToStream(fs);
+ fs.Flush();
+ }
+ }
+ public void ReadInfoFile(string filePath, out string dataFileCRC, out long dataFileSize)
+ {
+ byte[] binaryData = FileUtility.ReadAllBytes(filePath);
+ BufferReader buffer = new BufferReader(binaryData);
+ dataFileCRC = buffer.ReadUTF8();
+ dataFileSize = buffer.ReadInt64();
+ }
+
+ protected string GetDefaultRoot()
+ {
+#if UNITY_EDITOR
+ // 注意:为了方便调试查看,编辑器下把存储目录放到项目里。
+ string projectPath = Path.GetDirectoryName(UnityEngine.Application.dataPath);
+ projectPath = PathUtility.RegularPath(projectPath);
+ return PathUtility.Combine(projectPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
+#elif UNITY_STANDALONE
+ return PathUtility.Combine(UnityEngine.Application.dataPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
+#else
+ return PathUtility.Combine(UnityEngine.Application.persistentDataPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
+#endif
+ }
+ protected string GetDataFilePath(PackageBundle bundle)
+ {
+ if (_dataFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
+ {
+ string folderName = bundle.FileHash.Substring(0, 2);
+ filePath = PathUtility.Combine(_saveFileRoot, folderName, bundle.BundleGUID, DefaultCacheFileSystemDefine.SaveBundleDataFileName);
+ if (AppendFileExtension)
+ filePath += bundle.FileExtension;
+ _dataFilePaths.Add(bundle.BundleGUID, filePath);
+ }
+ return filePath;
+ }
+ protected string GetInfoFilePath(PackageBundle bundle)
+ {
+ if (_infoFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
+ {
+ string folderName = bundle.FileHash.Substring(0, 2);
+ filePath = PathUtility.Combine(_saveFileRoot, folderName, bundle.BundleGUID, DefaultCacheFileSystemDefine.SaveBundleInfoFileName);
+ _infoFilePaths.Add(bundle.BundleGUID, filePath);
+ }
+ return filePath;
+ }
+ public string GetTempFilePath(PackageBundle bundle)
+ {
+ if (_tempFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
+ {
+ filePath = PathUtility.Combine(_tempFileRoot, bundle.BundleGUID);
+ _tempFilePaths.Add(bundle.BundleGUID, filePath);
+ }
+ return filePath;
+ }
+ public string GetFileLoadPath(PackageBundle bundle)
+ {
+ return GetDataFilePath(bundle);
+ }
+ public string GetCacheFilesRoot()
+ {
+ return _saveFileRoot;
+ }
+ public string GetCachePackageHashFilePath(string packageVersion)
+ {
+ string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion);
+ return PathUtility.Combine(_manifestFileRoot, fileName);
+ }
+ public string GetCachePackageManifestFilePath(string packageVersion)
+ {
+ string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion);
+ return PathUtility.Combine(_manifestFileRoot, fileName);
+ }
+ public string GetSandboxAppFootPrintFilePath()
+ {
+ return PathUtility.Combine(_manifestFileRoot, DefaultCacheFileSystemDefine.AppFootPrintFileName);
+ }
+ public void DeleteAllManifestFiles()
+ {
+ if (Directory.Exists(_manifestFileRoot))
+ {
+ Directory.Delete(_manifestFileRoot, true);
+ }
+ }
+ public List GetAllCachedBundleGUIDs()
+ {
+ return _wrappers.Keys.ToList();
+ }
+
+ ///
+ /// 记录缓存信息
+ ///
+ public bool Record(string bundleGUID, FileWrapper wrapper)
+ {
+ if (Exists(bundleGUID))
+ {
+ YooLogger.Error($"{nameof(DefaultCacheFileSystem)} has element : {bundleGUID}");
+ return false;
+ }
+
+ _wrappers.Add(bundleGUID, wrapper);
+ return true;
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs.meta
new file mode 100644
index 00000000..8e1ebce8
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4989ddcb6c99102429eeefffc3675ae5
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystemDefine.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystemDefine.cs
new file mode 100644
index 00000000..c607cdb6
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystemDefine.cs
@@ -0,0 +1,36 @@
+
+namespace YooAsset
+{
+ internal class DefaultCacheFileSystemDefine
+ {
+ ///
+ /// 保存的数据文件名称
+ ///
+ public const string SaveBundleDataFileName = "__data";
+
+ ///
+ /// 保存的信息文件名称
+ ///
+ public const string SaveBundleInfoFileName = "__info";
+
+ ///
+ /// 保存的资源文件的文件夹名称
+ ///
+ public const string SaveFilesFolderName = "CacheFiles";
+
+ ///
+ /// 下载的临时文件的文件夹名称
+ ///
+ public const string TempFilesFolderName = "CacheTempFiles";
+
+ ///
+ /// 保存的清单文件的文件夹名称
+ ///
+ public const string ManifestFilesFolderName = "ManifestFiles";
+
+ ///
+ /// 记录应用程序版本的文件名称
+ ///
+ public const string AppFootPrintFileName = "ApplicationFootPrint.bytes";
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystemDefine.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystemDefine.cs.meta
new file mode 100644
index 00000000..940178db
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystemDefine.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 610912866fe58794a904b43c2e24d84d
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation.meta
new file mode 100644
index 00000000..3110b708
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 09e4cebb2073ab945ac09e9099b327ad
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearAllCacheFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearAllBundleFilesOperation.cs
similarity index 60%
rename from Assets/YooAsset/Runtime/CacheSystem/Operation/ClearAllCacheFilesOperation.cs
rename to Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearAllBundleFilesOperation.cs
index deb1ac84..351524fb 100644
--- a/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearAllCacheFilesOperation.cs
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearAllBundleFilesOperation.cs
@@ -1,13 +1,9 @@
using System.Collections;
using System.Collections.Generic;
-using System.IO;
namespace YooAsset
{
- ///
- /// 清理本地包裹所有的缓存文件
- ///
- public sealed class ClearAllCacheFilesOperation : AsyncOperationBase
+ internal sealed class DCFSClearAllBundleFilesOperation : FSClearAllBundleFilesOperation
{
private enum ESteps
{
@@ -17,14 +13,15 @@ namespace YooAsset
Done,
}
- private readonly CacheManager _cache;
- private List _allCacheGUIDs;
+ private readonly DefaultCacheFileSystem _fileSystem;
+ private List _allBundleGUIDs;
private int _fileTotalCount = 0;
private ESteps _steps = ESteps.None;
- internal ClearAllCacheFilesOperation(CacheManager cache)
+
+ internal DCFSClearAllBundleFilesOperation(DefaultCacheFileSystem fileSystem)
{
- _cache = cache;
+ _fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
@@ -37,20 +34,19 @@ namespace YooAsset
if (_steps == ESteps.GetAllCacheFiles)
{
- _allCacheGUIDs = _cache.GetAllCachedGUIDs();
- _fileTotalCount = _allCacheGUIDs.Count;
+ _allBundleGUIDs = _fileSystem.GetAllCachedBundleGUIDs();
+ _fileTotalCount = _allBundleGUIDs.Count;
YooLogger.Log($"Found all cache file count : {_fileTotalCount}");
_steps = ESteps.ClearAllCacheFiles;
}
if (_steps == ESteps.ClearAllCacheFiles)
{
- for (int i = _allCacheGUIDs.Count - 1; i >= 0; i--)
+ for (int i = _allBundleGUIDs.Count - 1; i >= 0; i--)
{
- string cacheGUID = _allCacheGUIDs[i];
- _cache.Discard(cacheGUID);
- _allCacheGUIDs.RemoveAt(i);
-
+ string bundleGUID = _allBundleGUIDs[i];
+ _fileSystem.DeleteFile(bundleGUID);
+ _allBundleGUIDs.RemoveAt(i);
if (OperationSystem.IsBusy)
break;
}
@@ -58,9 +54,9 @@ namespace YooAsset
if (_fileTotalCount == 0)
Progress = 1.0f;
else
- Progress = 1.0f - (_allCacheGUIDs.Count / _fileTotalCount);
+ Progress = 1.0f - (_allBundleGUIDs.Count / _fileTotalCount);
- if (_allCacheGUIDs.Count == 0)
+ if (_allBundleGUIDs.Count == 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearAllBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearAllBundleFilesOperation.cs.meta
new file mode 100644
index 00000000..fc104aac
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearAllBundleFilesOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: daed187502431d347bf11bddcf8d77de
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearUnusedCacheFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearUnusedBundleFilesOperation.cs
similarity index 51%
rename from Assets/YooAsset/Runtime/CacheSystem/Operation/ClearUnusedCacheFilesOperation.cs
rename to Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearUnusedBundleFilesOperation.cs
index 2db369fc..1dcb7218 100644
--- a/Assets/YooAsset/Runtime/CacheSystem/Operation/ClearUnusedCacheFilesOperation.cs
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearUnusedBundleFilesOperation.cs
@@ -1,13 +1,9 @@
using System.Collections;
using System.Collections.Generic;
-using System.IO;
namespace YooAsset
{
- ///
- /// 清理本地包裹未使用的缓存文件
- ///
- public sealed class ClearUnusedCacheFilesOperation : AsyncOperationBase
+ internal sealed class DCFSClearUnusedBundleFilesOperation : FSClearUnusedBundleFilesOperation
{
private enum ESteps
{
@@ -17,16 +13,17 @@ namespace YooAsset
Done,
}
- private readonly ResourcePackage _package;
- private readonly CacheManager _cache;
- private List _unusedCacheGUIDs;
+ private readonly DefaultCacheFileSystem _fileSystem;
+ private readonly PackageManifest _manifest;
+ private List _unusedBundleGUIDs;
private int _unusedFileTotalCount = 0;
private ESteps _steps = ESteps.None;
- internal ClearUnusedCacheFilesOperation(ResourcePackage package, CacheManager cache)
+
+ internal DCFSClearUnusedBundleFilesOperation(DefaultCacheFileSystem fileSystem, PackageManifest manifest)
{
- _package = package;
- _cache = cache;
+ _fileSystem = fileSystem;
+ _manifest = manifest;
}
internal override void InternalOnStart()
{
@@ -39,20 +36,19 @@ namespace YooAsset
if (_steps == ESteps.GetUnusedCacheFiles)
{
- _unusedCacheGUIDs = GetUnusedCacheGUIDs();
- _unusedFileTotalCount = _unusedCacheGUIDs.Count;
- YooLogger.Log($"Found unused cache file count : {_unusedFileTotalCount}");
_steps = ESteps.ClearUnusedCacheFiles;
+ _unusedBundleGUIDs = GetUnusedBundleGUIDs();
+ _unusedFileTotalCount = _unusedBundleGUIDs.Count;
+ YooLogger.Log($"Found unused cache file count : {_unusedFileTotalCount}");
}
if (_steps == ESteps.ClearUnusedCacheFiles)
{
- for (int i = _unusedCacheGUIDs.Count - 1; i >= 0; i--)
+ for (int i = _unusedBundleGUIDs.Count - 1; i >= 0; i--)
{
- string cacheGUID = _unusedCacheGUIDs[i];
- _cache.Discard(cacheGUID);
- _unusedCacheGUIDs.RemoveAt(i);
-
+ string bundleGUID = _unusedBundleGUIDs[i];
+ _fileSystem.DeleteFile(bundleGUID);
+ _unusedBundleGUIDs.RemoveAt(i);
if (OperationSystem.IsBusy)
break;
}
@@ -60,9 +56,9 @@ namespace YooAsset
if (_unusedFileTotalCount == 0)
Progress = 1.0f;
else
- Progress = 1.0f - (_unusedCacheGUIDs.Count / _unusedFileTotalCount);
+ Progress = 1.0f - (_unusedBundleGUIDs.Count / _unusedFileTotalCount);
- if (_unusedCacheGUIDs.Count == 0)
+ if (_unusedBundleGUIDs.Count == 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
@@ -70,15 +66,15 @@ namespace YooAsset
}
}
- private List GetUnusedCacheGUIDs()
+ private List GetUnusedBundleGUIDs()
{
- var allCacheGUIDs = _cache.GetAllCachedGUIDs();
- List result = new List(allCacheGUIDs.Count);
- foreach (var cacheGUID in allCacheGUIDs)
+ var allBundleGUIDs = _fileSystem.GetAllCachedBundleGUIDs();
+ List result = new List(allBundleGUIDs.Count);
+ foreach (var bundleGUID in allBundleGUIDs)
{
- if (_package.IsIncludeBundleFile(cacheGUID) == false)
+ if (_manifest.IsIncludeBundleFile(bundleGUID) == false)
{
- result.Add(cacheGUID);
+ result.Add(bundleGUID);
}
}
return result;
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearUnusedBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearUnusedBundleFilesOperation.cs.meta
new file mode 100644
index 00000000..b0863b70
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSClearUnusedBundleFilesOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: be7b242f10abf524fa59e9ca0d12b052
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSDownloadFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSDownloadFileOperation.cs
new file mode 100644
index 00000000..fd2bc7bd
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSDownloadFileOperation.cs
@@ -0,0 +1,432 @@
+using System.IO;
+using UnityEngine;
+using UnityEngine.Networking;
+
+namespace YooAsset
+{
+ internal sealed class DCFSDownloadNormalFileOperation : DefaultDownloadFileOperation
+ {
+ private readonly DefaultCacheFileSystem _fileSystem;
+ private VerifyTempFileOperation _verifyOperation;
+ private string _fileSavePath;
+ private ESteps _steps = ESteps.None;
+
+ internal DCFSDownloadNormalFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string mainURL, string fallbackURL, int failedTryAgain, int timeout)
+ : base(bundle, mainURL, fallbackURL, failedTryAgain, timeout)
+ {
+ _fileSystem = fileSystem;
+ }
+ internal override void InternalOnStart()
+ {
+ _fileSavePath = _fileSystem.GetTempFilePath(Bundle);
+
+ // 注意:检测文件是否存在
+ if (_fileSystem.Exists(Bundle))
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.CreateRequest;
+ }
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ // 创建下载器
+ if (_steps == ESteps.CreateRequest)
+ {
+ FileUtility.CreateFileDirectory(_fileSavePath);
+
+ // 获取请求地址
+ _requestURL = GetRequestURL();
+
+ // 重置变量
+ _isAbort = false;
+ _latestDownloadBytes = 0;
+ _latestDownloadRealtime = Time.realtimeSinceStartup;
+ DownloadProgress = 0f;
+ DownloadedBytes = 0;
+
+ // 重置计时器
+ if (_tryAgainTimer > 0f)
+ YooLogger.Warning($"Try again download : {_requestURL}");
+ _tryAgainTimer = 0f;
+
+ // 删除临时文件
+ if (File.Exists(_fileSavePath))
+ File.Delete(_fileSavePath);
+
+ // 创建下载器
+ 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.VerifyTempFile;
+ else
+ _steps = ESteps.TryAgain;
+
+ // 注意:最终释放请求器
+ DisposeWebRequest();
+ }
+
+ // 验证下载文件
+ if (_steps == ESteps.VerifyTempFile)
+ {
+ var element = new TempFileElement(_fileSavePath, Bundle.FileCRC, Bundle.FileSize);
+ _verifyOperation = new VerifyTempFileOperation(element);
+ OperationSystem.StartOperation(_fileSystem.PackageName, _verifyOperation);
+ _steps = ESteps.CheckVerifyTempFile;
+ }
+
+ // 等待验证完成
+ if (_steps == ESteps.CheckVerifyTempFile)
+ {
+ // 注意:同步解压文件更新
+ _verifyOperation.InternalOnUpdate();
+ if (_verifyOperation.IsDone == false)
+ return;
+
+ if (_verifyOperation.Status == EOperationStatus.Succeed)
+ {
+ if (_fileSystem.WriteFile(Bundle, _fileSavePath))
+ {
+ Status = EOperationStatus.Succeed;
+ _steps = ESteps.Done;
+ }
+ else
+ {
+ Error = $"{_fileSystem.GetType().FullName} write file failed !";
+ Status = EOperationStatus.Failed;
+ _steps = ESteps.Done;
+ YooLogger.Error(Error);
+ }
+ }
+ else
+ {
+ Error = _verifyOperation.Error;
+ _steps = ESteps.TryAgain;
+ }
+
+ // 注意:验证完成后直接删除文件
+ if (File.Exists(_fileSavePath))
+ File.Delete(_fileSavePath);
+ }
+
+ // 重新尝试下载
+ 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();
+ }
+ public override void WaitForAsyncComplete()
+ {
+ while (true)
+ {
+ // 文件验证
+ if (_verifyOperation != null)
+ {
+ if (_verifyOperation.IsDone == false)
+ _verifyOperation.WaitForAsyncComplete();
+ }
+
+ // 驱动流程
+ InternalOnUpdate();
+
+ // 完成后退出
+ if (IsDone)
+ break;
+ }
+ }
+
+ private void CreateWebRequest()
+ {
+ _webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
+ DownloadHandlerFile handler = new DownloadHandlerFile(_fileSavePath);
+ handler.removeFileOnAbort = true;
+ _webRequest.downloadHandler = handler;
+ _webRequest.disposeDownloadHandlerOnDispose = true;
+ _webRequest.SendWebRequest();
+ }
+ private void DisposeWebRequest()
+ {
+ if (_webRequest != null)
+ {
+ //注意:引擎底层会自动调用Abort方法
+ _webRequest.Dispose();
+ _webRequest = null;
+ }
+ }
+ }
+
+ internal sealed class DCFSDownloadResumeFileOperation : DefaultDownloadFileOperation
+ {
+ private readonly DefaultCacheFileSystem _fileSystem;
+ private DownloadHandlerFileRange _downloadHandle;
+ private VerifyTempFileOperation _verifyOperation;
+ private long _fileOriginLength = 0;
+ private string _fileSavePath;
+ private ESteps _steps = ESteps.None;
+
+
+ internal DCFSDownloadResumeFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string mainURL, string fallbackURL, int failedTryAgain, int timeout)
+ : base(bundle, mainURL, fallbackURL, failedTryAgain, timeout)
+ {
+ _fileSystem = fileSystem;
+ }
+ internal override void InternalOnStart()
+ {
+ _fileSavePath = _fileSystem.GetTempFilePath(Bundle);
+
+ // 注意:检测文件是否存在
+ if (_fileSystem.Exists(Bundle))
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.CreateRequest;
+ }
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ // 创建下载器
+ if (_steps == ESteps.CreateRequest)
+ {
+ FileUtility.CreateFileDirectory(_fileSavePath);
+
+ // 获取请求地址
+ _requestURL = GetRequestURL();
+
+ // 重置变量
+ _isAbort = false;
+ _latestDownloadBytes = 0;
+ _latestDownloadRealtime = Time.realtimeSinceStartup;
+ _fileOriginLength = 0;
+ DownloadProgress = 0f;
+ DownloadedBytes = 0;
+
+ // 重置计时器
+ if (_tryAgainTimer > 0f)
+ YooLogger.Warning($"Try again download : {_requestURL}");
+ _tryAgainTimer = 0f;
+
+ // 获取下载起始位置
+ long fileBeginLength = -1;
+ if (File.Exists(_fileSavePath))
+ {
+ FileInfo fileInfo = new FileInfo(_fileSavePath);
+ fileBeginLength = fileInfo.Length;
+ _fileOriginLength = fileBeginLength;
+ DownloadedBytes = _fileOriginLength;
+ }
+
+ // 检测下载起始位置
+ if (fileBeginLength >= Bundle.FileSize)
+ {
+ // 删除临时文件
+ if (File.Exists(_fileSavePath))
+ File.Delete(_fileSavePath);
+ }
+
+ // 创建下载器
+ CreateWebRequest(fileBeginLength);
+
+ _steps = ESteps.CheckRequest;
+ }
+
+ // 检测下载结果
+ if (_steps == ESteps.CheckRequest)
+ {
+ DownloadProgress = _webRequest.downloadProgress;
+ DownloadedBytes = _fileOriginLength + (long)_webRequest.downloadedBytes;
+ if (_webRequest.isDone == false)
+ {
+ CheckRequestTimeout();
+ return;
+ }
+
+ // 检查网络错误
+ if (CheckRequestResult())
+ _steps = ESteps.VerifyTempFile;
+ else
+ _steps = ESteps.TryAgain;
+
+ // 在遇到特殊错误的时候删除文件
+ ClearTempFileWhenError();
+
+ // 注意:最终释放请求器
+ DisposeWebRequest();
+ }
+
+ // 验证下载文件
+ if (_steps == ESteps.VerifyTempFile)
+ {
+ var element = new TempFileElement(_fileSavePath, Bundle.FileCRC, Bundle.FileSize);
+ _verifyOperation = new VerifyTempFileOperation(element);
+ OperationSystem.StartOperation(_fileSystem.PackageName, _verifyOperation);
+ _steps = ESteps.CheckVerifyTempFile;
+ }
+
+ // 等待验证完成
+ if (_steps == ESteps.CheckVerifyTempFile)
+ {
+ if (_verifyOperation.IsDone == false)
+ return;
+
+ if (_verifyOperation.Status == EOperationStatus.Succeed)
+ {
+ if (_fileSystem.WriteFile(Bundle, _fileSavePath))
+ {
+ Status = EOperationStatus.Succeed;
+ _steps = ESteps.Done;
+ }
+ else
+ {
+ Error = $"{_fileSystem.GetType().FullName} write file failed : {_fileSavePath}";
+ Status = EOperationStatus.Failed;
+ _steps = ESteps.Done;
+ }
+ }
+ else
+ {
+ Error = _verifyOperation.Error;
+ _steps = ESteps.TryAgain;
+ }
+
+ // 注意:验证完成后直接删除文件
+ if (File.Exists(_fileSavePath))
+ File.Delete(_fileSavePath);
+ }
+
+ // 重新尝试下载
+ 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();
+ }
+ public override void WaitForAsyncComplete()
+ {
+ while (true)
+ {
+ // 文件验证
+ if (_verifyOperation != null)
+ {
+ if (_verifyOperation.IsDone == false)
+ _verifyOperation.WaitForAsyncComplete();
+ }
+
+ // 驱动流程
+ InternalOnUpdate();
+
+ // 完成后退出
+ if (IsDone)
+ break;
+ }
+ }
+
+ private void CreateWebRequest(long beginLength)
+ {
+ _webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
+#if UNITY_2019_4_OR_NEWER
+ var handler = new DownloadHandlerFile(_fileSavePath, true);
+ handler.removeFileOnAbort = false;
+#else
+ var handler = new DownloadHandlerFileRange(FileSavePath, Bundle.FileSize, _webRequest);
+ _downloadHandle = handler;
+#endif
+ _webRequest.downloadHandler = handler;
+ _webRequest.disposeDownloadHandlerOnDispose = true;
+ if (beginLength > 0)
+ _webRequest.SetRequestHeader("Range", $"bytes={beginLength}-");
+ _webRequest.SendWebRequest();
+ }
+ private void DisposeWebRequest()
+ {
+ if (_downloadHandle != null)
+ {
+ _downloadHandle.Cleanup();
+ _downloadHandle = null;
+ }
+
+ if (_webRequest != null)
+ {
+ //注意:引擎底层会自动调用Abort方法
+ _webRequest.Dispose();
+ _webRequest = null;
+ }
+ }
+ private void ClearTempFileWhenError()
+ {
+ if (_fileSystem.ResumeDownloadResponseCodes == null)
+ return;
+
+ //说明:如果遇到以下错误返回码,验证失败直接删除文件
+ if (_fileSystem.ResumeDownloadResponseCodes.Contains(HttpCode))
+ {
+ if (File.Exists(_fileSavePath))
+ File.Delete(_fileSavePath);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSDownloadFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSDownloadFileOperation.cs.meta
new file mode 100644
index 00000000..39eda641
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSDownloadFileOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d6f813e2460f55e4ba3f54527e6999e3
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSInitializeOperation.cs
new file mode 100644
index 00000000..8243a34f
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSInitializeOperation.cs
@@ -0,0 +1,87 @@
+using System.IO;
+using UnityEngine;
+
+namespace YooAsset
+{
+ internal class DCFSInitializeOperation : FSInitializeFileSystemOperation
+ {
+ private enum ESteps
+ {
+ None,
+ CheckAppFootPrint,
+ SearchCacheFiles,
+ VerifyCacheFiles,
+ Done,
+ }
+
+ private readonly DefaultCacheFileSystem _fileSytem;
+ private SearchCacheFilesOperation _searchCacheFilesOp;
+ private VerifyCacheFilesOperation _verifyCacheFilesOp;
+ private ESteps _steps = ESteps.None;
+
+
+ internal DCFSInitializeOperation(DefaultCacheFileSystem fileSystem)
+ {
+ _fileSytem = fileSystem;
+ }
+ internal override void InternalOnStart()
+ {
+ _steps = ESteps.CheckAppFootPrint;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.CheckAppFootPrint)
+ {
+ var appFootPrint = new ApplicationFootPrint(_fileSytem);
+ appFootPrint.Load(_fileSytem.PackageName);
+
+ // 如果水印发生变化,则说明覆盖安装后首次打开游戏
+ if (appFootPrint.IsDirty())
+ {
+ _fileSytem.DeleteAllManifestFiles();
+ appFootPrint.Coverage(_fileSytem.PackageName);
+ YooLogger.Log("Delete manifest files when application foot print dirty !");
+ }
+
+ _steps = ESteps.SearchCacheFiles;
+ }
+
+ if (_steps == ESteps.SearchCacheFiles)
+ {
+ if (_searchCacheFilesOp == null)
+ {
+ _searchCacheFilesOp = new SearchCacheFilesOperation(_fileSytem);
+ OperationSystem.StartOperation(_fileSytem.PackageName, _searchCacheFilesOp);
+ }
+
+ Progress = _searchCacheFilesOp.Progress;
+ if (_searchCacheFilesOp.IsDone == false)
+ return;
+
+ _steps = ESteps.VerifyCacheFiles;
+ }
+
+ if (_steps == ESteps.VerifyCacheFiles)
+ {
+ if (_verifyCacheFilesOp == null)
+ {
+ _verifyCacheFilesOp = new VerifyCacheFilesOperation(_fileSytem, _searchCacheFilesOp.Result);
+ OperationSystem.StartOperation(_fileSytem.PackageName, _verifyCacheFilesOp);
+ }
+
+ Progress = _verifyCacheFilesOp.Progress;
+ if (_verifyCacheFilesOp.IsDone == false)
+ return;
+
+ // 注意:总是返回成功
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+
+ YooLogger.Log($"Package '{_fileSytem.PackageName}' cached files count : {_fileSytem.FileCount}");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSInitializeOperation.cs.meta
new file mode 100644
index 00000000..2bac299b
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSInitializeOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 443aa31f081edfd458a90e3385a75203
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs
new file mode 100644
index 00000000..6d6e62b3
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs
@@ -0,0 +1,330 @@
+using System.IO;
+using UnityEngine;
+
+namespace YooAsset
+{
+ internal class DCFSLoadAssetBundleOperation : FSLoadBundleOperation
+ {
+ private enum ESteps
+ {
+ None,
+ DownloadFile,
+ LoadAssetBundle,
+ CheckResult,
+ Done,
+ }
+
+ private readonly DefaultCacheFileSystem _fileSystem;
+ private readonly PackageBundle _bundle;
+ private FSDownloadFileOperation _downloadFileOp;
+ private AssetBundleCreateRequest _createRequest;
+ private bool _isWaitForAsyncComplete = false;
+ private ESteps _steps = ESteps.None;
+
+
+ internal DCFSLoadAssetBundleOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle)
+ {
+ _fileSystem = fileSystem;
+ _bundle = bundle;
+ }
+ internal override void InternalOnStart()
+ {
+ if (_fileSystem.CheckNeedDownload(_bundle))
+ {
+ DownloadProgress = 0f;
+ DownloadedBytes = 0;
+ _steps = ESteps.DownloadFile;
+ }
+ else
+ {
+ DownloadProgress = 1f;
+ DownloadedBytes = _bundle.FileSize;
+ _steps = ESteps.LoadAssetBundle;
+ }
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.DownloadFile)
+ {
+ if (_downloadFileOp == null)
+ {
+ int failedTryAgain = int.MaxValue;
+ int timeout = 60;
+ _downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, null, failedTryAgain, timeout);
+ }
+
+ DownloadProgress = _downloadFileOp.DownloadProgress;
+ DownloadedBytes = _downloadFileOp.DownloadedBytes;
+ if (_downloadFileOp.IsDone == false)
+ return;
+
+ if (_downloadFileOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.LoadAssetBundle;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _downloadFileOp.Error;
+ }
+ }
+
+ if (_steps == ESteps.LoadAssetBundle)
+ {
+ string filePath = _fileSystem.GetFileLoadPath(_bundle);
+ if (_isWaitForAsyncComplete)
+ {
+ Result = AssetBundle.LoadFromFile(filePath);
+ }
+ else
+ {
+ _createRequest = AssetBundle.LoadFromFileAsync(filePath);
+ }
+ _steps = ESteps.CheckResult;
+ }
+
+ if (_steps == ESteps.CheckResult)
+ {
+ if (_createRequest != null)
+ {
+ if (_isWaitForAsyncComplete)
+ {
+ // 强制挂起主线程(注意:该操作会很耗时)
+ YooLogger.Warning("Suspend the main thread to load unity bundle.");
+ Result = _createRequest.assetBundle;
+ }
+ else
+ {
+ if (_createRequest.isDone == false)
+ return;
+ Result = _createRequest.assetBundle;
+ }
+ }
+
+ if (Result != null)
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ // 注意:当缓存文件的校验等级为Low的时候,并不能保证缓存文件的完整性。
+ // 说明:在AssetBundle文件加载失败的情况下,我们需要重新验证文件的完整性!
+ EFileVerifyResult result = _fileSystem.VerifyFile(_bundle);
+ if (result == EFileVerifyResult.Succeed)
+ {
+ // 注意:在安卓移动平台,华为和三星真机上有极小概率加载资源包失败。
+ // 说明:大多数情况在首次安装下载资源到沙盒内,游戏过程中切换到后台再回到游戏内有很大概率触发!
+ string filePath = _fileSystem.GetFileLoadPath(_bundle);
+ byte[] fileData = FileUtility.ReadAllBytes(filePath);
+ if (fileData != null && fileData.Length > 0)
+ {
+ Result = AssetBundle.LoadFromMemory(fileData);
+ if (Result == null)
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = $"Failed to load assetBundle from memory : {_bundle.BundleName}";
+ YooLogger.Error(Error);
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = $"Failed to read assetBundle file bytes : {_bundle.BundleName}";
+ YooLogger.Error(Error);
+ }
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ _fileSystem.DeleteFile(_bundle);
+ Status = EOperationStatus.Failed;
+ Error = $"Find corrupted file and delete the file : {_bundle.BundleName}";
+ YooLogger.Error(Error);
+ }
+ }
+ }
+ }
+
+ public override void WaitForAsyncComplete()
+ {
+ _isWaitForAsyncComplete = true;
+
+ int frame = 1000;
+ while (true)
+ {
+ // 保险机制
+ // 注意:如果需要从远端下载资源,可能会触发保险机制!
+ frame--;
+ if (frame == 0)
+ {
+ Status = EOperationStatus.Failed;
+ Error = $"{nameof(WaitForAsyncComplete)} failed ! Try load bundle {_bundle.BundleName} from remote with sync load method !";
+ _steps = ESteps.Done;
+ YooLogger.Error(Error);
+ }
+
+ // 驱动流程
+ InternalOnUpdate();
+
+ // 完成后退出
+ if (IsDone)
+ break;
+ }
+ }
+ public override void AbortDownloadOperation()
+ {
+ if (_steps == ESteps.DownloadFile)
+ {
+ if (_downloadFileOp != null)
+ _downloadFileOp.SetAbort();
+ }
+ }
+ }
+
+ internal class DCFSLoadRawBundleOperation : FSLoadBundleOperation
+ {
+ private enum ESteps
+ {
+ None,
+ DownloadFile,
+ LoadRawBundle,
+ CheckResult,
+ Done,
+ }
+
+ private readonly DefaultCacheFileSystem _fileSystem;
+ private readonly PackageBundle _bundle;
+ private FSDownloadFileOperation _downloadFileOp;
+ private ESteps _steps = ESteps.None;
+
+
+ internal DCFSLoadRawBundleOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle)
+ {
+ _fileSystem = fileSystem;
+ _bundle = bundle;
+ }
+ internal override void InternalOnStart()
+ {
+ if (_fileSystem.CheckNeedDownload(_bundle))
+ {
+ DownloadProgress = 0f;
+ DownloadedBytes = 0;
+ _steps = ESteps.DownloadFile;
+ }
+ else
+ {
+ DownloadProgress = 1f;
+ DownloadedBytes = _bundle.FileSize;
+ _steps = ESteps.LoadRawBundle;
+ }
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.DownloadFile)
+ {
+ if (_downloadFileOp == null)
+ {
+ int failedTryAgain = int.MaxValue;
+ int timeout = 60;
+ _downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, null, failedTryAgain, timeout);
+ }
+
+ DownloadProgress = _downloadFileOp.DownloadProgress;
+ DownloadedBytes = _downloadFileOp.DownloadedBytes;
+ if (_downloadFileOp.IsDone == false)
+ return;
+
+ if (_downloadFileOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.LoadRawBundle;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _downloadFileOp.Error;
+ }
+ }
+
+ if (_steps == ESteps.LoadRawBundle)
+ {
+ string filePath = _fileSystem.GetFileLoadPath(_bundle);
+ Result = filePath;
+ _steps = ESteps.CheckResult;
+ }
+
+ if (_steps == ESteps.CheckResult)
+ {
+ if (Result != null)
+ {
+ string filePath = Result as string;
+ if (File.Exists(filePath))
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = $"Can not found raw bundle file : {filePath}";
+ }
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = $"Failed load raw bundle file : {_bundle.BundleName}";
+ }
+ }
+ }
+
+ public override void WaitForAsyncComplete()
+ {
+ int frame = 1000;
+ while (true)
+ {
+ // 保险机制
+ // 注意:如果需要从远端下载资源,可能会触发保险机制!
+ frame--;
+ if (frame == 0)
+ {
+ Status = EOperationStatus.Failed;
+ Error = $"{nameof(WaitForAsyncComplete)} failed ! Try load bundle {_bundle.BundleName} from remote with sync load method !";
+ _steps = ESteps.Done;
+ YooLogger.Error(Error);
+ }
+
+ // 驱动流程
+ InternalOnUpdate();
+
+ // 完成后退出
+ if (IsDone)
+ break;
+ }
+ }
+ public override void AbortDownloadOperation()
+ {
+ if (_steps == ESteps.DownloadFile)
+ {
+ if (_downloadFileOp != null)
+ _downloadFileOp.SetAbort();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs.meta
new file mode 100644
index 00000000..b18d6bf9
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a653cabf995909d48935a0486db6116f
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadPackageManifestOperation.cs
new file mode 100644
index 00000000..c55fe377
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadPackageManifestOperation.cs
@@ -0,0 +1,159 @@
+using System.IO;
+
+namespace YooAsset
+{
+ internal class DCFSLoadPackageManifestOperation : FSLoadPackageManifestOperation
+ {
+ private enum ESteps
+ {
+ None,
+ DownloadPackageHash,
+ DownloadPackageManifest,
+ LoadCachePackageHash,
+ LoadCachePackageManifest,
+ Done,
+ }
+
+ private readonly DefaultCacheFileSystem _fileSystem;
+ private readonly string _packageVersion;
+ private readonly int _timeout;
+ private DownloadPackageHashOperation _downloadPackageHashOp;
+ private DownloadPackageManifestOperation _downloadPackageManifestOp;
+ private LoadCachePackageHashOperation _loadCachePackageHashOp;
+ private LoadCachePackageManifestOperation _loadCachePackageManifestOp;
+ private ESteps _steps = ESteps.None;
+
+
+ internal DCFSLoadPackageManifestOperation(DefaultCacheFileSystem fileSystem, string packageVersion, int timeout)
+ {
+ _fileSystem = fileSystem;
+ _packageVersion = packageVersion;
+ _timeout = timeout;
+ }
+ internal override void InternalOnStart()
+ {
+ _steps = ESteps.DownloadPackageHash;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.DownloadPackageHash)
+ {
+ if (_downloadPackageHashOp == null)
+ {
+ _downloadPackageHashOp = new DownloadPackageHashOperation(_fileSystem, _packageVersion, _timeout);
+ OperationSystem.StartOperation(_fileSystem.PackageName, _downloadPackageHashOp);
+ }
+
+ if (_downloadPackageHashOp.IsDone == false)
+ return;
+
+ if (_downloadPackageHashOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.DownloadPackageManifest;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _downloadPackageHashOp.Error;
+ }
+ }
+
+ if (_steps == ESteps.DownloadPackageManifest)
+ {
+ if (_downloadPackageManifestOp == null)
+ {
+ _downloadPackageManifestOp = new DownloadPackageManifestOperation(_fileSystem, _packageVersion, _timeout);
+ OperationSystem.StartOperation(_fileSystem.PackageName, _downloadPackageManifestOp);
+ }
+
+ if (_downloadPackageManifestOp.IsDone == false)
+ return;
+
+ if (_downloadPackageManifestOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.LoadCachePackageHash;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _downloadPackageManifestOp.Error;
+ }
+ }
+
+ if (_steps == ESteps.LoadCachePackageHash)
+ {
+ if (_loadCachePackageHashOp == null)
+ {
+ _loadCachePackageHashOp = new LoadCachePackageHashOperation(_fileSystem, _packageVersion);
+ OperationSystem.StartOperation(_fileSystem.PackageName, _loadCachePackageHashOp);
+ }
+
+ if (_loadCachePackageHashOp.IsDone == false)
+ return;
+
+ if (_loadCachePackageHashOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.LoadCachePackageManifest;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _loadCachePackageHashOp.Error;
+ ClearCacheFatalFile();
+ }
+ }
+
+ if (_steps == ESteps.LoadCachePackageManifest)
+ {
+ if (_loadCachePackageManifestOp == null)
+ {
+ string packageHash = _loadCachePackageHashOp.PackageHash;
+ _loadCachePackageManifestOp = new LoadCachePackageManifestOperation(_fileSystem, _packageVersion, packageHash);
+ OperationSystem.StartOperation(_fileSystem.PackageName, _loadCachePackageManifestOp);
+ }
+
+ Progress = _loadCachePackageManifestOp.Progress;
+ if (_loadCachePackageManifestOp.IsDone == false)
+ return;
+
+ if (_loadCachePackageManifestOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.Done;
+ Result = _loadCachePackageManifestOp.Manifest;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _loadCachePackageManifestOp.Error;
+ ClearCacheFatalFile();
+ }
+ }
+ }
+
+ private void ClearCacheFatalFile()
+ {
+ // 注意:如果加载沙盒内的清单报错,为了避免流程被卡住,主动把损坏的文件删除。
+ string manifestFilePath = _fileSystem.GetCachePackageManifestFilePath(_packageVersion);
+ if (File.Exists(manifestFilePath))
+ {
+ YooLogger.Warning($"Failed to load cache manifest file : {Error}");
+ YooLogger.Warning($"Invalid cache manifest file have been removed : {manifestFilePath}");
+ File.Delete(manifestFilePath);
+ }
+
+ string hashFilePath = _fileSystem.GetCachePackageHashFilePath(_packageVersion);
+ if (File.Exists(hashFilePath))
+ {
+ File.Delete(hashFilePath);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadPackageManifestOperation.cs.meta
new file mode 100644
index 00000000..33187cb4
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadPackageManifestOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2447826454481704ab785153ae89be3a
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSRequestPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSRequestPackageVersionOperation.cs
new file mode 100644
index 00000000..228f5b19
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSRequestPackageVersionOperation.cs
@@ -0,0 +1,66 @@
+
+namespace YooAsset
+{
+ internal class DCFSRequestPackageVersionOperation : FSRequestPackageVersionOperation
+ {
+ private enum ESteps
+ {
+ None,
+ GetPackageVersion,
+ Done,
+ }
+
+ private readonly DefaultCacheFileSystem _fileSystem;
+ private readonly bool _appendTimeTicks;
+ private readonly int _timeout;
+ private DefaultGetRemotePackageVersionOperation _getRemotePackageVersionOp;
+ private ESteps _steps = ESteps.None;
+
+
+ internal DCFSRequestPackageVersionOperation(DefaultCacheFileSystem 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;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSRequestPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSRequestPackageVersionOperation.cs.meta
new file mode 100644
index 00000000..001fd338
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSRequestPackageVersionOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 856b1334d67ed4d41b31a583f713c449
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal.meta
new file mode 100644
index 00000000..d5629ef8
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 3414bfb159816a74f917270b7d48c25f
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ApplicationFootPrint.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ApplicationFootPrint.cs
new file mode 100644
index 00000000..cb492ce9
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ApplicationFootPrint.cs
@@ -0,0 +1,63 @@
+using System.IO;
+using UnityEngine;
+
+namespace YooAsset
+{
+ ///
+ /// 应用程序水印
+ ///
+ internal class ApplicationFootPrint
+ {
+ private readonly DefaultCacheFileSystem _fileSystem;
+ private string _footPrint;
+
+
+ public ApplicationFootPrint(DefaultCacheFileSystem fileSystem)
+ {
+ _fileSystem = fileSystem;
+ }
+
+ ///
+ /// 读取应用程序水印
+ ///
+ public void Load(string packageName)
+ {
+ string footPrintFilePath = _fileSystem.GetSandboxAppFootPrintFilePath();
+ if (File.Exists(footPrintFilePath))
+ {
+ _footPrint = FileUtility.ReadAllText(footPrintFilePath);
+ }
+ else
+ {
+ Coverage(packageName);
+ }
+ }
+
+ ///
+ /// 检测水印是否发生变化
+ ///
+ public bool IsDirty()
+ {
+#if UNITY_EDITOR
+ return _footPrint != Application.version;
+#else
+ return _footPrint != Application.buildGUID;
+#endif
+ }
+
+ ///
+ /// 覆盖掉水印
+ ///
+ public void Coverage(string packageName)
+ {
+#if UNITY_EDITOR
+ _footPrint = Application.version;
+#else
+ _footPrint = Application.buildGUID;
+#endif
+ string footPrintFilePath = _fileSystem.GetSandboxAppFootPrintFilePath();
+ FileUtility.WriteAllText(footPrintFilePath, _footPrint);
+ YooLogger.Log($"Save application foot print : {_footPrint}");
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ApplicationFootPrint.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ApplicationFootPrint.cs.meta
new file mode 100644
index 00000000..90536b59
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/ApplicationFootPrint.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c9d96ea955bc07149a08471e33915556
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/DownloadHandlerFileRange.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadHandlerFileRange.cs
similarity index 100%
rename from Assets/YooAsset/Runtime/DownloadSystem/Requester/DownloadHandlerFileRange.cs
rename to Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadHandlerFileRange.cs
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Requester/DownloadHandlerFileRange.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadHandlerFileRange.cs.meta
similarity index 100%
rename from Assets/YooAsset/Runtime/DownloadSystem/Requester/DownloadHandlerFileRange.cs.meta
rename to Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadHandlerFileRange.cs.meta
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs
new file mode 100644
index 00000000..39fb9463
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs
@@ -0,0 +1,92 @@
+using System.IO;
+
+namespace YooAsset
+{
+ internal class DownloadPackageHashOperation : AsyncOperationBase
+ {
+ private enum ESteps
+ {
+ None,
+ CheckExist,
+ DownloadFile,
+ Done,
+ }
+
+ private readonly DefaultCacheFileSystem _fileSystem;
+ private readonly string _packageVersion;
+ private readonly int _timeout;
+ private UnityWebFileRequestOperation _webFileRequestOp;
+ private int _requestCount = 0;
+ private ESteps _steps = ESteps.None;
+
+
+ internal DownloadPackageHashOperation(DefaultCacheFileSystem fileSystem, string packageVersion, int timeout)
+ {
+ _fileSystem = fileSystem;
+ _packageVersion = packageVersion;
+ _timeout = timeout;
+ }
+ internal override void InternalOnStart()
+ {
+ _requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(DownloadPackageHashOperation));
+ _steps = ESteps.CheckExist;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.CheckExist)
+ {
+ string filePath = _fileSystem.GetCachePackageHashFilePath(_packageVersion);
+ if (File.Exists(filePath))
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.DownloadFile;
+ }
+ }
+
+ if (_steps == ESteps.DownloadFile)
+ {
+ if (_webFileRequestOp == null)
+ {
+ string savePath = _fileSystem.GetCachePackageHashFilePath(_packageVersion);
+ string fileName = YooAssetSettingsData.GetPackageHashFileName(_fileSystem.PackageName, _packageVersion);
+ string webURL = GetWebRequestURL(fileName);
+ YooLogger.Log($"Beginning to download package hash file : {webURL}");
+ _webFileRequestOp = new UnityWebFileRequestOperation(webURL, savePath, _timeout);
+ OperationSystem.StartOperation(_fileSystem.PackageName, _webFileRequestOp);
+ }
+
+ if (_webFileRequestOp.IsDone == false)
+ return;
+
+ if (_webFileRequestOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _webFileRequestOp.Error;
+ WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(DownloadPackageHashOperation));
+ }
+ }
+ }
+
+ private string GetWebRequestURL(string fileName)
+ {
+ // 轮流返回请求地址
+ if (_requestCount % 2 == 0)
+ return _fileSystem.RemoteServices.GetRemoteMainURL(fileName);
+ else
+ return _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs.meta
new file mode 100644
index 00000000..4dc9a9b4
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageHashOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8604af2bf2c8a1d4684cb59d81ab9445
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs
new file mode 100644
index 00000000..e14bc2c4
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs
@@ -0,0 +1,92 @@
+using System.IO;
+
+namespace YooAsset
+{
+ internal class DownloadPackageManifestOperation : AsyncOperationBase
+ {
+ private enum ESteps
+ {
+ None,
+ CheckExist,
+ DownloadFile,
+ Done,
+ }
+
+ private readonly DefaultCacheFileSystem _fileSystem;
+ private readonly string _packageVersion;
+ private readonly int _timeout;
+ private UnityWebFileRequestOperation _webFileRequestOp;
+ private int _requestCount = 0;
+ private ESteps _steps = ESteps.None;
+
+
+ internal DownloadPackageManifestOperation(DefaultCacheFileSystem fileSystem, string packageVersion, int timeout)
+ {
+ _fileSystem = fileSystem;
+ _packageVersion = packageVersion;
+ _timeout = timeout;
+ }
+ internal override void InternalOnStart()
+ {
+ _requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(DownloadPackageManifestOperation));
+ _steps = ESteps.DownloadFile;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.CheckExist)
+ {
+ string filePath = _fileSystem.GetCachePackageManifestFilePath(_packageVersion);
+ if (File.Exists(filePath))
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.DownloadFile;
+ }
+ }
+
+ if (_steps == ESteps.DownloadFile)
+ {
+ if (_webFileRequestOp == null)
+ {
+ string savePath = _fileSystem.GetCachePackageManifestFilePath(_packageVersion);
+ string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_fileSystem.PackageName, _packageVersion);
+ string webURL = GetDownloadRequestURL(fileName);
+ YooLogger.Log($"Beginning to download package manifest file : {webURL}");
+ _webFileRequestOp = new UnityWebFileRequestOperation(webURL, savePath, _timeout);
+ OperationSystem.StartOperation(_fileSystem.PackageName, _webFileRequestOp);
+ }
+
+ if (_webFileRequestOp.IsDone == false)
+ return;
+
+ if (_webFileRequestOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _webFileRequestOp.Error;
+ WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(DownloadPackageManifestOperation));
+ }
+ }
+ }
+
+ private string GetDownloadRequestURL(string fileName)
+ {
+ // 轮流返回请求地址
+ if (_requestCount % 2 == 0)
+ return _fileSystem.RemoteServices.GetRemoteMainURL(fileName);
+ else
+ return _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs.meta
new file mode 100644
index 00000000..0a5383c6
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadPackageManifestOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 9d5983f1b32b2e14c8b4c5b539bee8fa
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryCachePackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs
similarity index 74%
rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryCachePackageHashOperation.cs
rename to Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs
index 72f8ed9a..94d1bc32 100644
--- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/QueryCachePackageHashOperation.cs
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs
@@ -2,16 +2,16 @@
namespace YooAsset
{
- internal class QueryCachePackageHashOperation : AsyncOperationBase
+ internal class LoadCachePackageHashOperation : AsyncOperationBase
{
private enum ESteps
{
None,
- LoadCachePackageHashFile,
+ LoadPackageHash,
Done,
}
- private readonly PersistentManager _persistent;
+ private readonly DefaultCacheFileSystem _fileSystem;
private readonly string _packageVersion;
private ESteps _steps = ESteps.None;
@@ -21,23 +21,23 @@ namespace YooAsset
public string PackageHash { private set; get; }
- public QueryCachePackageHashOperation(PersistentManager persistent, string packageVersion)
+ internal LoadCachePackageHashOperation(DefaultCacheFileSystem fileSystem, string packageVersion)
{
- _persistent = persistent;
+ _fileSystem = fileSystem;
_packageVersion = packageVersion;
}
internal override void InternalOnStart()
{
- _steps = ESteps.LoadCachePackageHashFile;
+ _steps = ESteps.LoadPackageHash;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
- if (_steps == ESteps.LoadCachePackageHashFile)
+ if (_steps == ESteps.LoadPackageHash)
{
- string filePath = _persistent.GetSandboxPackageHashFilePath(_packageVersion);
+ string filePath = _fileSystem.GetCachePackageHashFilePath(_packageVersion);
if (File.Exists(filePath) == false)
{
_steps = ESteps.Done;
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs.meta
new file mode 100644
index 00000000..ef75bc8e
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageHashOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: db66f75d31bfeca4e897e9ee0946b1de
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs
new file mode 100644
index 00000000..1d2df41f
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs
@@ -0,0 +1,102 @@
+using System.IO;
+
+namespace YooAsset
+{
+ internal class LoadCachePackageManifestOperation : AsyncOperationBase
+ {
+ private enum ESteps
+ {
+ None,
+ LoadFileData,
+ VerifyFileData,
+ LoadManifest,
+ Done,
+ }
+
+ private readonly DefaultCacheFileSystem _fileSystem;
+ private readonly string _packageVersion;
+ private readonly string _packageHash;
+ private DeserializeManifestOperation _deserializer;
+ private byte[] _fileData;
+ private ESteps _steps = ESteps.None;
+
+ ///
+ /// 加载的清单实例
+ ///
+ public PackageManifest Manifest { private set; get; }
+
+
+ internal LoadCachePackageManifestOperation(DefaultCacheFileSystem fileSystem, string packageVersion, string packageHash)
+ {
+ _fileSystem = fileSystem;
+ _packageVersion = packageVersion;
+ _packageHash = packageHash;
+ }
+ internal override void InternalOnStart()
+ {
+ _steps = ESteps.LoadFileData;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.LoadFileData)
+ {
+ string manifestFilePath = _fileSystem.GetCachePackageManifestFilePath(_packageVersion);
+ if (File.Exists(manifestFilePath))
+ {
+ _steps = ESteps.VerifyFileData;
+ _fileData = File.ReadAllBytes(manifestFilePath);
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = $"Cache manifest file not found : {manifestFilePath}";
+ }
+ }
+
+ if (_steps == ESteps.VerifyFileData)
+ {
+ string fileHash = HashUtility.BytesMD5(_fileData);
+ if (fileHash == _packageHash)
+ {
+ _steps = ESteps.LoadManifest;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = "Failed to verify cache package manifest file!";
+ }
+ }
+
+ if (_steps == ESteps.LoadManifest)
+ {
+ if (_deserializer == null)
+ {
+ _deserializer = new DeserializeManifestOperation(_fileData);
+ 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;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs.meta
new file mode 100644
index 00000000..06a58497
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/LoadCachePackageManifestOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: acd84795f7cc3e348ab2b6cde03c8a22
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/FindCacheFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs
similarity index 61%
rename from Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/FindCacheFilesOperation.cs
rename to Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs
index da6d2f8f..f17fa16c 100644
--- a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/FindCacheFilesOperation.cs
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs
@@ -5,18 +5,17 @@ using System.Collections.Generic;
namespace YooAsset
{
- internal sealed class FindCacheFilesOperation : AsyncOperationBase
+ internal sealed class SearchCacheFilesOperation : AsyncOperationBase
{
private enum ESteps
{
None,
Prepare,
- UpdateCacheFiles,
+ SearchFiles,
Done,
}
- private readonly PersistentManager _persistent;
- private readonly CacheManager _cache;
+ private readonly DefaultCacheFileSystem _fileSystem;
private IEnumerator _filesEnumerator = null;
private float _verifyStartTime;
private ESteps _steps = ESteps.None;
@@ -24,12 +23,12 @@ namespace YooAsset
///
/// 需要验证的元素
///
- public readonly List VerifyElements = new List(5000);
+ public readonly List Result = new List(5000);
- public FindCacheFilesOperation(PersistentManager persistent, CacheManager cache)
+
+ internal SearchCacheFilesOperation(DefaultCacheFileSystem fileSystem)
{
- _persistent = persistent;
- _cache = cache;
+ _fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
@@ -43,30 +42,29 @@ namespace YooAsset
if (_steps == ESteps.Prepare)
{
- string rootPath = _persistent.SandboxCacheFilesRoot;
- DirectoryInfo rootDirectory = new DirectoryInfo(rootPath);
+ DirectoryInfo rootDirectory = new DirectoryInfo(_fileSystem.GetCacheFilesRoot());
if (rootDirectory.Exists)
{
var directorieInfos = rootDirectory.EnumerateDirectories();
_filesEnumerator = directorieInfos.GetEnumerator();
}
- _steps = ESteps.UpdateCacheFiles;
+ _steps = ESteps.SearchFiles;
}
- if (_steps == ESteps.UpdateCacheFiles)
+ if (_steps == ESteps.SearchFiles)
{
- if (UpdateCacheFiles())
+ if (SearchFiles())
return;
// 注意:总是返回成功
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime;
- YooLogger.Log($"Find cache files elapsed time {costTime:f1} seconds");
+ YooLogger.Log($"Search cache files elapsed time {costTime:f1} seconds");
}
}
- private bool UpdateCacheFiles()
+ private bool SearchFiles()
{
if (_filesEnumerator == null)
return false;
@@ -82,29 +80,25 @@ namespace YooAsset
var childDirectories = rootFoder.GetDirectories();
foreach (var chidDirectory in childDirectories)
{
- string cacheGUID = chidDirectory.Name;
- if (_cache.IsCached(cacheGUID))
+ string bundleGUID = chidDirectory.Name;
+ if (_fileSystem.Exists(bundleGUID))
continue;
// 创建验证元素类
string fileRootPath = chidDirectory.FullName;
- string dataFilePath = $"{fileRootPath}/{ YooAssetSettings.CacheBundleDataFileName}";
- string infoFilePath = $"{fileRootPath}/{ YooAssetSettings.CacheBundleInfoFileName}";
- string dataFileExtension = FindDataFileExtension(chidDirectory);
+ string dataFilePath = $"{fileRootPath}/{ DefaultCacheFileSystemDefine.SaveBundleDataFileName}";
+ string infoFilePath = $"{fileRootPath}/{ DefaultCacheFileSystemDefine.SaveBundleInfoFileName}";
- // 跳过断点续传的临时文件
- if (dataFileExtension == ".temp")
- continue;
-
- // 注意:根据配置需求数据文件会带文件格式
- if (_persistent.AppendFileExtension)
+ // 存储的数据文件追加文件格式
+ if (_fileSystem.AppendFileExtension)
{
+ string dataFileExtension = FindDataFileExtension(chidDirectory);
if (string.IsNullOrEmpty(dataFileExtension) == false)
dataFilePath += dataFileExtension;
}
- VerifyCacheFileElement element = new VerifyCacheFileElement(_cache.PackageName, cacheGUID, fileRootPath, dataFilePath, infoFilePath);
- VerifyElements.Add(element);
+ var element = new CacheFileElement(_fileSystem.PackageName, bundleGUID, fileRootPath, dataFilePath, infoFilePath);
+ Result.Add(element);
}
if (OperationSystem.IsBusy)
@@ -119,7 +113,7 @@ namespace YooAsset
var fileInfos = directoryInfo.GetFiles();
foreach (var fileInfo in fileInfos)
{
- if (fileInfo.Name.StartsWith(YooAssetSettings.CacheBundleDataFileName))
+ if (fileInfo.Name.StartsWith(DefaultCacheFileSystemDefine.SaveBundleDataFileName))
{
dataFileExtension = fileInfo.Extension;
break;
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs.meta
new file mode 100644
index 00000000..e977ef00
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/SearchCacheFilesOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8adb017a806563548b1d4c47f7b343e2
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs
new file mode 100644
index 00000000..8459ebf9
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs
@@ -0,0 +1,205 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading;
+
+namespace YooAsset
+{
+ internal class CacheFileElement
+ {
+ public string PackageName { private set; get; }
+ public string BundleGUID { private set; get; }
+ public string FileRootPath { private set; get; }
+ public string DataFilePath { private set; get; }
+ public string InfoFilePath { private set; get; }
+
+ public EFileVerifyResult Result;
+ public string DataFileCRC;
+ public long DataFileSize;
+
+ public CacheFileElement(string packageName, string bundleGUID, string fileRootPath, string dataFilePath, string infoFilePath)
+ {
+ PackageName = packageName;
+ BundleGUID = bundleGUID;
+ FileRootPath = fileRootPath;
+ DataFilePath = dataFilePath;
+ InfoFilePath = infoFilePath;
+ }
+
+ public void DeleteFiles()
+ {
+ try
+ {
+ Directory.Delete(FileRootPath, true);
+ }
+ catch (System.Exception e)
+ {
+ YooLogger.Warning($"Failed delete cache bundle folder : {e}");
+ }
+ }
+ }
+
+ ///
+ /// 缓存文件验证(线程版)
+ ///
+ internal class VerifyCacheFilesOperation : AsyncOperationBase
+ {
+ private enum ESteps
+ {
+ None,
+ InitVerify,
+ UpdateVerify,
+ Done,
+ }
+
+ private readonly ThreadSyncContext _syncContext = new ThreadSyncContext();
+ private readonly DefaultCacheFileSystem _fileSystem;
+ private List _waitingList;
+ private List _verifyingList;
+ private EFileVerifyLevel _verifyLevel = EFileVerifyLevel.Middle;
+ private int _verifyMaxNum;
+ private int _verifyTotalCount;
+ private float _verifyStartTime;
+ private int _succeedCount;
+ private int _failedCount;
+ private ESteps _steps = ESteps.None;
+
+
+ internal VerifyCacheFilesOperation(DefaultCacheFileSystem fileSystem, List elements)
+ {
+ _fileSystem = fileSystem;
+ _waitingList = elements;
+ _verifyLevel = _fileSystem.FileVerifyLevel;
+ }
+ internal override void InternalOnStart()
+ {
+ _steps = ESteps.InitVerify;
+ _verifyStartTime = UnityEngine.Time.realtimeSinceStartup;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.InitVerify)
+ {
+ int fileCount = _waitingList.Count;
+
+ // 设置同时验证的最大数
+ ThreadPool.GetMaxThreads(out int workerThreads, out int ioThreads);
+ YooLogger.Log($"Work threads : {workerThreads}, IO threads : {ioThreads}");
+ _verifyMaxNum = Math.Min(workerThreads, ioThreads);
+ _verifyTotalCount = fileCount;
+ if (_verifyMaxNum < 1)
+ _verifyMaxNum = 1;
+
+ _verifyingList = new List(_verifyMaxNum);
+ _steps = ESteps.UpdateVerify;
+ }
+
+ if (_steps == ESteps.UpdateVerify)
+ {
+ _syncContext.Update();
+
+ Progress = GetProgress();
+ if (_waitingList.Count == 0 && _verifyingList.Count == 0)
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime;
+ YooLogger.Log($"Verify cache files elapsed time {costTime:f1} seconds");
+ }
+
+ for (int i = _waitingList.Count - 1; i >= 0; i--)
+ {
+ if (OperationSystem.IsBusy)
+ break;
+
+ if (_verifyingList.Count >= _verifyMaxNum)
+ break;
+
+ var element = _waitingList[i];
+ if (BeginVerifyFileWithThread(element))
+ {
+ _waitingList.RemoveAt(i);
+ _verifyingList.Add(element);
+ }
+ else
+ {
+ YooLogger.Warning("The thread pool is failed queued.");
+ break;
+ }
+ }
+ }
+ }
+
+ private float GetProgress()
+ {
+ if (_verifyTotalCount == 0)
+ return 1f;
+ return (float)(_succeedCount + _failedCount) / _verifyTotalCount;
+ }
+ private bool BeginVerifyFileWithThread(CacheFileElement element)
+ {
+ return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element);
+ }
+ private void VerifyInThread(object obj)
+ {
+ CacheFileElement element = (CacheFileElement)obj;
+ element.Result = VerifyingCacheFile(element, _verifyLevel);
+ _syncContext.Post(VerifyCallback, element);
+ }
+ private void VerifyCallback(object obj)
+ {
+ CacheFileElement element = (CacheFileElement)obj;
+ _verifyingList.Remove(element);
+
+ if (element.Result == EFileVerifyResult.Succeed)
+ {
+ _succeedCount++;
+ var fileWrapper = new DefaultCacheFileSystem.FileWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize);
+ _fileSystem.Record(element.BundleGUID, fileWrapper);
+ }
+ else
+ {
+ _failedCount++;
+
+ YooLogger.Warning($"Failed verify file {element.Result} and delete files : {element.FileRootPath}");
+ element.DeleteFiles();
+ }
+ }
+
+ ///
+ /// 验证缓存文件(子线程内操作)
+ ///
+ private EFileVerifyResult VerifyingCacheFile(CacheFileElement element, EFileVerifyLevel verifyLevel)
+ {
+ try
+ {
+ if (verifyLevel == EFileVerifyLevel.Low)
+ {
+ if (File.Exists(element.InfoFilePath) == false)
+ return EFileVerifyResult.InfoFileNotExisted;
+ if (File.Exists(element.DataFilePath) == false)
+ return EFileVerifyResult.DataFileNotExisted;
+ return EFileVerifyResult.Succeed;
+ }
+ else
+ {
+ if (File.Exists(element.InfoFilePath) == false)
+ return EFileVerifyResult.InfoFileNotExisted;
+
+ // 解析信息文件获取验证数据
+ _fileSystem.ReadInfoFile(element.InfoFilePath, out element.DataFileCRC, out element.DataFileSize);
+ }
+ }
+ catch (Exception)
+ {
+ return EFileVerifyResult.Exception;
+ }
+
+ return FileSystemHelper.FileVerify(element.DataFilePath, element.DataFileSize, element.DataFileCRC, verifyLevel);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyCacheFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs.meta
similarity index 83%
rename from Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyCacheFilesOperation.cs.meta
rename to Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs.meta
index c0aa9baf..62a7722f 100644
--- a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyCacheFilesOperation.cs.meta
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyCacheFilesOperation.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 868188d19436b674b8c403d2d90afeaf
+guid: 5e9325baa24ae234ea0208d70dd3347e
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyTempFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyTempFileOperation.cs
new file mode 100644
index 00000000..b3fa80a0
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyTempFileOperation.cs
@@ -0,0 +1,112 @@
+using System;
+using System.Threading;
+
+namespace YooAsset
+{
+ internal class TempFileElement
+ {
+ public string TempFilePath { private set; get; }
+ public string TempFileCRC { private set; get; }
+ public long TempFileSize { private set; get; }
+
+ ///
+ /// 注意:原子操作对象
+ ///
+ public int Result = 0;
+
+ public TempFileElement(string filePath, string fileCRC, long fileSize)
+ {
+ TempFilePath = filePath;
+ TempFileCRC = fileCRC;
+ TempFileSize = fileSize;
+ }
+ }
+
+ ///
+ /// 下载文件验证(线程版)
+ ///
+ internal class VerifyTempFileOperation : AsyncOperationBase
+ {
+ private enum ESteps
+ {
+ None,
+ VerifyFile,
+ Waiting,
+ Done,
+ }
+
+ private readonly TempFileElement _element;
+ private ESteps _steps = ESteps.None;
+
+ ///
+ /// 验证结果
+ ///
+ public EFileVerifyResult VerifyResult { protected set; get; }
+
+
+ internal VerifyTempFileOperation(TempFileElement element)
+ {
+ _element = element;
+ }
+ internal override void InternalOnStart()
+ {
+ _steps = ESteps.VerifyFile;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.VerifyFile)
+ {
+ if (BeginVerifyFileWithThread(_element))
+ {
+ _steps = ESteps.Waiting;
+ }
+ }
+
+ if (_steps == ESteps.Waiting)
+ {
+ int result = _element.Result;
+ if (result == 0)
+ return;
+
+ VerifyResult = (EFileVerifyResult)result;
+ if (VerifyResult == EFileVerifyResult.Succeed)
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = $"Failed verify file : {_element.TempFilePath} ! ErrorCode : {VerifyResult}";
+ }
+ }
+ }
+ public override void WaitForAsyncComplete()
+ {
+ while (true)
+ {
+ // 驱动流程
+ InternalOnUpdate();
+
+ // 完成后退出
+ if (IsDone)
+ break;
+ }
+ }
+
+ private bool BeginVerifyFileWithThread(TempFileElement element)
+ {
+ return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element);
+ }
+ private void VerifyInThread(object obj)
+ {
+ TempFileElement element = (TempFileElement)obj;
+ int result = (int)FileSystemHelper.FileVerify(element.TempFilePath, element.TempFileSize, element.TempFileCRC, EFileVerifyLevel.High);
+ element.Result = result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyTempFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyTempFileOperation.cs.meta
similarity index 83%
rename from Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyTempFileOperation.cs.meta
rename to Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyTempFileOperation.cs.meta
index 9abd50f2..36ed7d72 100644
--- a/Assets/YooAsset/Runtime/CacheSystem/Operation/Internal/VerifyTempFileOperation.cs.meta
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/VerifyTempFileOperation.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: cd356e68c5b4ef04ab018a6388f5173a
+guid: 764ac4f47afd3be4a8d583578f51126d
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem.meta
new file mode 100644
index 00000000..93b1ffb0
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ca2dc2186da7a2847b300c398600e472
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystem.cs
new file mode 100644
index 00000000..efe00e2d
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystem.cs
@@ -0,0 +1,206 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace YooAsset
+{
+ ///
+ /// 内置文件系统
+ ///
+ internal class DefaultEditorFileSystem : IFileSystem
+ {
+ protected string _packageRoot;
+
+
+ ///
+ /// 包裹名称
+ ///
+ public string PackageName { private set; get; }
+
+ ///
+ /// 文件访问权限
+ ///
+ public EFileAccess FileSystemAccess
+ {
+ get
+ {
+ return EFileAccess.Read;
+ }
+ }
+
+ ///
+ /// 文件根目录
+ ///
+ public string FileRoot
+ {
+ get
+ {
+ return _packageRoot;
+ }
+ }
+
+ ///
+ /// 文件数量
+ ///
+ public int FileCount
+ {
+ get
+ {
+ return 0;
+ }
+ }
+
+ #region 自定义参数
+ ///
+ /// 自定义参数:模拟运行的资源清单文件路径
+ ///
+ public string SimulateManifestFilePath { private set; get; } = string.Empty;
+ #endregion
+
+
+ public DefaultEditorFileSystem()
+ {
+ }
+ public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync()
+ {
+ var operation = new DEFSInitializeOperation(this);
+ OperationSystem.StartOperation(PackageName, operation);
+ return operation;
+ }
+ public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(params object[] args)
+ {
+ var operation = new DEFSLoadPackageManifestOperation(this);
+ OperationSystem.StartOperation(PackageName, operation);
+ return operation;
+ }
+ public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(params object[] args)
+ {
+ throw new System.NotImplementedException();
+ }
+ public virtual FSClearAllBundleFilesOperation ClearAllBundleFilesAsync(params object[] args)
+ {
+ var operation = new DEFSClearAllBundleFilesOperation(this);
+ OperationSystem.StartOperation(PackageName, operation);
+ return operation;
+ }
+ public virtual FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(params object[] args)
+ {
+ var operation = new DEFSClearUnusedBundleFilesOperation(this);
+ OperationSystem.StartOperation(PackageName, operation);
+ return operation;
+ }
+ public virtual FSDownloadFileOperation DownloadFileAsync(params object[] args)
+ {
+ PackageBundle bundle = args[0] as PackageBundle;
+ var operation = new DEFSDownloadFileOperation(bundle);
+ OperationSystem.StartOperation(PackageName, operation);
+ return operation;
+ }
+
+ public virtual void SetParameter(string name, object value)
+ {
+ if (name == "SIMULATE_MANIFEST_FILE_PATH")
+ {
+ SimulateManifestFilePath = (string)value;
+ }
+ else
+ {
+ YooLogger.Warning($"Invalid parameter : {name}");
+ }
+ }
+ public virtual void OnCreate(string packageName, string rootDirectory)
+ {
+ PackageName = packageName;
+
+ if (string.IsNullOrEmpty(rootDirectory))
+ rootDirectory = GetDefaultRoot();
+
+ _packageRoot = 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 true;
+ }
+ public virtual bool Exists(string bundleGUID)
+ {
+ return true;
+ }
+
+ 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)
+ {
+ return true;
+ }
+ public virtual bool DeleteFile(PackageBundle bundle)
+ {
+ return true;
+ }
+ public virtual bool DeleteFile(string bundleGUID)
+ {
+ return true;
+ }
+ 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 DEFSLoadBundleOperation(this, bundle);
+ OperationSystem.StartOperation(PackageName, operation);
+ return operation;
+ }
+ public virtual void UnloadBundleFile(PackageBundle bundle, object result)
+ {
+ }
+
+ #region 内部方法
+ protected string GetDefaultRoot()
+ {
+ return "Assets/";
+ }
+
+ ///
+ /// 记录缓存信息
+ ///
+ public bool Record(string bundleGUID, object value)
+ {
+ return true;
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystem.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystem.cs.meta
new file mode 100644
index 00000000..0f3718ce
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystem.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 53f40d241c7bcf340841a33459678568
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystemDefine.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystemDefine.cs
new file mode 100644
index 00000000..eb0771e2
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystemDefine.cs
@@ -0,0 +1,7 @@
+
+namespace YooAsset
+{
+ internal class DefaultEditorFileSystemDefine
+ {
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystemDefine.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystemDefine.cs.meta
new file mode 100644
index 00000000..75b6d175
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/DefaultEditorFileSystemDefine.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d6d4ba58bf1a1bb4db469b2cdd741ad0
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation.meta
new file mode 100644
index 00000000..1919e6f9
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 3779423aa03ffb6499efda626280c72a
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearAllBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearAllBundleFilesOperation.cs
new file mode 100644
index 00000000..557bb425
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearAllBundleFilesOperation.cs
@@ -0,0 +1,20 @@
+
+namespace YooAsset
+{
+ internal sealed class DEFSClearAllBundleFilesOperation : FSClearAllBundleFilesOperation
+ {
+ private readonly DefaultEditorFileSystem _fileSystem;
+
+ internal DEFSClearAllBundleFilesOperation(DefaultEditorFileSystem fileSystem)
+ {
+ _fileSystem = fileSystem;
+ }
+ internal override void InternalOnStart()
+ {
+ Status = EOperationStatus.Succeed;
+ }
+ internal override void InternalOnUpdate()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearAllBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearAllBundleFilesOperation.cs.meta
new file mode 100644
index 00000000..982b339a
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearAllBundleFilesOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a16dae8497d54984daa95a3682a7beb4
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearUnusedBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearUnusedBundleFilesOperation.cs
new file mode 100644
index 00000000..268f1043
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearUnusedBundleFilesOperation.cs
@@ -0,0 +1,20 @@
+
+namespace YooAsset
+{
+ internal sealed class DEFSClearUnusedBundleFilesOperation : FSClearUnusedBundleFilesOperation
+ {
+ private readonly DefaultEditorFileSystem _fileSystem;
+
+ internal DEFSClearUnusedBundleFilesOperation(DefaultEditorFileSystem fileSystem)
+ {
+ _fileSystem = fileSystem;
+ }
+ internal override void InternalOnStart()
+ {
+ Status = EOperationStatus.Succeed;
+ }
+ internal override void InternalOnUpdate()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearUnusedBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearUnusedBundleFilesOperation.cs.meta
new file mode 100644
index 00000000..abf8526f
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSClearUnusedBundleFilesOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1f86d3bce4381694b8c619ceda2e7309
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSDownloadFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSDownloadFileOperation.cs
new file mode 100644
index 00000000..bf8f3ff1
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSDownloadFileOperation.cs
@@ -0,0 +1,17 @@
+
+namespace YooAsset
+{
+ internal class DEFSDownloadFileOperation : FSDownloadFileOperation
+ {
+ internal DEFSDownloadFileOperation(PackageBundle bundle) : base(bundle)
+ {
+ }
+ internal override void InternalOnStart()
+ {
+ Status = EOperationStatus.Succeed;
+ }
+ internal override void InternalOnUpdate()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSDownloadFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSDownloadFileOperation.cs.meta
new file mode 100644
index 00000000..3e8607bb
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSDownloadFileOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 06a8abe71cf3fe64180ec076a79b4b66
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSInitializeOperation.cs
new file mode 100644
index 00000000..8172e85e
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSInitializeOperation.cs
@@ -0,0 +1,20 @@
+
+namespace YooAsset
+{
+ internal class DEFSInitializeOperation : FSInitializeFileSystemOperation
+ {
+ private readonly DefaultEditorFileSystem _fileSytem;
+
+ internal DEFSInitializeOperation(DefaultEditorFileSystem fileSystem)
+ {
+ _fileSytem = fileSystem;
+ }
+ internal override void InternalOnStart()
+ {
+ Status = EOperationStatus.Succeed;
+ }
+ internal override void InternalOnUpdate()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSInitializeOperation.cs.meta
new file mode 100644
index 00000000..01a90c46
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSInitializeOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 99cfeba8095613442992a0e21a248b73
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadBundleOperation.cs
new file mode 100644
index 00000000..c5119f17
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadBundleOperation.cs
@@ -0,0 +1,31 @@
+
+namespace YooAsset
+{
+ internal class DEFSLoadBundleOperation : FSLoadBundleOperation
+ {
+ private readonly DefaultEditorFileSystem _fileSystem;
+ private readonly PackageBundle _bundle;
+
+ internal DEFSLoadBundleOperation(DefaultEditorFileSystem fileSystem, PackageBundle bundle)
+ {
+ _fileSystem = fileSystem;
+ _bundle = bundle;
+ }
+ internal override void InternalOnStart()
+ {
+ DownloadProgress = 1f;
+ DownloadedBytes = _bundle.FileSize;
+ Status = EOperationStatus.Succeed;
+ }
+ internal override void InternalOnUpdate()
+ {
+ }
+
+ public override void WaitForAsyncComplete()
+ {
+ }
+ public override void AbortDownloadOperation()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadBundleOperation.cs.meta
new file mode 100644
index 00000000..e35fb24e
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadBundleOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 47b871368218c7c49920927c10c6955e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadPackageManifestOperation.cs
new file mode 100644
index 00000000..bf65e449
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadPackageManifestOperation.cs
@@ -0,0 +1,58 @@
+
+namespace YooAsset
+{
+ internal class DEFSLoadPackageManifestOperation : FSLoadPackageManifestOperation
+ {
+ private enum ESteps
+ {
+ None,
+ LoadEditorPackageManifest,
+ Done,
+ }
+
+ private readonly DefaultEditorFileSystem _fileSystem;
+ private LoadEditorPackageManifestOperation _loadEditorPackageManifestOp;
+ private ESteps _steps = ESteps.None;
+
+
+ internal DEFSLoadPackageManifestOperation(DefaultEditorFileSystem fileSystem)
+ {
+ _fileSystem = fileSystem;
+ }
+ internal override void InternalOnStart()
+ {
+ _steps = ESteps.LoadEditorPackageManifest;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.LoadEditorPackageManifest)
+ {
+ if (_loadEditorPackageManifestOp == null)
+ {
+ _loadEditorPackageManifestOp = new LoadEditorPackageManifestOperation(_fileSystem);
+ OperationSystem.StartOperation(_fileSystem.PackageName, _loadEditorPackageManifestOp);
+ }
+
+ Progress = _loadEditorPackageManifestOp.Progress;
+ if (_loadEditorPackageManifestOp.IsDone == false)
+ return;
+
+ if (_loadEditorPackageManifestOp.Status == EOperationStatus.Succeed)
+ {
+ _steps = ESteps.Done;
+ Result = _loadEditorPackageManifestOp.Manifest;
+ Status = EOperationStatus.Succeed;
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _loadEditorPackageManifestOp.Error;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadPackageManifestOperation.cs.meta
new file mode 100644
index 00000000..d933afcb
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/DEFSLoadPackageManifestOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f3abaff43b56f62489688162296203cd
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal.meta
new file mode 100644
index 00000000..69f062b2
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: cf9de625784f5fe41a8d4fc53bf71ff0
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadEditorManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs
similarity index 53%
rename from Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadEditorManifestOperation.cs
rename to Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs
index 2dc1093b..a25cccef 100644
--- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/Internal/LoadEditorManifestOperation.cs
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs
@@ -2,19 +2,19 @@
namespace YooAsset
{
- internal class LoadEditorManifestOperation : AsyncOperationBase
+ internal class LoadEditorPackageManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
- LoadEditorManifest,
- CheckDeserializeManifest,
+ LoadFileData,
+ LoadManifest,
Done,
}
- private readonly string _packageName;
- private readonly string _manifestFilePath;
+ private readonly DefaultEditorFileSystem _fileSystem;
private DeserializeManifestOperation _deserializer;
+ private byte[] _fileData;
private ESteps _steps = ESteps.None;
///
@@ -23,47 +23,51 @@ namespace YooAsset
public PackageManifest Manifest { private set; get; }
- public LoadEditorManifestOperation(string packageName, string manifestFilePath)
+ internal LoadEditorPackageManifestOperation(DefaultEditorFileSystem fileSystem)
{
- _packageName = packageName;
- _manifestFilePath = manifestFilePath;
+ _fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
- _steps = ESteps.LoadEditorManifest;
+ _steps = ESteps.LoadFileData;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
- if (_steps == ESteps.LoadEditorManifest)
+ if (_steps == ESteps.LoadFileData)
{
- if (File.Exists(_manifestFilePath) == false)
+ string manifestFilePath = _fileSystem.SimulateManifestFilePath;
+ if (File.Exists(manifestFilePath))
+ {
+ _steps = ESteps.LoadManifest;
+ _fileData = FileUtility.ReadAllBytes(manifestFilePath);
+ }
+ else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
- Error = $"Not found simulation manifest file : {_manifestFilePath}";
- return;
+ Error = $"Simulation manifest file not found : {manifestFilePath}";
}
-
- YooLogger.Log($"Load editor manifest file : {_manifestFilePath}");
- byte[] bytesData = FileUtility.ReadAllBytes(_manifestFilePath);
- _deserializer = new DeserializeManifestOperation(bytesData);
- OperationSystem.StartOperation(_packageName, _deserializer);
- _steps = ESteps.CheckDeserializeManifest;
}
- if (_steps == ESteps.CheckDeserializeManifest)
+ if (_steps == ESteps.LoadManifest)
{
+ if (_deserializer == null)
+ {
+ _deserializer = new DeserializeManifestOperation(_fileData);
+ OperationSystem.StartOperation(_fileSystem.PackageName, _deserializer);
+ }
+
Progress = _deserializer.Progress;
if (_deserializer.IsDone == false)
return;
if (_deserializer.Status == EOperationStatus.Succeed)
{
- Manifest = _deserializer.Manifest;
_steps = ESteps.Done;
+ Manifest = _deserializer.Manifest;
Status = EOperationStatus.Succeed;
}
else
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs.meta
new file mode 100644
index 00000000..eb985ede
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultEditorFileSystem/Operation/internal/LoadEditorPackageManifestOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b6504949dca3fbf4fbb8c61c3ab9c51f
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem.meta
new file mode 100644
index 00000000..343af569
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 07e60a75ff092314cb4d9ba6d5b14296
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystem.cs
new file mode 100644
index 00000000..0d6fbaa4
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystem.cs
@@ -0,0 +1,21 @@
+
+namespace YooAsset
+{
+ ///
+ /// 缓存文件系统
+ ///
+ internal class DefaultUnpackFileSystem : DefaultCacheFileSystem
+ {
+ public DefaultUnpackFileSystem()
+ {
+ }
+ public override void OnCreate(string packageName, string rootDirectory)
+ {
+ base.OnCreate(packageName, rootDirectory);
+
+ // 注意:重写保存根目录和临时目录
+ _saveFileRoot = PathUtility.Combine(_packageRoot, DefaultUnpackFileSystemDefine.SaveFilesFolderName);
+ _tempFileRoot = PathUtility.Combine(_packageRoot, DefaultUnpackFileSystemDefine.TempFilesFolderName);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystem.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystem.cs.meta
new file mode 100644
index 00000000..9d0d1db6
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystem.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0bb4584d46f520741bcf6f52b67746d5
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystemDefine.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystemDefine.cs
new file mode 100644
index 00000000..2cc50180
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystemDefine.cs
@@ -0,0 +1,21 @@
+
+namespace YooAsset
+{
+ internal class DefaultUnpackFileSystemDefine
+ {
+ ///
+ /// 文件系统的优先级
+ ///
+ public const int DefaultPriority = 11;
+
+ ///
+ /// 保存的资源文件的文件夹名称
+ ///
+ public const string SaveFilesFolderName = "UnpackFiles";
+
+ ///
+ /// 下载的临时文件的文件夹名称
+ ///
+ public const string TempFilesFolderName = "UnpackTempFiles";
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystemDefine.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystemDefine.cs.meta
new file mode 100644
index 00000000..ca2e3da2
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultUnpackFileSystem/DefaultUnpackFileSystemDefine.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ee46c041e2affd349929df43af3f21c1
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem.meta
new file mode 100644
index 00000000..eca7b1f4
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 17d469f0c029a034bafe8d17a3db9ee5
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/DefaultWebFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/DefaultWebFileSystem.cs
new file mode 100644
index 00000000..1b7e9d09
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/DefaultWebFileSystem.cs
@@ -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 _wrappers = new Dictionary(10000);
+ protected readonly Dictionary _webFilePaths = new Dictionary(10000);
+ protected string _webPackageRoot = string.Empty;
+
+
+ ///
+ /// 包裹名称
+ ///
+ public string PackageName { private set; get; }
+
+ ///
+ /// 文件访问权限
+ ///
+ public EFileAccess FileSystemAccess
+ {
+ get
+ {
+ return EFileAccess.ReadWrite;
+ }
+ }
+
+ ///
+ /// 文件根目录
+ ///
+ public string FileRoot
+ {
+ get
+ {
+ return _webPackageRoot;
+ }
+ }
+
+ ///
+ /// 文件数量
+ ///
+ public int FileCount
+ {
+ get
+ {
+ return 0;
+ }
+ }
+
+ #region 自定义参数
+ public bool AllowCrossAccess { private set; get; } = false;
+
+ ///
+ /// 自定义参数:远程服务接口
+ ///
+ 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);
+ }
+
+ ///
+ /// 记录缓存信息
+ ///
+ 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
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/DefaultWebFileSystem.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/DefaultWebFileSystem.cs.meta
new file mode 100644
index 00000000..fd8fb455
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/DefaultWebFileSystem.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0772e17daa1b32b4a80a6211396a50e8
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation.meta
new file mode 100644
index 00000000..03b9c15d
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: fe53f557bb5cf3242a04b3fce756dd38
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearAllBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearAllBundleFilesOperation.cs
new file mode 100644
index 00000000..439a8ccf
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearAllBundleFilesOperation.cs
@@ -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()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearAllBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearAllBundleFilesOperation.cs.meta
new file mode 100644
index 00000000..cd41a65a
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearAllBundleFilesOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 68578d4c5e39a554aa3df2e7ec5218e9
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearUnusedBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearUnusedBundleFilesOperation.cs
new file mode 100644
index 00000000..6ce6b0f4
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearUnusedBundleFilesOperation.cs
@@ -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()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearUnusedBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearUnusedBundleFilesOperation.cs.meta
new file mode 100644
index 00000000..1d8a7b0c
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSClearUnusedBundleFilesOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1560968379b66d440a94382b2a311a15
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSDownloadFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSDownloadFileOperation.cs
new file mode 100644
index 00000000..46ad3534
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSDownloadFileOperation.cs
@@ -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;
+
+ ///
+ /// 下载结果
+ ///
+ 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;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSDownloadFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSDownloadFileOperation.cs.meta
new file mode 100644
index 00000000..08958f56
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSDownloadFileOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3b82b4b846083d34b958320b584d8d9b
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSInitializeOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSInitializeOperation.cs
new file mode 100644
index 00000000..f46ce372
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSInitializeOperation.cs
@@ -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;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSInitializeOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSInitializeOperation.cs.meta
new file mode 100644
index 00000000..a941c141
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSInitializeOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4c7cf2dca805b0b4d91cb5e0782dcb0c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadBundleOperation.cs
new file mode 100644
index 00000000..1313863f
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadBundleOperation.cs
@@ -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();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadBundleOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadBundleOperation.cs.meta
new file mode 100644
index 00000000..67b3f784
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadBundleOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a50dacdf7a3ad7c40a4195126425bbec
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadPackageManifestOperation.cs
new file mode 100644
index 00000000..12ca51d8
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadPackageManifestOperation.cs
@@ -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;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadPackageManifestOperation.cs.meta
new file mode 100644
index 00000000..40d0fe56
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSLoadPackageManifestOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0d0f8063cfabb5d40b364f162ce49fc0
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSRequestPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSRequestPackageVersionOperation.cs
new file mode 100644
index 00000000..384616ae
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSRequestPackageVersionOperation.cs
@@ -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;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSRequestPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSRequestPackageVersionOperation.cs.meta
new file mode 100644
index 00000000..4b85fd96
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/DWFSRequestPackageVersionOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 212a79e362fe6234c81fa79c3924dd20
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal.meta
new file mode 100644
index 00000000..53accb53
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 0e91f62e8fc7c1f4592681b7881ad925
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadRemotePackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadRemotePackageManifestOperation.cs
new file mode 100644
index 00000000..42edc568
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadRemotePackageManifestOperation.cs
@@ -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;
+
+ ///
+ /// 加载的清单实例
+ ///
+ 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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadRemotePackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadRemotePackageManifestOperation.cs.meta
new file mode 100644
index 00000000..183900fb
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadRemotePackageManifestOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2c2153284d246964fb2146f9fdda311c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebCatalogFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebCatalogFileOperation.cs
new file mode 100644
index 00000000..a6fa1cad
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebCatalogFileOperation.cs
@@ -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;
+
+ ///
+ /// 内置清单版本
+ ///
+ 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(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;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebCatalogFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebCatalogFileOperation.cs.meta
new file mode 100644
index 00000000..e5931448
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebCatalogFileOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4c34c01e10454c842819e066eef488cf
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebPackageManifestOperation.cs
new file mode 100644
index 00000000..7b1a866f
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebPackageManifestOperation.cs
@@ -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;
+
+ ///
+ /// 加载的清单实例
+ ///
+ 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;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebPackageManifestOperation.cs.meta
new file mode 100644
index 00000000..2e4eb98a
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/LoadWebPackageManifestOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 04a60c61990d93b4cb934ab1901a44f5
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestRemotePackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestRemotePackageHashOperation.cs
new file mode 100644
index 00000000..0e9b1d7c
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestRemotePackageHashOperation.cs
@@ -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;
+
+ ///
+ /// 包裹哈希值
+ ///
+ 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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestRemotePackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestRemotePackageHashOperation.cs.meta
new file mode 100644
index 00000000..c2f4ed99
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestRemotePackageHashOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3f8269507a575884f935f9fbc71396ea
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageHashOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageHashOperation.cs
new file mode 100644
index 00000000..5ef9cd25
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageHashOperation.cs
@@ -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;
+
+ ///
+ /// 包裹哈希值
+ ///
+ 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;
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageHashOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageHashOperation.cs.meta
new file mode 100644
index 00000000..4b49e5df
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageHashOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ead93dc6c4d5ed942b209ec2202087dc
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageVersionOperation.cs
new file mode 100644
index 00000000..20f1fd2a
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageVersionOperation.cs
@@ -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;
+
+ ///
+ /// 包裹版本
+ ///
+ 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;
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageVersionOperation.cs.meta
new file mode 100644
index 00000000..4e7e4b8b
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultWebFileSystem/Operation/internal/RequestWebPackageVersionOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: bfa0e562b63f31141bbf04d4d5336d87
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/EFileAccess.cs b/Assets/YooAsset/Runtime/FileSystem/EFileAccess.cs
new file mode 100644
index 00000000..a350ad8d
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/EFileAccess.cs
@@ -0,0 +1,21 @@
+
+namespace YooAsset
+{
+ internal enum EFileAccess
+ {
+ ///
+ /// 只可读
+ ///
+ Read = 0,
+
+ ///
+ /// 只可写
+ ///
+ Write = 1,
+
+ ///
+ /// 可读写
+ ///
+ ReadWrite = 2
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/EFileAccess.cs.meta b/Assets/YooAsset/Runtime/FileSystem/EFileAccess.cs.meta
new file mode 100644
index 00000000..09d836fd
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/EFileAccess.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1ec116be6f4596f4db2cb4c627d9fe51
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/CacheSystem/EVerifyLevel.cs b/Assets/YooAsset/Runtime/FileSystem/EFileVerifyLevel.cs
similarity index 73%
rename from Assets/YooAsset/Runtime/CacheSystem/EVerifyLevel.cs
rename to Assets/YooAsset/Runtime/FileSystem/EFileVerifyLevel.cs
index 966a922f..711cf3f8 100644
--- a/Assets/YooAsset/Runtime/CacheSystem/EVerifyLevel.cs
+++ b/Assets/YooAsset/Runtime/FileSystem/EFileVerifyLevel.cs
@@ -2,23 +2,23 @@
namespace YooAsset
{
///
- /// 下载文件校验等级
+ /// 文件校验等级
///
- public enum EVerifyLevel
+ public enum EFileVerifyLevel
{
///
/// 验证文件存在
///
- Low,
+ Low = 1,
///
/// 验证文件大小
///
- Middle,
+ Middle = 2,
///
/// 验证文件大小和CRC
///
- High,
+ High = 3,
}
}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/EFileVerifyLevel.cs.meta b/Assets/YooAsset/Runtime/FileSystem/EFileVerifyLevel.cs.meta
new file mode 100644
index 00000000..b93496fa
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/EFileVerifyLevel.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5023ed6a87d5e5a4482f5559c3d80122
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs b/Assets/YooAsset/Runtime/FileSystem/EFileVerifyResult.cs
similarity index 94%
rename from Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs
rename to Assets/YooAsset/Runtime/FileSystem/EFileVerifyResult.cs
index c8636e35..12b9ad19 100644
--- a/Assets/YooAsset/Runtime/CacheSystem/EVerifyResult.cs
+++ b/Assets/YooAsset/Runtime/FileSystem/EFileVerifyResult.cs
@@ -2,9 +2,9 @@
namespace YooAsset
{
///
- /// 下载文件校验结果
+ /// 文件校验结果
///
- internal enum EVerifyResult
+ internal enum EFileVerifyResult
{
///
/// 验证异常
diff --git a/Assets/YooAsset/Runtime/FileSystem/EFileVerifyResult.cs.meta b/Assets/YooAsset/Runtime/FileSystem/EFileVerifyResult.cs.meta
new file mode 100644
index 00000000..8422fe26
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/EFileVerifyResult.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1c71d42855e9484409e0dc352acb176a
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystemHelper.cs b/Assets/YooAsset/Runtime/FileSystem/FileSystemHelper.cs
new file mode 100644
index 00000000..b2f606bc
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/FileSystemHelper.cs
@@ -0,0 +1,45 @@
+using System;
+using System.IO;
+
+namespace YooAsset
+{
+ internal class FileSystemHelper
+ {
+ ///
+ /// 文件校验
+ ///
+ public static EFileVerifyResult FileVerify(string filePath, long fileSize, string fileCRC, EFileVerifyLevel verifyLevel)
+ {
+ try
+ {
+ if (File.Exists(filePath) == false)
+ return EFileVerifyResult.DataFileNotExisted;
+
+ // 先验证文件大小
+ long size = FileUtility.GetFileSize(filePath);
+ if (size < fileSize)
+ return EFileVerifyResult.FileNotComplete;
+ else if (size > fileSize)
+ return EFileVerifyResult.FileOverflow;
+
+ // 再验证文件CRC
+ if (verifyLevel == EFileVerifyLevel.High)
+ {
+ string crc = HashUtility.FileCRC32Safely(filePath);
+ if (crc == fileCRC)
+ return EFileVerifyResult.Succeed;
+ else
+ return EFileVerifyResult.FileCrcError;
+ }
+ else
+ {
+ return EFileVerifyResult.Succeed;
+ }
+ }
+ catch (Exception)
+ {
+ return EFileVerifyResult.Exception;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/FileSystemHelper.cs.meta b/Assets/YooAsset/Runtime/FileSystem/FileSystemHelper.cs.meta
new file mode 100644
index 00000000..a2091cde
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/FileSystemHelper.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: cbc12d398555ced46b201626eec6825e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/Interface.meta b/Assets/YooAsset/Runtime/FileSystem/Interface.meta
new file mode 100644
index 00000000..26ba3b13
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Interface.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 0b81b60c4748e3447967805ca3884d07
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs
new file mode 100644
index 00000000..a3d5d950
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs
@@ -0,0 +1,153 @@
+
+namespace YooAsset
+{
+ internal interface IFileSystem
+ {
+ ///
+ /// 包裹名称
+ ///
+ string PackageName { get; }
+
+ ///
+ /// 文件访问权限
+ ///
+ EFileAccess FileSystemAccess { get; }
+
+ ///
+ /// 文件根目录
+ ///
+ string FileRoot { get; }
+
+ ///
+ /// 文件数量
+ ///
+ int FileCount { get; }
+
+
+ ///
+ /// 初始化缓存系统
+ ///
+ FSInitializeFileSystemOperation InitializeFileSystemAsync();
+
+ ///
+ /// 加载包裹清单
+ ///
+ FSLoadPackageManifestOperation LoadPackageManifestAsync(params object[] args);
+
+ ///
+ /// 查询最新的版本
+ ///
+ FSRequestPackageVersionOperation RequestPackageVersionAsync(params object[] args);
+
+ ///
+ /// 清空所有的文件
+ ///
+ FSClearAllBundleFilesOperation ClearAllBundleFilesAsync(params object[] args);
+
+ ///
+ /// 清空未使用的文件
+ ///
+ FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(params object[] args);
+
+ ///
+ /// 下载远端文件
+ ///
+ FSDownloadFileOperation DownloadFileAsync(params object[] args);
+
+
+ ///
+ /// 设置自定义参数
+ ///
+ void SetParameter(string name, object value);
+
+ ///
+ /// 创建缓存系统
+ ///
+ void OnCreate(string packageName, string rootDirectory);
+
+ ///
+ /// 更新文件系统
+ ///
+ void OnUpdate();
+
+
+ ///
+ /// 查询文件归属
+ ///
+ bool Belong(PackageBundle bundle);
+
+ ///
+ /// 查询文件归属
+ ///
+ bool Belong(string bundleGUID);
+
+ ///
+ /// 查询文件是否存在
+ ///
+ bool Exists(PackageBundle bundle);
+
+ ///
+ /// 查询文件是否存在
+ ///
+ bool Exists(string bundleGUID);
+
+
+ ///
+ /// 检测是否需要下载
+ ///
+ bool CheckNeedDownload(PackageBundle bundle);
+
+ ///
+ /// 检测是否需要解压
+ ///
+ bool CheckNeedUnpack(PackageBundle bundle);
+
+ ///
+ /// 检测是否需要导入
+ ///
+ bool CheckNeedImport(PackageBundle bundle);
+
+
+ ///
+ /// 写入文件
+ ///
+ bool WriteFile(PackageBundle bundle, string copyPath);
+
+ ///
+ /// 删除文件
+ ///
+ bool DeleteFile(PackageBundle bundle);
+
+ ///
+ /// 删除文件
+ ///
+ bool DeleteFile(string bundleGUID);
+
+ ///
+ /// 校验文件
+ ///
+ EFileVerifyResult VerifyFile(PackageBundle bundle);
+
+
+ ///
+ /// 读取文件的二进制数据
+ ///
+ byte[] ReadFileBytes(PackageBundle bundle);
+
+ ///
+ /// 读取文件的文本数据
+ ///
+ string ReadFileText(PackageBundle bundle);
+
+
+ ///
+ /// 加载Bundle文件
+ ///
+ FSLoadBundleOperation LoadBundleFile(PackageBundle bundle);
+
+ ///
+ /// 卸载Bundle文件
+ ///
+ void UnloadBundleFile(PackageBundle bundle, object result);
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs.meta
new file mode 100644
index 00000000..cdd6a064
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Interface/IFileSystem.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 960fb79a45e1fa147943ced59f2fb61c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation.meta b/Assets/YooAsset/Runtime/FileSystem/Operation.meta
new file mode 100644
index 00000000..8766bbc9
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 7ea2c2e5d4ba0f142a8ecd5d5f79c360
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal.meta
new file mode 100644
index 00000000..766b9a6a
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 97923f5987c469a4898718033af09e99
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultDownloadFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultDownloadFileOperation.cs
new file mode 100644
index 00000000..73844f99
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultDownloadFileOperation.cs
@@ -0,0 +1,118 @@
+using UnityEngine.Networking;
+
+namespace YooAsset
+{
+ internal abstract class DefaultDownloadFileOperation : FSDownloadFileOperation
+ {
+ protected enum ESteps
+ {
+ None,
+ CreateRequest,
+ CheckRequest,
+ VerifyTempFile,
+ CheckVerifyTempFile,
+ TryAgain,
+ Done,
+ }
+
+ // 初始参数
+ protected readonly string _mainURL;
+ protected readonly string _fallbackURL;
+ protected readonly int _failedTryAgain;
+ protected readonly int _timeout;
+
+ // 请求相关
+ protected UnityWebRequest _webRequest;
+ protected string _requestURL;
+ protected int _requestCount = 0;
+
+ // 超时相关
+ protected bool _isAbort = false;
+ protected long _latestDownloadBytes;
+ protected float _latestDownloadRealtime;
+ protected float _tryAgainTimer;
+
+ // 失败相关
+ protected int FailedTryAgain;
+
+
+ internal DefaultDownloadFileOperation(PackageBundle bundle,
+ string mainURL, string fallbackURL, int failedTryAgain, int timeout) : base(bundle)
+ {
+ _mainURL = mainURL;
+ _fallbackURL = fallbackURL;
+ _failedTryAgain = failedTryAgain;
+ _timeout = timeout;
+
+ FailedTryAgain = failedTryAgain;
+ }
+
+ ///
+ /// 获取网络请求地址
+ ///
+ protected string GetRequestURL()
+ {
+ // 轮流返回请求地址
+ _requestCount++;
+ if (_requestCount % 2 == 0)
+ return _fallbackURL;
+ else
+ return _mainURL;
+ }
+
+ ///
+ /// 检测请求超时
+ ///
+ protected void CheckRequestTimeout()
+ {
+ // 注意:在连续时间段内无新增下载数据及判定为超时
+ if (_isAbort == false)
+ {
+ if (_latestDownloadBytes != DownloadedBytes)
+ {
+ _latestDownloadBytes = DownloadedBytes;
+ _latestDownloadRealtime = UnityEngine.Time.realtimeSinceStartup;
+ }
+
+ float offset = UnityEngine.Time.realtimeSinceStartup - _latestDownloadRealtime;
+ if (offset > _timeout)
+ {
+ YooLogger.Warning($"Web file request timeout : {_requestURL}");
+ if (_webRequest != null)
+ _webRequest.Abort();
+ _isAbort = true;
+ }
+ }
+ }
+
+ ///
+ /// 检测请求结果
+ ///
+ protected bool CheckRequestResult()
+ {
+ HttpCode = _webRequest.responseCode;
+
+#if UNITY_2020_3_OR_NEWER
+ if (_webRequest.result != UnityWebRequest.Result.Success)
+ {
+ Error = _webRequest.error;
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+#else
+ if (_webRequest.isNetworkError || _webRequest.isHttpError)
+ {
+ Error = _webRequest.error;
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+#endif
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultDownloadFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultDownloadFileOperation.cs.meta
new file mode 100644
index 00000000..411526b8
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultDownloadFileOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: af07b7cdf729e944dbb6d60204c71235
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultGetRemotePackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultGetRemotePackageVersionOperation.cs
new file mode 100644
index 00000000..9ba2ee64
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultGetRemotePackageVersionOperation.cs
@@ -0,0 +1,102 @@
+
+namespace YooAsset
+{
+ internal class DefaultGetRemotePackageVersionOperation : AsyncOperationBase
+ {
+ private enum ESteps
+ {
+ None,
+ RequestPackageVersion,
+ Done,
+ }
+
+ private readonly string _packageName;
+ private readonly string _mainURL;
+ private readonly string _fallbackURL;
+ private readonly bool _appendTimeTicks;
+ private readonly int _timeout;
+ private UnityWebTextRequestOperation _webTextRequestOp;
+ private int _requestCount = 0;
+ private ESteps _steps = ESteps.None;
+
+ ///
+ /// 查询的远端版本信息
+ ///
+ internal string PackageVersion { set; get; }
+
+
+ internal DefaultGetRemotePackageVersionOperation(string packageName, string mainURL, string fallbackURL, bool appendTimeTicks, int timeout)
+ {
+ _packageName = packageName;
+ _mainURL = mainURL;
+ _fallbackURL = fallbackURL;
+ _appendTimeTicks = appendTimeTicks;
+ _timeout = timeout;
+ }
+ internal override void InternalOnStart()
+ {
+ _requestCount = WebRequestCounter.GetRequestFailedCount(_packageName, nameof(DefaultGetRemotePackageVersionOperation));
+ _steps = ESteps.RequestPackageVersion;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.RequestPackageVersion)
+ {
+ if (_webTextRequestOp == null)
+ {
+ string url = GetPackageVersionRequestURL();
+ YooLogger.Log($"Beginning to request package version : {url}");
+ _webTextRequestOp = new UnityWebTextRequestOperation(url, _timeout);
+ OperationSystem.StartOperation(_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(_packageName, nameof(DefaultGetRemotePackageVersionOperation));
+ }
+ else
+ {
+ PackageVersion = _webTextRequestOp.Result;
+ if (string.IsNullOrEmpty(PackageVersion))
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = $"Remote package version file content is empty !";
+ }
+ else
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ }
+ }
+ }
+
+ private string GetPackageVersionRequestURL()
+ {
+ string url;
+
+ // 轮流返回请求地址
+ if (_requestCount % 2 == 0)
+ url = _mainURL;
+ else
+ url = _fallbackURL;
+
+ // 在URL末尾添加时间戳
+ if (_appendTimeTicks)
+ return $"{url}?{System.DateTime.UtcNow.Ticks}";
+ else
+ return url;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultGetRemotePackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultGetRemotePackageVersionOperation.cs.meta
new file mode 100644
index 00000000..e2049f65
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DefaultGetRemotePackageVersionOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1b078a220cc4f7d4392d77ccc77c001e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearAllBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearAllBundleFilesOperation.cs
new file mode 100644
index 00000000..cba25d35
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearAllBundleFilesOperation.cs
@@ -0,0 +1,7 @@
+
+namespace YooAsset
+{
+ internal abstract class FSClearAllBundleFilesOperation : AsyncOperationBase
+ {
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearAllBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearAllBundleFilesOperation.cs.meta
new file mode 100644
index 00000000..e39f22d8
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearAllBundleFilesOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e9fe9171073a87746a7393f7d1fcb924
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearUnusedBundleFilesOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearUnusedBundleFilesOperation.cs
new file mode 100644
index 00000000..a0d8f88f
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearUnusedBundleFilesOperation.cs
@@ -0,0 +1,7 @@
+
+namespace YooAsset
+{
+ internal abstract class FSClearUnusedBundleFilesOperation : AsyncOperationBase
+ {
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearUnusedBundleFilesOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearUnusedBundleFilesOperation.cs.meta
new file mode 100644
index 00000000..a29a42d1
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSClearUnusedBundleFilesOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 857423cdfd4f9184eab094be01c62480
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSDownloadFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSDownloadFileOperation.cs
new file mode 100644
index 00000000..f9fa7e26
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSDownloadFileOperation.cs
@@ -0,0 +1,46 @@
+
+namespace YooAsset
+{
+ internal abstract class FSDownloadFileOperation : AsyncOperationBase
+ {
+ public PackageBundle Bundle { private set; get; }
+
+ ///
+ /// 引用计数
+ ///
+ public int RefCount { private set; get; }
+
+ ///
+ /// HTTP返回码
+ ///
+ public long HttpCode { protected set; get; }
+
+ ///
+ /// 当前下载的字节数
+ ///
+ public long DownloadedBytes { protected set; get; }
+
+ ///
+ /// 当前下载进度(0f - 1f)
+ ///
+ public float DownloadProgress { protected set; get; }
+
+
+ public FSDownloadFileOperation(PackageBundle bundle)
+ {
+ Bundle = bundle;
+ RefCount = 0;
+ HttpCode = 0;
+ DownloadedBytes = 0;
+ DownloadProgress = 0;
+ }
+ public void Release()
+ {
+ RefCount--;
+ }
+ public void Reference()
+ {
+ RefCount++;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSDownloadFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSDownloadFileOperation.cs.meta
new file mode 100644
index 00000000..3a1ea952
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSDownloadFileOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5e61f870d9802cf4ab18d0050aa38ae7
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSInitializeFileSystemOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSInitializeFileSystemOperation.cs
new file mode 100644
index 00000000..d9a5666c
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSInitializeFileSystemOperation.cs
@@ -0,0 +1,7 @@
+
+namespace YooAsset
+{
+ internal abstract class FSInitializeFileSystemOperation : AsyncOperationBase
+ {
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSInitializeFileSystemOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSInitializeFileSystemOperation.cs.meta
new file mode 100644
index 00000000..9835c333
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSInitializeFileSystemOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5de0f7b58d8d2114680a9ff319db5d26
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadBundleFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadBundleFileOperation.cs
new file mode 100644
index 00000000..63133960
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadBundleFileOperation.cs
@@ -0,0 +1,27 @@
+using UnityEngine;
+
+namespace YooAsset
+{
+ internal abstract class FSLoadBundleOperation : AsyncOperationBase
+ {
+ ///
+ /// 加载结果
+ ///
+ public object Result { protected set; get; }
+
+ ///
+ /// 下载进度
+ ///
+ public float DownloadProgress { protected set; get; }
+
+ ///
+ /// 下载大小
+ ///
+ public long DownloadedBytes { protected set; get; }
+
+ ///
+ /// 终止下载任务
+ ///
+ public abstract void AbortDownloadOperation();
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadBundleFileOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadBundleFileOperation.cs.meta
new file mode 100644
index 00000000..bceb8832
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadBundleFileOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e9d1f8374e0d38b4f9a7d1db62bb062e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadPackageManifestOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadPackageManifestOperation.cs
new file mode 100644
index 00000000..a9aaf6b1
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadPackageManifestOperation.cs
@@ -0,0 +1,11 @@
+
+namespace YooAsset
+{
+ internal abstract class FSLoadPackageManifestOperation : AsyncOperationBase
+ {
+ ///
+ /// 加载结果
+ ///
+ internal PackageManifest Result { set; get; }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadPackageManifestOperation.cs.meta
new file mode 100644
index 00000000..9b054e7a
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSLoadPackageManifestOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1d486c0822a1831438865d132c4690a9
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSQueryPackageVersionOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSQueryPackageVersionOperation.cs
new file mode 100644
index 00000000..1f269dac
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSQueryPackageVersionOperation.cs
@@ -0,0 +1,11 @@
+
+namespace YooAsset
+{
+ internal abstract class FSRequestPackageVersionOperation : AsyncOperationBase
+ {
+ ///
+ /// 查询的最新版本信息
+ ///
+ internal string PackageVersion { set; get; }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSQueryPackageVersionOperation.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSQueryPackageVersionOperation.cs.meta
new file mode 100644
index 00000000..5ed2e5ff
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/FSQueryPackageVersionOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6a98e69d7c0b9024a84093bcc7835a15
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/InitializeParameters.cs b/Assets/YooAsset/Runtime/InitializeParameters.cs
index b66f40b6..cd4684b7 100644
--- a/Assets/YooAsset/Runtime/InitializeParameters.cs
+++ b/Assets/YooAsset/Runtime/InitializeParameters.cs
@@ -1,4 +1,6 @@
-
+using System;
+using System.Collections.Generic;
+
namespace YooAsset
{
///
@@ -48,48 +50,147 @@ namespace YooAsset
WebPlayMode,
}
+ ///
+ /// 文件系统参数
+ ///
+ public class FileSystemParameters
+ {
+ internal Dictionary CreateParameters = new Dictionary();
+
+ ///
+ /// 文件系统类
+ /// 格式: "namespace.class,assembly"
+ /// 格式: "命名空间.类型名,程序集"
+ ///
+ public string FileSystemClass { private set; get; }
+
+ ///
+ /// 文件系统的根目录
+ ///
+ public string RootDirectory { private set; get; }
+
+
+ public FileSystemParameters(string fileSystemClass, string rootDirectory)
+ {
+ FileSystemClass = fileSystemClass;
+ RootDirectory = rootDirectory;
+ }
+
+ ///
+ /// 添加自定义参数
+ ///
+ public void AddParameter(string name, object value)
+ {
+ CreateParameters.Add(name, value);
+ }
+
+
+ ///
+ /// 创建默认的编辑器文件系统参数
+ /// 用于模拟运行的资源清单路径
+ ///
+ public static FileSystemParameters CreateDefaultEditorFileSystemParameters(string simulateManifestFilePath)
+ {
+ string fileSystemClass = typeof(DefaultEditorFileSystem).FullName;
+ var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
+ fileSystemParams.AddParameter("SIMULATE_MANIFEST_FILE_PATH", simulateManifestFilePath);
+ return fileSystemParams;
+ }
+
+ ///
+ /// 创建默认的内置文件系统参数
+ ///
+ /// 缓存文件的校验等级
+ /// 内置文件的根路径
+ public static FileSystemParameters CreateDefaultBuildinFileSystemParameters(EFileVerifyLevel verifyLevel = EFileVerifyLevel.Middle, string rootDirectory = null)
+ {
+ string fileSystemClass = typeof(DefaultBuildinFileSystem).FullName;
+ var fileSystemParams = new FileSystemParameters(fileSystemClass, rootDirectory);
+ fileSystemParams.AddParameter("FILE_VERIFY_LEVEL", verifyLevel);
+ return fileSystemParams;
+ }
+
+ ///
+ /// 创建默认的内置文件系统参数(原生文件)
+ ///
+ /// 缓存文件的校验等级
+ /// 内置文件的根路径
+ public static FileSystemParameters CreateDefaultBuildinRawFileSystemParameters(EFileVerifyLevel verifyLevel = EFileVerifyLevel.Middle, string rootDirectory = null)
+ {
+ string fileSystemClass = typeof(DefaultBuildinFileSystem).FullName;
+ var fileSystemParams = new FileSystemParameters(fileSystemClass, rootDirectory);
+ fileSystemParams.AddParameter("FILE_VERIFY_LEVEL", verifyLevel);
+ fileSystemParams.AddParameter("APPEND_FILE_EXTENSION", true);
+ fileSystemParams.AddParameter("RAW_FILE_BUILD_PIPELINE", true);
+ return fileSystemParams;
+ }
+
+ ///
+ /// 创建默认的缓存文件系统参数
+ ///
+ /// 远端资源地址查询服务类
+ /// 缓存文件的校验等级
+ /// 文件系统的根目录
+ public static FileSystemParameters CreateDefaultCacheFileSystemParameters(IRemoteServices remoteServices, EFileVerifyLevel verifyLevel = EFileVerifyLevel.Middle, string rootDirectory = null)
+ {
+ string fileSystemClass = typeof(DefaultCacheFileSystem).FullName;
+ var fileSystemParams = new FileSystemParameters(fileSystemClass, rootDirectory);
+ fileSystemParams.AddParameter("REMOTE_SERVICES", remoteServices);
+ fileSystemParams.AddParameter("FILE_VERIFY_LEVEL", verifyLevel);
+ return fileSystemParams;
+ }
+
+ ///
+ /// 创建默认的缓存文件系统参数(原生文件)
+ ///
+ /// 远端资源地址查询服务类
+ /// 缓存文件的校验等级
+ /// 文件系统的根目录
+ public static FileSystemParameters CreateDefaultCacheRawFileSystemParameters(IRemoteServices remoteServices, EFileVerifyLevel verifyLevel = EFileVerifyLevel.Middle, string rootDirectory = null)
+ {
+ string fileSystemClass = typeof(DefaultCacheFileSystem).FullName;
+ var fileSystemParams = new FileSystemParameters(fileSystemClass, rootDirectory);
+ fileSystemParams.AddParameter("REMOTE_SERVICES", remoteServices);
+ fileSystemParams.AddParameter("FILE_VERIFY_LEVEL", verifyLevel);
+ fileSystemParams.AddParameter("APPEND_FILE_EXTENSION", true);
+ fileSystemParams.AddParameter("RAW_FILE_BUILD_PIPELINE", true);
+ return fileSystemParams;
+ }
+
+ ///
+ /// 创建默认的Web文件系统参数
+ ///
+ public static FileSystemParameters CreateDefaultWebFileSystemParameters()
+ {
+ string fileSystemClass = typeof(DefaultWebFileSystem).FullName;
+ var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
+ fileSystemParams.AddParameter("ALLOW_CROSS_ACCESS", false);
+ return fileSystemParams;
+ }
+
+ ///
+ /// 创建默认的Web文件系统参数
+ ///
+ /// 远端资源地址查询服务类
+ public static FileSystemParameters CreateDefaultWebFileSystemParameters(IRemoteServices remoteServices)
+ {
+ string fileSystemClass = typeof(DefaultWebFileSystem).FullName;
+ var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
+ fileSystemParams.AddParameter("ALLOW_CROSS_ACCESS", true);
+ fileSystemParams.AddParameter("REMOTE_SERVICES", remoteServices);
+ return fileSystemParams;
+ }
+ }
+
///
/// 初始化参数
///
public abstract class InitializeParameters
{
- ///
- /// 内置文件的根路径
- /// 注意:当参数为空的时候会使用默认的根目录。
- ///
- public string BuildinRootDirectory = string.Empty;
-
- ///
- /// 沙盒文件的根路径
- /// 注意:当参数为空的时候会使用默认的根目录。
- ///
- public string SandboxRootDirectory = string.Empty;
-
- ///
- /// 缓存文件追加原始后缀格式
- ///
- public bool CacheFileAppendExtension = false;
-
- ///
- /// 缓存系统启动时的验证级别
- ///
- public EVerifyLevel CacheBootVerifyLevel = EVerifyLevel.Middle;
-
///
/// 自动销毁不再使用的资源提供者
///
public bool AutoDestroyAssetProvider = false;
-
- ///
- /// 启用断点续传参数
- /// 说明:当文件的大小大于设置的字节数时启用断点续传下载器
- ///
- public uint BreakpointResumeFileSize = int.MaxValue;
-
- ///
- /// 文件解密服务接口
- ///
- public IDecryptionServices DecryptionServices = null;
}
///
@@ -97,10 +198,7 @@ namespace YooAsset
///
public class EditorSimulateModeParameters : InitializeParameters
{
- ///
- /// 用于模拟运行的资源清单路径
- ///
- public string SimulateManifestFilePath = string.Empty;
+ public FileSystemParameters EditorFileSystemParameters;
}
///
@@ -108,6 +206,7 @@ namespace YooAsset
///
public class OfflinePlayModeParameters : InitializeParameters
{
+ public FileSystemParameters BuildinFileSystemParameters;
}
///
@@ -115,25 +214,9 @@ namespace YooAsset
///
public class HostPlayModeParameters : InitializeParameters
{
- ///
- /// 远端资源地址查询服务类
- ///
- public IRemoteServices RemoteServices = null;
-
- ///
- /// 内置资源查询服务接口
- ///
- public IBuildinQueryServices BuildinQueryServices = null;
-
- ///
- /// 分发资源查询服务接口
- ///
- public IDeliveryQueryServices DeliveryQueryServices = null;
-
- ///
- /// 分发资源加载服务接口
- ///
- public IDeliveryLoadServices DeliveryLoadServices = null;
+ public FileSystemParameters BuildinFileSystemParameters;
+ public FileSystemParameters DeliveryFileSystemParameters;
+ public FileSystemParameters CacheFileSystemParameters;
}
///
@@ -141,19 +224,6 @@ namespace YooAsset
///
public class WebPlayModeParameters : InitializeParameters
{
- ///
- /// 远端资源地址查询服务类
- ///
- public IRemoteServices RemoteServices = null;
-
- ///
- /// 内置资源查询服务接口
- ///
- public IBuildinQueryServices BuildinQueryServices = null;
-
- ///
- /// 微信缓存查询服务接口
- ///
- public IWechatQueryServices WechatQueryServices = null;
+ public FileSystemParameters WebFileSystemParameters;
}
}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs b/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs
index 711c774f..8e8d4397 100644
--- a/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs
+++ b/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs
@@ -10,14 +10,12 @@ namespace YooAsset
// 用户请求的回调
private Action _callback;
+ // 所属包裹
+ private string _packageName = null;
+
// 是否已经完成
internal bool IsFinish = false;
- ///
- /// 所属包裹
- ///
- public string PackageName { private set; get; }
-
///
/// 优先级
///
@@ -88,9 +86,13 @@ namespace YooAsset
internal abstract void InternalOnUpdate();
internal virtual void InternalOnAbort() { }
+ internal string GetPackageName()
+ {
+ return _packageName;
+ }
internal void SetPackageName(string packageName)
{
- PackageName = packageName;
+ _packageName = packageName;
}
internal void SetStart()
{
@@ -116,11 +118,19 @@ namespace YooAsset
{
Status = EOperationStatus.Failed;
Error = "user abort";
- YooLogger.Warning($"Async operaiton has been abort : {this.GetType().Name}");
+ YooLogger.Warning($"Async operaiton {this.GetType().Name} has been abort !");
InternalOnAbort();
}
}
+ ///
+ /// 等待异步执行完毕
+ ///
+ public virtual void WaitForAsyncComplete()
+ {
+ throw new System.NotImplementedException(this.GetType().Name);
+ }
+
///
/// 清空完成回调
///
diff --git a/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs b/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs
index 2c420c6b..98a7e001 100644
--- a/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs
+++ b/Assets/YooAsset/Runtime/OperationSystem/OperationSystem.cs
@@ -112,7 +112,7 @@ namespace YooAsset
// 终止临时队列里的任务
foreach (var operation in _newList)
{
- if (operation.PackageName == packageName)
+ if (operation.GetPackageName() == packageName)
{
operation.SetAbort();
}
@@ -121,7 +121,7 @@ namespace YooAsset
// 终止正在进行的任务
foreach (var operation in _operations)
{
- if (operation.PackageName == packageName)
+ if (operation.GetPackageName() == packageName)
{
operation.SetAbort();
}
@@ -137,14 +137,5 @@ namespace YooAsset
operation.SetPackageName(packageName);
operation.SetStart();
}
-
- ///
- /// 开始处理异步操作类
- ///
- public static void StartOperation(AsyncOperationBase operation)
- {
- _newList.Add(operation);
- operation.SetStart();
- }
}
}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleFileLoader.cs b/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleFileLoader.cs
deleted file mode 100644
index cdd66654..00000000
--- a/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleFileLoader.cs
+++ /dev/null
@@ -1,319 +0,0 @@
-using System;
-using System.IO;
-using System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-
-namespace YooAsset
-{
- internal sealed class AssetBundleFileLoader : BundleLoaderBase
- {
- private enum ESteps
- {
- None = 0,
- Download,
- CheckDownload,
- Unpack,
- CheckUnpack,
- LoadBundleFile,
- LoadDeliveryFile,
- CheckLoadFile,
- Done,
- }
-
- private ESteps _steps = ESteps.None;
- private bool _isWaitForAsyncComplete = false;
- private bool _isShowWaitForAsyncError = false;
- private DownloaderBase _unpacker;
- private DownloaderBase _downloader;
- private AssetBundleCreateRequest _createRequest;
- private Stream _managedStream;
-
-
- public AssetBundleFileLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
- {
- }
-
- ///
- /// 轮询更新
- ///
- public override void Update()
- {
- if (_steps == ESteps.Done)
- return;
-
- if (_steps == ESteps.None)
- {
- if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
- {
- _steps = ESteps.Download;
- FileLoadPath = MainBundleInfo.CachedDataFilePath;
- }
- else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
- {
-#if UNITY_ANDROID
- if (MainBundleInfo.Bundle.Encrypted)
- {
- _steps = ESteps.Unpack;
- FileLoadPath = MainBundleInfo.CachedDataFilePath;
- }
- else
- {
- _steps = ESteps.LoadBundleFile;
- FileLoadPath = MainBundleInfo.BuildinFilePath;
- }
-#else
- _steps = ESteps.LoadBundleFile;
- FileLoadPath = MainBundleInfo.BuildinFilePath;
-#endif
- }
- else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
- {
- _steps = ESteps.LoadBundleFile;
- FileLoadPath = MainBundleInfo.CachedDataFilePath;
- }
- else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromDelivery)
- {
- _steps = ESteps.LoadDeliveryFile;
- FileLoadPath = MainBundleInfo.DeliveryFilePath;
- }
- else
- {
- throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
- }
- }
-
- // 1. 从服务器下载
- if (_steps == ESteps.Download)
- {
- _downloader = MainBundleInfo.CreateDownloader(int.MaxValue);
- _downloader.SendRequest();
- _steps = ESteps.CheckDownload;
- }
-
- // 2. 检测服务器下载结果
- if (_steps == ESteps.CheckDownload)
- {
- DownloadProgress = _downloader.DownloadProgress;
- DownloadedBytes = _downloader.DownloadedBytes;
- if (_downloader.IsDone() == false)
- return;
-
- if (_downloader.HasError())
- {
- _steps = ESteps.Done;
- Status = EStatus.Failed;
- LastError = _downloader.GetLastError();
- }
- else
- {
- _steps = ESteps.LoadBundleFile;
- return; //下载完毕等待一帧再去加载!
- }
- }
-
- // 3. 内置文件解压
- if (_steps == ESteps.Unpack)
- {
- int failedTryAgain = 1;
- _unpacker = MainBundleInfo.CreateUnpacker(failedTryAgain);
- _unpacker.SendRequest();
- _steps = ESteps.CheckUnpack;
- }
-
- // 4.检测内置文件解压结果
- if (_steps == ESteps.CheckUnpack)
- {
- DownloadProgress = _unpacker.DownloadProgress;
- DownloadedBytes = _unpacker.DownloadedBytes;
- if (_unpacker.IsDone() == false)
- return;
-
- if (_unpacker.HasError())
- {
- _steps = ESteps.Done;
- Status = EStatus.Failed;
- LastError = _unpacker.GetLastError();
- }
- else
- {
- _steps = ESteps.LoadBundleFile;
- }
- }
-
- // 5. 加载AssetBundle
- if (_steps == ESteps.LoadBundleFile)
- {
-#if UNITY_EDITOR
- // 注意:Unity2017.4编辑器模式下,如果AssetBundle文件不存在会导致编辑器崩溃,这里做了预判。
- if (System.IO.File.Exists(FileLoadPath) == false)
- {
- _steps = ESteps.Done;
- Status = EStatus.Failed;
- LastError = $"Not found assetBundle file : {FileLoadPath}";
- YooLogger.Error(LastError);
- return;
- }
-#endif
-
- // 设置下载进度
- DownloadProgress = 1f;
- DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
-
- // 加载AssetBundle资源对象
- // 注意:解密服务类可能会返回空的对象。
- if (_isWaitForAsyncComplete)
- CacheBundle = MainBundleInfo.LoadAssetBundle(FileLoadPath, out _managedStream);
- else
- _createRequest = MainBundleInfo.LoadAssetBundleAsync(FileLoadPath, out _managedStream);
-
- _steps = ESteps.CheckLoadFile;
- }
-
- // 6. 加载AssetBundle
- if (_steps == ESteps.LoadDeliveryFile)
- {
- // 设置下载进度
- DownloadProgress = 1f;
- DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
-
- // Load assetBundle file
- if (_isWaitForAsyncComplete)
- CacheBundle = MainBundleInfo.LoadDeliveryAssetBundle(FileLoadPath);
- else
- _createRequest = MainBundleInfo.LoadDeliveryAssetBundleAsync(FileLoadPath);
-
- _steps = ESteps.CheckLoadFile;
- }
-
- // 7. 检测AssetBundle加载结果
- if (_steps == ESteps.CheckLoadFile)
- {
- if (_createRequest != null)
- {
- if (_isWaitForAsyncComplete || IsForceDestroyComplete)
- {
- // 强制挂起主线程(注意:该操作会很耗时)
- YooLogger.Warning("Suspend the main thread to load unity bundle.");
- CacheBundle = _createRequest.assetBundle;
- }
- else
- {
- if (_createRequest.isDone == false)
- return;
- CacheBundle = _createRequest.assetBundle;
- }
- }
-
- // Check error
- if (CacheBundle == null)
- {
- // 注意:当缓存文件的校验等级为Low的时候,并不能保证缓存文件的完整性。
- // 在AssetBundle文件加载失败的情况下,我们需要重新验证文件的完整性!
- if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
- {
- var result = MainBundleInfo.VerifySelf();
- if (result == EVerifyResult.Succeed)
- {
- // 说明:在安卓移动平台,华为和三星真机上有极小概率加载资源包失败。
- // 大多数情况在首次安装下载资源到沙盒内,游戏过程中切换到后台再回到游戏内有很大概率触发!
- byte[] fileData = FileUtility.ReadAllBytes(FileLoadPath);
- if (fileData != null && fileData.Length > 0)
- CacheBundle = AssetBundle.LoadFromMemory(fileData);
- if (CacheBundle == null)
- {
- _steps = ESteps.Done;
- Status = EStatus.Failed;
- LastError = $"Failed to load assetBundle from memory : {MainBundleInfo.Bundle.BundleName}";
- YooLogger.Error(LastError);
- }
- else
- {
- _steps = ESteps.Done;
- Status = EStatus.Succeed;
- }
- }
- else
- {
- _steps = ESteps.Done;
- Status = EStatus.Failed;
- LastError = $"Found possibly corrupt file ! {MainBundleInfo.Bundle.CacheGUID} Verify result : {result}";
- YooLogger.Error(LastError);
- MainBundleInfo.CacheDiscard();
- }
- }
- else
- {
- _steps = ESteps.Done;
- Status = EStatus.Failed;
- LastError = $"Failed to load assetBundle : {MainBundleInfo.Bundle.BundleName}";
- YooLogger.Error(LastError);
- }
- }
- else
- {
- _steps = ESteps.Done;
- Status = EStatus.Succeed;
- }
- }
- }
-
- ///
- /// 销毁
- ///
- public override void Destroy()
- {
- base.Destroy();
-
- if (_managedStream != null)
- {
- _managedStream.Close();
- _managedStream.Dispose();
- _managedStream = null;
- }
- }
-
- ///
- /// 主线程等待异步操作完毕
- ///
- public override void WaitForAsyncComplete()
- {
- _isWaitForAsyncComplete = true;
-
- int frame = 1000;
- while (true)
- {
- // 文件解压
- if (_unpacker != null)
- {
- if (_unpacker.IsDone() == false)
- {
- _unpacker.WaitForAsyncComplete = true;
- _unpacker.Update();
- continue;
- }
- }
-
- // 保险机制
- // 注意:如果需要从WEB端下载资源,可能会触发保险机制!
- frame--;
- if (frame == 0)
- {
- if (_isShowWaitForAsyncError == false)
- {
- _isShowWaitForAsyncError = true;
- YooLogger.Error($"{nameof(WaitForAsyncComplete)} failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !");
- }
- break;
- }
-
- // 驱动流程
- Update();
-
- // 完成后退出
- if (IsDone())
- break;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleFileLoader.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleFileLoader.cs.meta
deleted file mode 100644
index a88ab9c7..00000000
--- a/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleFileLoader.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 64d0a51f59c2a964eaf97b87db47428f
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleWebLoader.cs b/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleWebLoader.cs
deleted file mode 100644
index 2d43aed7..00000000
--- a/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleWebLoader.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-using System;
-using System.IO;
-using System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-using UnityEngine.Networking;
-
-namespace YooAsset
-{
- ///
- /// WebGL平台加载器
- ///
- internal sealed class AssetBundleWebLoader : BundleLoaderBase
- {
- private enum ESteps
- {
- None = 0,
- LoadWebSiteFile,
- LoadRemoteFile,
- CheckLoadFile,
- Done,
- }
-
- private ESteps _steps = ESteps.None;
- private DownloaderBase _downloader;
-
-
- public AssetBundleWebLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
- {
- }
-
- ///
- /// 轮询更新
- ///
- public override void Update()
- {
- if (_steps == ESteps.Done)
- return;
-
- if (_steps == ESteps.None)
- {
- if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
- {
- _steps = ESteps.LoadRemoteFile;
- FileLoadPath = string.Empty;
- }
- else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
- {
- _steps = ESteps.LoadWebSiteFile;
- FileLoadPath = string.Empty;
- }
- else
- {
- throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
- }
- }
-
- // 1. 跨域获取资源包
- if (_steps == ESteps.LoadRemoteFile)
- {
- _downloader = MainBundleInfo.CreateDownloader(int.MaxValue);
- _downloader.SendRequest(true);
- _steps = ESteps.CheckLoadFile;
- }
-
- // 2. 从站点获取资源包
- if (_steps == ESteps.LoadWebSiteFile)
- {
- _downloader = MainBundleInfo.CreateUnpacker(int.MaxValue);
- _downloader.SendRequest(true);
- _steps = ESteps.CheckLoadFile;
- }
-
- // 3. 检测加载结果
- if (_steps == ESteps.CheckLoadFile)
- {
- DownloadProgress = _downloader.DownloadProgress;
- DownloadedBytes = _downloader.DownloadedBytes;
- if (_downloader.IsDone() == false)
- return;
-
- CacheBundle = _downloader.GetAssetBundle();
- if (CacheBundle == null)
- {
- _steps = ESteps.Done;
- Status = EStatus.Failed;
- LastError = $"AssetBundle file is invalid : {MainBundleInfo.Bundle.BundleName}";
- YooLogger.Error(LastError);
- }
- else
- {
- _steps = ESteps.Done;
- Status = EStatus.Succeed;
- }
- }
- }
-
- ///
- /// 主线程等待异步操作完毕
- ///
- public override void WaitForAsyncComplete()
- {
- if (IsDone() == false)
- {
- Status = EStatus.Failed;
- LastError = $"{nameof(WaitForAsyncComplete)} failed ! WebGL platform not support sync load method !";
- YooLogger.Error(LastError);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleWebLoader.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleWebLoader.cs.meta
deleted file mode 100644
index 3b5e44bf..00000000
--- a/Assets/YooAsset/Runtime/ResourceManager/Loader/AssetBundleWebLoader.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: bd1ad395c62c5804589ec9b267ea0484
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleLoaderBase.cs b/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleFileLoader.cs
similarity index 60%
rename from Assets/YooAsset/Runtime/ResourceManager/Loader/BundleLoaderBase.cs
rename to Assets/YooAsset/Runtime/ResourceManager/Loader/BundleFileLoader.cs
index 6039f89a..cfc49ba0 100644
--- a/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleLoaderBase.cs
+++ b/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleFileLoader.cs
@@ -5,7 +5,7 @@ using UnityEngine;
namespace YooAsset
{
- internal abstract class BundleLoaderBase
+ internal class BundleFileLoader
{
public enum EStatus
{
@@ -14,21 +14,17 @@ namespace YooAsset
Failed
}
- ///
- /// 所属资源系统
- ///
- public ResourceManager Impl { private set; get; }
+ private readonly ResourceManager _resourceManager;
+ private readonly List _providers = new List(100);
+ private readonly List _removeList = new List(100);
+ private FSLoadBundleOperation _loadBundleOp;
+ private bool _isDone = false;
///
/// 资源包文件信息
///
public BundleInfo MainBundleInfo { private set; get; }
- ///
- /// 引用计数
- ///
- public int RefCount { private set; get; }
-
///
/// 加载状态
///
@@ -37,30 +33,87 @@ namespace YooAsset
///
/// 最近的错误信息
///
- public string LastError { protected set; get; }
+ public string LastError { protected set; get; } = string.Empty;
///
/// 是否已经销毁
///
public bool IsDestroyed { private set; get; } = false;
- private readonly List _providers = new List(100);
- private readonly List _removeList = new List(100);
- protected bool IsForceDestroyComplete { private set; get; } = false;
- internal AssetBundle CacheBundle { set; get; }
- internal string FileLoadPath { set; get; }
- internal float DownloadProgress { set; get; }
- internal ulong DownloadedBytes { set; get; }
+ ///
+ /// 引用计数
+ ///
+ public int RefCount { private set; get; } = 0;
+
+ ///
+ /// 下载进度
+ ///
+ public float DownloadProgress { set; get; } = 0;
+
+ ///
+ /// 下载大小
+ ///
+ public long DownloadedBytes { set; get; } = 0;
+
+ ///
+ /// 下载结果
+ ///
+ public object Result { set; get; }
- public BundleLoaderBase(ResourceManager impl, BundleInfo bundleInfo)
+ public BundleFileLoader(ResourceManager resourceManager, BundleInfo bundleInfo)
{
- Impl = impl;
+ _resourceManager = resourceManager;
MainBundleInfo = bundleInfo;
- RefCount = 0;
Status = EStatus.None;
}
+ ///
+ /// 轮询更新
+ ///
+ public void Update()
+ {
+ if (_isDone)
+ return;
+
+ if (_loadBundleOp == null)
+ _loadBundleOp = MainBundleInfo.LoadBundleFile();
+
+ DownloadProgress = _loadBundleOp.DownloadProgress;
+ DownloadedBytes = _loadBundleOp.DownloadedBytes;
+ if (_loadBundleOp.IsDone == false)
+ return;
+
+ if (_loadBundleOp.Status == EOperationStatus.Succeed)
+ {
+ _isDone = true;
+ Status = EStatus.Succeed;
+ Result = _loadBundleOp.Result;
+ }
+ else
+ {
+ _isDone = true;
+ Status = EStatus.Failed;
+ LastError = _loadBundleOp.Error;
+ }
+ }
+
+ ///
+ /// 销毁
+ ///
+ public void Destroy()
+ {
+ IsDestroyed = true;
+
+ // Check fatal
+ if (RefCount > 0)
+ throw new Exception($"Bundle file loader ref is not zero : {MainBundleInfo.Bundle.BundleName}");
+ if (IsDone() == false)
+ throw new Exception($"Bundle file loader is not done : {MainBundleInfo.Bundle.BundleName}");
+
+ MainBundleInfo.UnloadBundleFile(Result);
+ }
+
///
/// 引用(引用计数递加)
///
@@ -130,52 +183,40 @@ namespace YooAsset
// 移除资源提供者
if (_removeList.Count > 0)
{
- Impl.RemoveBundleProviders(_removeList);
+ _resourceManager.RemoveBundleProviders(_removeList);
_removeList.Clear();
}
}
-
- ///
- /// 轮询更新
- ///
- public abstract void Update();
-
- ///
- /// 销毁
- ///
- public virtual void Destroy()
- {
- IsDestroyed = true;
-
- // Check fatal
- if (RefCount > 0)
- throw new Exception($"Bundle file loader ref is not zero : {MainBundleInfo.Bundle.BundleName}");
- if (IsDone() == false)
- throw new Exception($"Bundle file loader is not done : {MainBundleInfo.Bundle.BundleName}");
-
- if (CacheBundle != null)
- {
- CacheBundle.Unload(true);
- CacheBundle = null;
- }
- }
-
- ///
- /// 强制销毁资源提供者
- ///
- public void ForceDestroyComplete()
- {
- IsForceDestroyComplete = true;
-
- // 注意:主动轮询更新完成同步加载
- // 说明:如果正在下载或解压也可以放心销毁。
- Update();
- }
-
///
/// 主线程等待异步操作完毕
///
- public abstract void WaitForAsyncComplete();
+ public void WaitForAsyncComplete()
+ {
+ while (true)
+ {
+ if (_loadBundleOp != null)
+ {
+ if (_loadBundleOp.IsDone == false)
+ _loadBundleOp.WaitForAsyncComplete();
+ }
+
+ // 驱动流程
+ Update();
+
+ // 完成后退出
+ if (IsDone())
+ break;
+ }
+ }
+
+ ///
+ /// 终止下载任务
+ ///
+ public void AbortDownloadOperation()
+ {
+ if (_loadBundleOp != null)
+ _loadBundleOp.AbortDownloadOperation();
+ }
}
}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleFileLoader.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleFileLoader.cs.meta
new file mode 100644
index 00000000..2aae8658
--- /dev/null
+++ b/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleFileLoader.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 031287bf937f83e4fa18a0db797abb42
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleLoaderBase.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleLoaderBase.cs.meta
deleted file mode 100644
index 5cd8fa4f..00000000
--- a/Assets/YooAsset/Runtime/ResourceManager/Loader/BundleLoaderBase.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: b8aaabc43e74af14d8eb3c7c85e19cda
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/DependAssetBundles.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/DependAssetBundles.cs.meta
deleted file mode 100644
index d770c0d6..00000000
--- a/Assets/YooAsset/Runtime/ResourceManager/Loader/DependAssetBundles.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: b7eeccc96e4c31c45bd105b0dbc3fd6e
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/DependAssetBundles.cs b/Assets/YooAsset/Runtime/ResourceManager/Loader/DependFileLoaders.cs
similarity index 89%
rename from Assets/YooAsset/Runtime/ResourceManager/Loader/DependAssetBundles.cs
rename to Assets/YooAsset/Runtime/ResourceManager/Loader/DependFileLoaders.cs
index d2e5496b..c484afd3 100644
--- a/Assets/YooAsset/Runtime/ResourceManager/Loader/DependAssetBundles.cs
+++ b/Assets/YooAsset/Runtime/ResourceManager/Loader/DependFileLoaders.cs
@@ -4,15 +4,15 @@ using System.Collections.Generic;
namespace YooAsset
{
- internal class DependAssetBundles
+ internal class DependFileLoaders
{
///
/// 依赖的资源包加载器列表
///
- internal readonly List DependList;
+ internal readonly List DependList;
- public DependAssetBundles(List dpendList)
+ public DependFileLoaders(List dpendList)
{
DependList = dpendList;
}
@@ -37,7 +37,7 @@ namespace YooAsset
{
foreach (var loader in DependList)
{
- if (loader.Status != BundleLoaderBase.EStatus.Succeed)
+ if (loader.Status != BundleFileLoader.EStatus.Succeed)
{
return false;
}
@@ -52,7 +52,7 @@ namespace YooAsset
{
foreach (var loader in DependList)
{
- if (loader.Status != BundleLoaderBase.EStatus.Succeed)
+ if (loader.Status != BundleFileLoader.EStatus.Succeed)
{
return loader.LastError;
}
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/DependFileLoaders.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/DependFileLoaders.cs.meta
new file mode 100644
index 00000000..edd0393a
--- /dev/null
+++ b/Assets/YooAsset/Runtime/ResourceManager/Loader/DependFileLoaders.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3834f832061fdd74fbfb1eba381b1b3e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadStatus.cs b/Assets/YooAsset/Runtime/ResourceManager/Loader/DownloadStatus.cs
similarity index 57%
rename from Assets/YooAsset/Runtime/DownloadSystem/DownloadStatus.cs
rename to Assets/YooAsset/Runtime/ResourceManager/Loader/DownloadStatus.cs
index 880d81d1..038503c1 100644
--- a/Assets/YooAsset/Runtime/DownloadSystem/DownloadStatus.cs
+++ b/Assets/YooAsset/Runtime/ResourceManager/Loader/DownloadStatus.cs
@@ -4,32 +4,28 @@ namespace YooAsset
public struct DownloadStatus
{
///
- /// 下载是否完成
+ /// 下载是否已经完成
///
public bool IsDone;
///
- /// 下载进度(0f~1f)
+ /// 下载进度(0-1f)
///
public float Progress;
///
- /// 需要下载的总字节数
+ /// 下载文件的总大小
///
- public ulong TotalBytes;
+ public long TotalBytes;
///
- /// 已经下载的字节数
+ /// 已经下载的文件大小
///
- public ulong DownloadedBytes;
+ public long DownloadedBytes;
public static DownloadStatus CreateDefaultStatus()
{
DownloadStatus status = new DownloadStatus();
- status.IsDone = false;
- status.Progress = 0f;
- status.TotalBytes = 0;
- status.DownloadedBytes = 0;
return status;
}
}
diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadStatus.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/DownloadStatus.cs.meta
similarity index 83%
rename from Assets/YooAsset/Runtime/DownloadSystem/DownloadStatus.cs.meta
rename to Assets/YooAsset/Runtime/ResourceManager/Loader/DownloadStatus.cs.meta
index 43818f2f..28567282 100644
--- a/Assets/YooAsset/Runtime/DownloadSystem/DownloadStatus.cs.meta
+++ b/Assets/YooAsset/Runtime/ResourceManager/Loader/DownloadStatus.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: d40b8341fcd4ad2478eb1a890ebf0476
+guid: 26dbf3c6610209e40bcf31c9c66739bc
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleFileLoader.cs b/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleFileLoader.cs
deleted file mode 100644
index f1163ee7..00000000
--- a/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleFileLoader.cs
+++ /dev/null
@@ -1,188 +0,0 @@
-using System.IO;
-
-namespace YooAsset
-{
- internal class RawBundleFileLoader : BundleLoaderBase
- {
- private enum ESteps
- {
- None,
- Download,
- CheckDownload,
- Unpack,
- CheckUnpack,
- CheckFile,
- Done,
- }
-
- private ESteps _steps = ESteps.None;
- private DownloaderBase _unpacker;
- private DownloaderBase _downloader;
-
-
- public RawBundleFileLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
- {
- }
-
- ///
- /// 轮询更新
- ///
- public override void Update()
- {
- if (_steps == ESteps.Done)
- return;
-
- if (_steps == ESteps.None)
- {
- if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
- {
- _steps = ESteps.Download;
- FileLoadPath = MainBundleInfo.CachedDataFilePath;
- }
- else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
- {
-#if UNITY_ANDROID
- _steps = ESteps.Unpack;
- FileLoadPath = MainBundleInfo.CachedDataFilePath;
-#else
- _steps = ESteps.CheckFile;
- FileLoadPath = MainBundleInfo.BuildinFilePath;
-#endif
- }
- else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
- {
- _steps = ESteps.CheckFile;
- FileLoadPath = MainBundleInfo.CachedDataFilePath;
- }
- else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromDelivery)
- {
- _steps = ESteps.CheckFile;
- FileLoadPath = MainBundleInfo.DeliveryFilePath;
- }
- else
- {
- throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
- }
- }
-
- // 1. 下载远端文件
- if (_steps == ESteps.Download)
- {
- _downloader = MainBundleInfo.CreateDownloader(int.MaxValue);
- _downloader.SendRequest();
- _steps = ESteps.CheckDownload;
- }
-
- // 2. 检测下载结果
- if (_steps == ESteps.CheckDownload)
- {
- DownloadProgress = _downloader.DownloadProgress;
- DownloadedBytes = _downloader.DownloadedBytes;
- if (_downloader.IsDone() == false)
- return;
-
- if (_downloader.HasError())
- {
- _steps = ESteps.Done;
- Status = EStatus.Failed;
- LastError = _downloader.GetLastError();
- }
- else
- {
- _steps = ESteps.CheckFile;
- }
- }
-
- // 3. 解压内置文件
- if (_steps == ESteps.Unpack)
- {
- int failedTryAgain = 1;
- _unpacker = MainBundleInfo.CreateUnpacker(failedTryAgain);
- _unpacker.SendRequest();
- _steps = ESteps.CheckUnpack;
- }
-
- // 4. 检测解压结果
- if (_steps == ESteps.CheckUnpack)
- {
- DownloadProgress = _unpacker.DownloadProgress;
- DownloadedBytes = _unpacker.DownloadedBytes;
- if (_unpacker.IsDone() == false)
- return;
-
- if (_unpacker.HasError())
- {
- _steps = ESteps.Done;
- Status = EStatus.Failed;
- LastError = _unpacker.GetLastError();
- }
- else
- {
- _steps = ESteps.CheckFile;
- }
- }
-
- // 5. 检测结果
- if (_steps == ESteps.CheckFile)
- {
- // 设置下载进度
- DownloadProgress = 1f;
- DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
-
- if (File.Exists(FileLoadPath))
- {
- _steps = ESteps.Done;
- Status = EStatus.Succeed;
- }
- else
- {
- _steps = ESteps.Done;
- Status = EStatus.Failed;
- LastError = $"Raw file not found : {FileLoadPath}";
- }
- }
- }
-
- ///
- /// 主线程等待异步操作完毕
- ///
- public override void WaitForAsyncComplete()
- {
- int frame = 1000;
- while (true)
- {
- // 文件解压
- if (_unpacker != null)
- {
- if (_unpacker.IsDone() == false)
- {
- _unpacker.WaitForAsyncComplete = true;
- _unpacker.Update();
- continue;
- }
- }
-
- // 保险机制
- // 注意:如果需要从远端下载资源,可能会触发保险机制!
- frame--;
- if (frame == 0)
- {
- if (IsDone() == false)
- {
- Status = EStatus.Failed;
- LastError = $"WaitForAsyncComplete failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !";
- YooLogger.Error(LastError);
- }
- break;
- }
-
- // 驱动流程
- Update();
-
- // 完成后退出
- if (IsDone())
- break;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleFileLoader.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleFileLoader.cs.meta
deleted file mode 100644
index 011a6a35..00000000
--- a/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleFileLoader.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: fa39f24727abe514093f18787c0c7e27
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleWebLoader.cs b/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleWebLoader.cs
deleted file mode 100644
index 18c37a31..00000000
--- a/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleWebLoader.cs
+++ /dev/null
@@ -1,145 +0,0 @@
-using System.IO;
-
-namespace YooAsset
-{
- ///
- /// WebGL平台加载器
- ///
- internal class RawBundleWebLoader : BundleLoaderBase
- {
- private enum ESteps
- {
- None,
- Download,
- CheckDownload,
- Website,
- CheckWebsite,
- CheckFile,
- Done,
- }
-
- private ESteps _steps = ESteps.None;
- private DownloaderBase _website;
- private DownloaderBase _downloader;
-
-
- public RawBundleWebLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
- {
- }
-
- ///
- /// 轮询更新
- ///
- public override void Update()
- {
- if (_steps == ESteps.Done)
- return;
-
- if (_steps == ESteps.None)
- {
- if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
- {
- _steps = ESteps.Download;
- FileLoadPath = MainBundleInfo.CachedDataFilePath;
- }
- else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
- {
- _steps = ESteps.Website;
- FileLoadPath = MainBundleInfo.CachedDataFilePath;
- }
- else
- {
- throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
- }
- }
-
- // 1. 下载远端文件
- if (_steps == ESteps.Download)
- {
- _downloader = MainBundleInfo.CreateDownloader(int.MaxValue);
- _downloader.SendRequest();
- _steps = ESteps.CheckDownload;
- }
-
- // 2. 检测下载结果
- if (_steps == ESteps.CheckDownload)
- {
- DownloadProgress = _downloader.DownloadProgress;
- DownloadedBytes = _downloader.DownloadedBytes;
- if (_downloader.IsDone() == false)
- return;
-
- if (_downloader.HasError())
- {
- _steps = ESteps.Done;
- Status = EStatus.Failed;
- LastError = _downloader.GetLastError();
- }
- else
- {
- _steps = ESteps.CheckFile;
- }
- }
-
- // 3. 从站点下载
- if (_steps == ESteps.Website)
- {
- _website = MainBundleInfo.CreateUnpacker(int.MaxValue);
- _website.SendRequest();
- _steps = ESteps.CheckWebsite;
- }
-
- // 4. 检测站点下载
- if (_steps == ESteps.CheckWebsite)
- {
- DownloadProgress = _website.DownloadProgress;
- DownloadedBytes = _website.DownloadedBytes;
- if (_website.IsDone() == false)
- return;
-
- if (_website.HasError())
- {
- _steps = ESteps.Done;
- Status = EStatus.Failed;
- LastError = _website.GetLastError();
- }
- else
- {
- _steps = ESteps.CheckFile;
- }
- }
-
- // 5. 检测结果
- if (_steps == ESteps.CheckFile)
- {
- // 设置下载进度
- DownloadProgress = 1f;
- DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
-
- _steps = ESteps.Done;
- if (File.Exists(FileLoadPath))
- {
- Status = EStatus.Succeed;
- }
- else
- {
- Status = EStatus.Failed;
- LastError = $"Raw file not found : {FileLoadPath}";
- }
- }
- }
-
- ///
- /// 主线程等待异步操作完毕
- ///
- public override void WaitForAsyncComplete()
- {
- if (IsDone() == false)
- {
- Status = EStatus.Failed;
- LastError = $"{nameof(WaitForAsyncComplete)} failed ! WebGL platform not support sync load method !";
- YooLogger.Error(LastError);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleWebLoader.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleWebLoader.cs.meta
deleted file mode 100644
index 6420e988..00000000
--- a/Assets/YooAsset/Runtime/ResourceManager/Loader/RawBundleWebLoader.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 1d16b689f73611e44bd01a4cc429a6ac
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/VirtualBundleFileLoader.cs b/Assets/YooAsset/Runtime/ResourceManager/Loader/VirtualBundleFileLoader.cs
deleted file mode 100644
index c90a6ddc..00000000
--- a/Assets/YooAsset/Runtime/ResourceManager/Loader/VirtualBundleFileLoader.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-
-namespace YooAsset
-{
- internal class VirtualBundleFileLoader : BundleLoaderBase
- {
- private enum ESteps
- {
- None,
- CheckFile,
- Done,
- }
-
- private ESteps _steps = ESteps.None;
-
- public VirtualBundleFileLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
- {
- }
-
- ///
- /// 轮询更新
- ///
- public override void Update()
- {
- if (_steps == ESteps.Done)
- return;
-
- if (_steps == ESteps.None)
- {
- if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromEditor)
- {
- _steps = ESteps.CheckFile;
- }
- else
- {
- throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
- }
- }
-
- // 1. 检测结果
- if (_steps == ESteps.CheckFile)
- {
- // 设置下载进度
- DownloadProgress = 1f;
- DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
-
- _steps = ESteps.Done;
- Status = EStatus.Succeed;
- }
- }
-
- ///
- /// 主线程等待异步操作完毕
- ///
- public override void WaitForAsyncComplete()
- {
- int frame = 1000;
- while (true)
- {
- // 保险机制
- // 注意:如果需要从远端下载资源,可能会触发保险机制!
- frame--;
- if (frame == 0)
- {
- if (IsDone() == false)
- {
- Status = EStatus.Failed;
- LastError = $"WaitForAsyncComplete failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !";
- YooLogger.Error(LastError);
- }
- break;
- }
-
- // 驱动流程
- Update();
-
- // 完成后退出
- if (IsDone())
- break;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Loader/VirtualBundleFileLoader.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Loader/VirtualBundleFileLoader.cs.meta
deleted file mode 100644
index c8289e17..00000000
--- a/Assets/YooAsset/Runtime/ResourceManager/Loader/VirtualBundleFileLoader.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 7b9023a940b496549894d9d8872219fb
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOperation.cs
index 1b4b762b..68158a47 100644
--- a/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOperation.cs
+++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOperation.cs
@@ -72,23 +72,10 @@ namespace YooAsset
}
}
- ///
- /// 取消实例化对象操作
- ///
- public void Cancel()
- {
- if (IsDone == false)
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Failed;
- Error = $"User cancelled !";
- }
- }
-
///
/// 等待异步实例化结束
///
- public void WaitForAsyncComplete()
+ public override void WaitForAsyncComplete()
{
if (_steps == ESteps.Done)
return;
@@ -96,6 +83,14 @@ namespace YooAsset
InternalOnUpdate();
}
+ ///
+ /// 取消实例化对象操作
+ ///
+ public void Cancel()
+ {
+ SetAbort();
+ }
+
internal static GameObject InstantiateInternal(UnityEngine.Object assetObject, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays)
{
if (assetObject == null)
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs
new file mode 100644
index 00000000..b0563fb7
--- /dev/null
+++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs
@@ -0,0 +1,94 @@
+using System;
+using UnityEngine;
+
+namespace YooAsset
+{
+ public sealed class UnloadAllAssetsOperation : AsyncOperationBase
+ {
+ private enum ESteps
+ {
+ None,
+ AbortDownload,
+ CheckLoading,
+ UnloadAll,
+ Done,
+ }
+
+ private readonly ResourceManager _resManager;
+ private ESteps _steps = ESteps.None;
+
+ internal UnloadAllAssetsOperation(ResourceManager resourceManager)
+ {
+ _resManager = resourceManager;
+ }
+ internal override void InternalOnStart()
+ {
+ _steps = ESteps.AbortDownload;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.AbortDownload)
+ {
+ // 注意:终止所有下载任务
+ var loaderList = _resManager._loaderList;
+ foreach (var loader in loaderList)
+ {
+ loader.AbortDownloadOperation();
+ }
+ _steps = ESteps.CheckLoading;
+ }
+
+ if (_steps == ESteps.CheckLoading)
+ {
+ // 注意:等待所有任务完成
+ var providerDic = _resManager._providerDic;
+ foreach (var provider in providerDic.Values)
+ {
+ if (provider.IsDone == false)
+ return;
+ }
+ _steps = ESteps.UnloadAll;
+ }
+
+ if (_steps == ESteps.UnloadAll)
+ {
+ var loaderList = _resManager._loaderList;
+ var loaderDic = _resManager._loaderDic;
+ var providerDic = _resManager._providerDic;
+
+ // 释放所有资源句柄
+ foreach (var provider in providerDic.Values)
+ {
+ provider.ReleaseAllHandles();
+ }
+
+ // 强制销毁资源提供者
+ foreach (var provider in providerDic.Values)
+ {
+ provider.Destroy();
+ }
+
+ // 强制销毁文件加载器
+ foreach (var loader in loaderList)
+ {
+ loader.Destroy();
+ }
+
+ // 清空数据
+ providerDic.Clear();
+ loaderList.Clear();
+ loaderDic.Clear();
+ _resManager.ClearSceneHandle();
+
+ // 注意:调用底层接口释放所有资源
+ Resources.UnloadUnusedAssets();
+
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs.meta
new file mode 100644
index 00000000..f76659be
--- /dev/null
+++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 97b5f55d30137a4438d3cbed93819c6b
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs
new file mode 100644
index 00000000..9c4708d8
--- /dev/null
+++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs
@@ -0,0 +1,62 @@
+using System;
+using UnityEngine;
+
+namespace YooAsset
+{
+ public sealed class UnloadUnusedAssetsOperation : AsyncOperationBase
+ {
+ private enum ESteps
+ {
+ None,
+ UnloadUnused,
+ Done,
+ }
+
+ private readonly ResourceManager _resManager;
+ private ESteps _steps = ESteps.None;
+
+ internal UnloadUnusedAssetsOperation(ResourceManager resourceManager)
+ {
+ _resManager = resourceManager;
+ }
+ internal override void InternalOnStart()
+ {
+ _steps = ESteps.UnloadUnused;
+ }
+ internal override void InternalOnUpdate()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.UnloadUnused)
+ {
+ var loaderList = _resManager._loaderList;
+ var loaderDic = _resManager._loaderDic;
+
+ for (int i = loaderList.Count - 1; i >= 0; i--)
+ {
+ BundleFileLoader loader = loaderList[i];
+ loader.TryDestroyProviders();
+ }
+
+ for (int i = loaderList.Count - 1; i >= 0; i--)
+ {
+ BundleFileLoader loader = loaderList[i];
+ if (loader.CanDestroy())
+ {
+ string bundleName = loader.MainBundleInfo.Bundle.BundleName;
+ loader.Destroy();
+ loaderList.RemoveAt(i);
+ loaderDic.Remove(bundleName);
+ }
+ }
+
+ // 注意:调用底层接口释放所有资源
+ Resources.UnloadUnusedAssets();
+
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs.meta b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs.meta
new file mode 100644
index 00000000..6556c042
--- /dev/null
+++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 90a7cd6101e04ac48ae6aa383572d2c4
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAllAssetsProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAllAssetsProvider.cs
index 7182738b..0266506b 100644
--- a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAllAssetsProvider.cs
+++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAllAssetsProvider.cs
@@ -6,6 +6,7 @@ namespace YooAsset
{
internal sealed class BundledAllAssetsProvider : ProviderBase
{
+ private AssetBundle _assetBundle;
private AssetBundleRequest _cacheRequest;
public BundledAllAssetsProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
@@ -30,54 +31,62 @@ namespace YooAsset
{
if (IsWaitForAsyncComplete)
{
- DependBundles.WaitForAsyncComplete();
- OwnerBundle.WaitForAsyncComplete();
+ DependLoaders.WaitForAsyncComplete();
+ FileLoader.WaitForAsyncComplete();
}
- if (DependBundles.IsDone() == false)
+ if (DependLoaders.IsDone() == false)
return;
- if (OwnerBundle.IsDone() == false)
+ if (FileLoader.IsDone() == false)
return;
- if (DependBundles.IsSucceed() == false)
+ if (DependLoaders.IsSucceed() == false)
{
- string error = DependBundles.GetLastError();
+ string error = DependLoaders.GetLastError();
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
- if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
+ if (FileLoader.Status != BundleFileLoader.EStatus.Succeed)
{
- string error = OwnerBundle.LastError;
+ string error = FileLoader.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
- if (OwnerBundle.CacheBundle == null)
+ if (FileLoader.Result == null)
{
- ProcessCacheBundleException();
+ ProcessFatalEvent();
return;
}
+ if (FileLoader.Result is AssetBundle == false)
+ {
+ string error = "Try load raw file using load assetbundle method !";
+ InvokeCompletion(error, EOperationStatus.Failed);
+ return;
+ }
+
+ _assetBundle = FileLoader.Result as AssetBundle;
_steps = ESteps.Loading;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
- if (IsWaitForAsyncComplete || IsForceDestroyComplete)
+ if (IsWaitForAsyncComplete)
{
if (MainAssetInfo.AssetType == null)
- AllAssetObjects = OwnerBundle.CacheBundle.LoadAllAssets();
+ AllAssetObjects = _assetBundle.LoadAllAssets();
else
- AllAssetObjects = OwnerBundle.CacheBundle.LoadAllAssets(MainAssetInfo.AssetType);
+ AllAssetObjects = _assetBundle.LoadAllAssets(MainAssetInfo.AssetType);
}
else
{
if (MainAssetInfo.AssetType == null)
- _cacheRequest = OwnerBundle.CacheBundle.LoadAllAssetsAsync();
+ _cacheRequest = _assetBundle.LoadAllAssetsAsync();
else
- _cacheRequest = OwnerBundle.CacheBundle.LoadAllAssetsAsync(MainAssetInfo.AssetType);
+ _cacheRequest = _assetBundle.LoadAllAssetsAsync(MainAssetInfo.AssetType);
}
_steps = ESteps.Checking;
}
@@ -87,7 +96,7 @@ namespace YooAsset
{
if (_cacheRequest != null)
{
- if (IsWaitForAsyncComplete || IsForceDestroyComplete)
+ if (IsWaitForAsyncComplete)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity asset.");
@@ -106,9 +115,9 @@ namespace YooAsset
{
string error;
if (MainAssetInfo.AssetType == null)
- error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
+ error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {FileLoader.MainBundleInfo.Bundle.BundleName}";
else
- error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
+ error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {FileLoader.MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAssetProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAssetProvider.cs
index a77a1f34..7af1d013 100644
--- a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAssetProvider.cs
+++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAssetProvider.cs
@@ -6,6 +6,7 @@ namespace YooAsset
{
internal sealed class BundledAssetProvider : ProviderBase
{
+ private AssetBundle _assetBundle;
private AssetBundleRequest _cacheRequest;
public BundledAssetProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
@@ -30,54 +31,62 @@ namespace YooAsset
{
if (IsWaitForAsyncComplete)
{
- DependBundles.WaitForAsyncComplete();
- OwnerBundle.WaitForAsyncComplete();
+ DependLoaders.WaitForAsyncComplete();
+ FileLoader.WaitForAsyncComplete();
}
- if (DependBundles.IsDone() == false)
+ if (DependLoaders.IsDone() == false)
return;
- if (OwnerBundle.IsDone() == false)
+ if (FileLoader.IsDone() == false)
return;
- if (DependBundles.IsSucceed() == false)
+ if (DependLoaders.IsSucceed() == false)
{
- string error = DependBundles.GetLastError();
+ string error = DependLoaders.GetLastError();
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
- if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
+ if (FileLoader.Status != BundleFileLoader.EStatus.Succeed)
{
- string error = OwnerBundle.LastError;
+ string error = FileLoader.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
- if (OwnerBundle.CacheBundle == null)
+ if (FileLoader.Result == null)
{
- ProcessCacheBundleException();
+ ProcessFatalEvent();
return;
}
+ if (FileLoader.Result is AssetBundle == false)
+ {
+ string error = "Try load raw file using load assetbundle method !";
+ InvokeCompletion(error, EOperationStatus.Failed);
+ return;
+ }
+
+ _assetBundle = FileLoader.Result as AssetBundle;
_steps = ESteps.Loading;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
- if (IsWaitForAsyncComplete || IsForceDestroyComplete)
+ if (IsWaitForAsyncComplete)
{
if (MainAssetInfo.AssetType == null)
- AssetObject = OwnerBundle.CacheBundle.LoadAsset(MainAssetInfo.AssetPath);
+ AssetObject = _assetBundle.LoadAsset(MainAssetInfo.AssetPath);
else
- AssetObject = OwnerBundle.CacheBundle.LoadAsset(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
+ AssetObject = _assetBundle.LoadAsset(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
}
else
{
if (MainAssetInfo.AssetType == null)
- _cacheRequest = OwnerBundle.CacheBundle.LoadAssetAsync(MainAssetInfo.AssetPath);
+ _cacheRequest = _assetBundle.LoadAssetAsync(MainAssetInfo.AssetPath);
else
- _cacheRequest = OwnerBundle.CacheBundle.LoadAssetAsync(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
+ _cacheRequest = _assetBundle.LoadAssetAsync(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
}
_steps = ESteps.Checking;
}
@@ -87,7 +96,7 @@ namespace YooAsset
{
if (_cacheRequest != null)
{
- if (IsWaitForAsyncComplete || IsForceDestroyComplete)
+ if (IsWaitForAsyncComplete)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity asset.");
@@ -106,9 +115,9 @@ namespace YooAsset
{
string error;
if (MainAssetInfo.AssetType == null)
- error = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
+ error = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {FileLoader.MainBundleInfo.Bundle.BundleName}";
else
- error = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
+ error = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {FileLoader.MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledRawFileProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledRawFileProvider.cs
index 4a104a83..1ef2a9de 100644
--- a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledRawFileProvider.cs
+++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledRawFileProvider.cs
@@ -24,16 +24,21 @@ namespace YooAsset
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
- {
- OwnerBundle.WaitForAsyncComplete();
- }
+ FileLoader.WaitForAsyncComplete();
- if (OwnerBundle.IsDone() == false)
+ if (FileLoader.IsDone() == false)
return;
- if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
+ if (FileLoader.Status != BundleFileLoader.EStatus.Succeed)
{
- string error = OwnerBundle.LastError;
+ string error = FileLoader.LastError;
+ InvokeCompletion(error, EOperationStatus.Failed);
+ return;
+ }
+
+ if (FileLoader.Result is string == false)
+ {
+ string error = "Try load AssetBundle file using load raw file method !";
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
@@ -44,7 +49,7 @@ namespace YooAsset
// 2. 检测加载结果
if (_steps == ESteps.Checking)
{
- RawFilePath = OwnerBundle.FileLoadPath;
+ RawFilePath = FileLoader.Result as string;
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSceneProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSceneProvider.cs
index eda57712..b684bd9d 100644
--- a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSceneProvider.cs
+++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSceneProvider.cs
@@ -37,25 +37,25 @@ namespace YooAsset
{
if (IsWaitForAsyncComplete)
{
- DependBundles.WaitForAsyncComplete();
- OwnerBundle.WaitForAsyncComplete();
+ DependLoaders.WaitForAsyncComplete();
+ FileLoader.WaitForAsyncComplete();
}
- if (DependBundles.IsDone() == false)
+ if (DependLoaders.IsDone() == false)
return;
- if (OwnerBundle.IsDone() == false)
+ if (FileLoader.IsDone() == false)
return;
- if (DependBundles.IsSucceed() == false)
+ if (DependLoaders.IsSucceed() == false)
{
- string error = DependBundles.GetLastError();
+ string error = DependLoaders.GetLastError();
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
- if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
+ if (FileLoader.Status != BundleFileLoader.EStatus.Succeed)
{
- string error = OwnerBundle.LastError;
+ string error = FileLoader.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
@@ -66,7 +66,7 @@ namespace YooAsset
// 2. 加载场景
if (_steps == ESteps.Loading)
{
- if (IsWaitForAsyncComplete || IsForceDestroyComplete)
+ if (IsWaitForAsyncComplete)
{
// 注意:场景同步加载方法不会立即加载场景,而是在下一帧加载。
LoadSceneParameters parameters = new LoadSceneParameters(SceneMode);
@@ -99,7 +99,7 @@ namespace YooAsset
{
if (_asyncOperation != null)
{
- if (IsWaitForAsyncComplete || IsForceDestroyComplete)
+ if (IsWaitForAsyncComplete)
{
// 场景加载无法强制异步转同步
YooLogger.Error("The scene is loading asyn !");
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSubAssetsProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSubAssetsProvider.cs
index acc86410..7bc8e72e 100644
--- a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSubAssetsProvider.cs
+++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSubAssetsProvider.cs
@@ -6,6 +6,7 @@ namespace YooAsset
{
internal sealed class BundledSubAssetsProvider : ProviderBase
{
+ private AssetBundle _assetBundle;
private AssetBundleRequest _cacheRequest;
public BundledSubAssetsProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
@@ -30,54 +31,62 @@ namespace YooAsset
{
if (IsWaitForAsyncComplete)
{
- DependBundles.WaitForAsyncComplete();
- OwnerBundle.WaitForAsyncComplete();
+ DependLoaders.WaitForAsyncComplete();
+ FileLoader.WaitForAsyncComplete();
}
- if (DependBundles.IsDone() == false)
+ if (DependLoaders.IsDone() == false)
return;
- if (OwnerBundle.IsDone() == false)
+ if (FileLoader.IsDone() == false)
return;
- if (DependBundles.IsSucceed() == false)
+ if (DependLoaders.IsSucceed() == false)
{
- string error = DependBundles.GetLastError();
+ string error = DependLoaders.GetLastError();
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
- if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
+ if (FileLoader.Status != BundleFileLoader.EStatus.Succeed)
{
- string error = OwnerBundle.LastError;
+ string error = FileLoader.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
- if (OwnerBundle.CacheBundle == null)
+ if (FileLoader.Result == null)
{
- ProcessCacheBundleException();
+ ProcessFatalEvent();
return;
}
+ if (FileLoader.Result is AssetBundle == false)
+ {
+ string error = "Try load raw file using load assetbundle method !";
+ InvokeCompletion(error, EOperationStatus.Failed);
+ return;
+ }
+
+ _assetBundle = FileLoader.Result as AssetBundle;
_steps = ESteps.Loading;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
- if (IsWaitForAsyncComplete || IsForceDestroyComplete)
+ if (IsWaitForAsyncComplete)
{
if (MainAssetInfo.AssetType == null)
- AllAssetObjects = OwnerBundle.CacheBundle.LoadAssetWithSubAssets(MainAssetInfo.AssetPath);
+ AllAssetObjects = _assetBundle.LoadAssetWithSubAssets(MainAssetInfo.AssetPath);
else
- AllAssetObjects = OwnerBundle.CacheBundle.LoadAssetWithSubAssets(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
+ AllAssetObjects = _assetBundle.LoadAssetWithSubAssets(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
}
else
{
if (MainAssetInfo.AssetType == null)
- _cacheRequest = OwnerBundle.CacheBundle.LoadAssetWithSubAssetsAsync(MainAssetInfo.AssetPath);
+ _cacheRequest = _assetBundle.LoadAssetWithSubAssetsAsync(MainAssetInfo.AssetPath);
else
- _cacheRequest = OwnerBundle.CacheBundle.LoadAssetWithSubAssetsAsync(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
+ _cacheRequest = _assetBundle.LoadAssetWithSubAssetsAsync(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
}
_steps = ESteps.Checking;
}
@@ -87,7 +96,7 @@ namespace YooAsset
{
if (_cacheRequest != null)
{
- if (IsWaitForAsyncComplete || IsForceDestroyComplete)
+ if (IsWaitForAsyncComplete)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity asset.");
@@ -106,9 +115,9 @@ namespace YooAsset
{
string error;
if (MainAssetInfo.AssetType == null)
- error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
+ error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {FileLoader.MainBundleInfo.Bundle.BundleName}";
else
- error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
+ error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {FileLoader.MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAllAssetsProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAllAssetsProvider.cs
index 8e192718..d8a9604a 100644
--- a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAllAssetsProvider.cs
+++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAllAssetsProvider.cs
@@ -43,15 +43,15 @@ namespace YooAsset
{
if (IsWaitForAsyncComplete)
{
- OwnerBundle.WaitForAsyncComplete();
+ FileLoader.WaitForAsyncComplete();
}
- if (OwnerBundle.IsDone() == false)
+ if (FileLoader.IsDone() == false)
return;
- if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
+ if (FileLoader.Status != BundleFileLoader.EStatus.Succeed)
{
- string error = OwnerBundle.LastError;
+ string error = FileLoader.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
@@ -65,7 +65,7 @@ namespace YooAsset
if (MainAssetInfo.AssetType == null)
{
List result = new List