Update CacheSystem

优化缓存系统代码结构
pull/36/head
hevinci 2022-08-15 11:55:13 +08:00
parent aba68f859f
commit fbbf762e70
26 changed files with 306 additions and 446 deletions

View File

@ -273,7 +273,7 @@ namespace YooAsset
private static AssetBundleLoaderBase CreateAssetBundleLoaderInternal(BundleInfo bundleInfo)
{
// 如果加载器已经存在
AssetBundleLoaderBase loader = TryGetAssetBundleLoader(bundleInfo.BundleName);
AssetBundleLoaderBase loader = TryGetAssetBundleLoader(bundleInfo.Bundle.BundleName);
if (loader != null)
return loader;
@ -293,7 +293,7 @@ namespace YooAsset
for (int i = 0; i < _loaders.Count; i++)
{
AssetBundleLoaderBase temp = _loaders[i];
if (temp.MainBundleInfo.BundleName.Equals(bundleName))
if (temp.MainBundleInfo.Bundle.BundleName.Equals(bundleName))
{
loader = temp;
break;

View File

@ -40,29 +40,20 @@ namespace YooAsset
if (_steps == ESteps.None)
{
if (MainBundleInfo.IsInvalid)
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"The bundle info is invalid : {MainBundleInfo.BundleName}";
YooLogger.Error(LastError);
return;
}
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
{
_steps = ESteps.Download;
_fileLoadPath = MainBundleInfo.GetCacheLoadPath();
_fileLoadPath = MainBundleInfo.Bundle.CachedFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
_steps = ESteps.LoadFile;
_fileLoadPath = MainBundleInfo.GetStreamingLoadPath();
_fileLoadPath = MainBundleInfo.Bundle.StreamingFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
_steps = ESteps.LoadFile;
_fileLoadPath = MainBundleInfo.GetCacheLoadPath();
_fileLoadPath = MainBundleInfo.Bundle.CachedFilePath;
}
else
{
@ -112,15 +103,14 @@ namespace YooAsset
#endif
// Load assetBundle file
if (MainBundleInfo.IsEncrypted)
if (MainBundleInfo.Bundle.IsEncrypted)
{
if (AssetSystem.DecryptionServices == null)
throw new Exception($"{nameof(AssetBundleFileLoader)} need {nameof(IDecryptionServices)} : {MainBundleInfo.BundleName}");
throw new Exception($"{nameof(AssetBundleFileLoader)} need {nameof(IDecryptionServices)} : {MainBundleInfo.Bundle.BundleName}");
DecryptionFileInfo fileInfo = new DecryptionFileInfo();
fileInfo.BundleName = MainBundleInfo.BundleName;
fileInfo.FileHash = MainBundleInfo.FileHash;
fileInfo.FileCRC = MainBundleInfo.FileCRC;
fileInfo.BundleName = MainBundleInfo.Bundle.BundleName;
fileInfo.FileHash = MainBundleInfo.Bundle.FileHash;
ulong offset = AssetSystem.DecryptionServices.GetFileOffset(fileInfo);
if (_isWaitForAsyncComplete)
CacheBundle = AssetBundle.LoadFromFile(_fileLoadPath, 0, offset);
@ -161,15 +151,15 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"Failed to load assetBundle : {MainBundleInfo.BundleName}";
LastError = $"Failed to load assetBundle : {MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(LastError);
// 注意当缓存文件的校验等级为Low的时候并不能保证缓存文件的完整性。
// 在AssetBundle文件加载失败的情况下我们需要重新验证文件的完整性
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
string cacheLoadPath = MainBundleInfo.GetCacheLoadPath();
if (CacheSystem.CheckContentIntegrity(EVerifyLevel.High, cacheLoadPath, MainBundleInfo.FileSize, MainBundleInfo.FileCRC) == false)
string cacheLoadPath = MainBundleInfo.Bundle.CachedFilePath;
if (CacheSystem.VerifyBundle(MainBundleInfo.Bundle, EVerifyLevel.High) == false)
{
if (File.Exists(cacheLoadPath))
{
@ -205,7 +195,7 @@ namespace YooAsset
if (_isShowWaitForAsyncError == false)
{
_isShowWaitForAsyncError = true;
YooLogger.Error($"WaitForAsyncComplete failed ! Try load bundle : {MainBundleInfo.BundleName} from remote with sync load method !");
YooLogger.Error($"WaitForAsyncComplete failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !");
}
break;
}

View File

@ -91,9 +91,9 @@ namespace YooAsset
if (forceDestroy == false)
{
if (RefCount > 0)
throw new Exception($"Bundle file loader ref is not zero : {MainBundleInfo.BundleName}");
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.BundleName}");
throw new Exception($"Bundle file loader is not done : {MainBundleInfo.Bundle.BundleName}");
}
if (CacheBundle != null)

View File

@ -38,19 +38,10 @@ namespace YooAsset
if (_steps == ESteps.None)
{
if (MainBundleInfo.IsInvalid)
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"The bundle info is invalid : {MainBundleInfo.BundleName}";
YooLogger.Error(LastError);
return;
}
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
_steps = ESteps.LoadFile;
_webURL = MainBundleInfo.GetStreamingLoadPath();
_webURL = MainBundleInfo.Bundle.StreamingFilePath;
}
else
{
@ -61,7 +52,7 @@ namespace YooAsset
// 1. 从服务器或缓存中获取AssetBundle文件
if (_steps == ESteps.LoadFile)
{
_webRequest = UnityWebRequestAssetBundle.GetAssetBundle(_webURL, Hash128.Parse(MainBundleInfo.FileHash));
_webRequest = UnityWebRequestAssetBundle.GetAssetBundle(_webURL, Hash128.Parse(MainBundleInfo.Bundle.FileHash));
_webRequest.SendWebRequest();
_steps = ESteps.CheckFile;
}
@ -89,7 +80,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"AssetBundle file is invalid : {MainBundleInfo.BundleName}";
LastError = $"AssetBundle file is invalid : {MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(LastError);
}
else

View File

@ -102,7 +102,7 @@ namespace YooAsset
foreach (var loader in _dependBundles)
{
var bundleInfo = new DebugBundleInfo();
bundleInfo.BundleName = loader.MainBundleInfo.BundleName;
bundleInfo.BundleName = loader.MainBundleInfo.Bundle.BundleName;
bundleInfo.RefCount = loader.RefCount;
bundleInfo.Status = (int)loader.Status;
output.Add(bundleInfo);

View File

@ -171,14 +171,14 @@ namespace YooAsset
{
None,
Prepare,
DownloadFromApk,
CheckDownloadFromApk,
DownloadBuildinFile,
CheckDownload,
CheckAndCopyFile,
Done,
}
private ESteps _steps = ESteps.None;
private UnityWebFileRequester _fileRequester;
private DownloaderBase _downloader;
public OfflinePlayModeRawFileOperation(BundleInfo bundleInfo, string copyPath) : base(bundleInfo, copyPath)
{
@ -199,14 +199,15 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Bundle info is invalid : {_bundleInfo.BundleName}";
Error = $"Bundle info is invalid : {_bundleInfo.Bundle.BundleName}";
}
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
if (CacheSystem.ContainsVerifyFile(_bundleInfo.LoadBundle))
_steps = ESteps.DownloadBuildinFile;
}
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
_steps = ESteps.CheckAndCopyFile;
else
_steps = ESteps.DownloadFromApk;
}
else
{
@ -214,43 +215,32 @@ namespace YooAsset
}
}
// 2. 从APK拷贝文件
if (_steps == ESteps.DownloadFromApk)
// 2. 下载文件
if (_steps == ESteps.DownloadBuildinFile)
{
string downloadURL = PathHelper.ConvertToWWWPath(_bundleInfo.GetStreamingLoadPath());
_fileRequester = new UnityWebFileRequester();
_fileRequester.SendRequest(downloadURL, GetCachePath());
_steps = ESteps.CheckDownloadFromApk;
int failedTryAgain = int.MaxValue;
var bundleInfo = PatchHelper.ConvertToUnpackInfo(_bundleInfo.Bundle);
_downloader = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain);
_steps = ESteps.CheckDownload;
}
// 3. 检测APK拷贝文件结果
if (_steps == ESteps.CheckDownloadFromApk)
// 3. 检测下载结果
if (_steps == ESteps.CheckDownload)
{
Progress = _fileRequester.Progress();
if (_fileRequester.IsDone() == false)
Progress = _downloader.DownloadProgress;
if (_downloader.IsDone() == false)
return;
if (_fileRequester.HasError())
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _fileRequester.GetError();
Error = _downloader.GetLastError();
}
else
{
if (CacheSystem.CheckContentIntegrity(GetCachePath(), _bundleInfo.FileSize, _bundleInfo.FileCRC))
{
CacheSystem.CacheVerifyFile(_bundleInfo.LoadBundle);
_steps = ESteps.CheckAndCopyFile;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "File content verify failed !";
}
}
_fileRequester.Dispose();
}
// 4. 检测并拷贝原生文件
@ -267,7 +257,7 @@ namespace YooAsset
// 如果原生文件已经存在,则验证其完整性
if (File.Exists(CopyPath))
{
bool result = CacheSystem.CheckContentIntegrity(CopyPath, _bundleInfo.FileSize, _bundleInfo.FileCRC);
bool result = CacheSystem.VerifyContentInternal(CopyPath, _bundleInfo.Bundle.FileSize, _bundleInfo.Bundle.FileCRC, EVerifyLevel.High);
if (result)
{
_steps = ESteps.Done;
@ -303,7 +293,7 @@ namespace YooAsset
{
if (_bundleInfo == null)
return string.Empty;
return _bundleInfo.GetCacheLoadPath();
return _bundleInfo.Bundle.CachedFilePath;
}
}
@ -316,17 +306,15 @@ namespace YooAsset
{
None,
Prepare,
DownloadFromWeb,
CheckDownloadFromWeb,
DownloadFromApk,
CheckDownloadFromApk,
DownloadWebFile,
DownloadBuildinFile,
CheckDownload,
CheckAndCopyFile,
Done,
}
private ESteps _steps = ESteps.None;
private DownloaderBase _downloader;
private UnityWebFileRequester _fileRequester;
internal HostPlayModeRawFileOperation(BundleInfo bundleInfo, string copyPath) : base(bundleInfo, copyPath)
{
@ -347,18 +335,15 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Bundle info is invalid : {_bundleInfo.BundleName}";
Error = $"Bundle info is invalid : {_bundleInfo.Bundle.BundleName}";
}
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
{
_steps = ESteps.DownloadFromWeb;
_steps = ESteps.DownloadWebFile;
}
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
if (CacheSystem.ContainsVerifyFile(_bundleInfo.LoadBundle))
_steps = ESteps.CheckAndCopyFile;
else
_steps = ESteps.DownloadFromApk;
_steps = ESteps.DownloadBuildinFile;
}
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
@ -370,16 +355,25 @@ namespace YooAsset
}
}
// 2. 从服务器下载
if (_steps == ESteps.DownloadFromWeb)
// 2. 下载远端文件
if (_steps == ESteps.DownloadWebFile)
{
int failedTryAgain = int.MaxValue;
_downloader = DownloadSystem.BeginDownload(_bundleInfo, failedTryAgain);
_steps = ESteps.CheckDownloadFromWeb;
_steps = ESteps.CheckDownload;
}
// 3. 检测服务器下载结果
if (_steps == ESteps.CheckDownloadFromWeb)
// 3. 下载内置文件
if (_steps == ESteps.DownloadBuildinFile)
{
int failedTryAgain = int.MaxValue;
var bundleInfo = PatchHelper.ConvertToUnpackInfo(_bundleInfo.Bundle);
_downloader = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain);
_steps = ESteps.CheckDownload;
}
// 4. 检测下载结果
if (_steps == ESteps.CheckDownload)
{
Progress = _downloader.DownloadProgress;
if (_downloader.IsDone() == false)
@ -397,46 +391,7 @@ namespace YooAsset
}
}
// 4. 从APK拷贝文件
if (_steps == ESteps.DownloadFromApk)
{
string downloadURL = PathHelper.ConvertToWWWPath(_bundleInfo.GetStreamingLoadPath());
_fileRequester = new UnityWebFileRequester();
_fileRequester.SendRequest(downloadURL, GetCachePath());
_steps = ESteps.CheckDownloadFromApk;
}
// 5. 检测APK拷贝文件结果
if (_steps == ESteps.CheckDownloadFromApk)
{
Progress = _fileRequester.Progress();
if (_fileRequester.IsDone() == false)
return;
if (_fileRequester.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _fileRequester.GetError();
}
else
{
if (CacheSystem.CheckContentIntegrity(GetCachePath(), _bundleInfo.FileSize, _bundleInfo.FileCRC))
{
CacheSystem.CacheVerifyFile(_bundleInfo.LoadBundle);
_steps = ESteps.CheckAndCopyFile;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "File content verify failed !";
}
}
_fileRequester.Dispose();
}
// 6. 检测并拷贝原生文件
// 5. 检测并拷贝原生文件
if (_steps == ESteps.CheckAndCopyFile)
{
// 如果不需要保存文件
@ -450,7 +405,7 @@ namespace YooAsset
// 如果原生文件已经存在,则验证其完整性
if (File.Exists(CopyPath))
{
bool result = CacheSystem.CheckContentIntegrity(CopyPath, _bundleInfo.FileSize, _bundleInfo.FileCRC);
bool result = CacheSystem.VerifyContentInternal(CopyPath, _bundleInfo.Bundle.FileSize, _bundleInfo.Bundle.FileCRC, EVerifyLevel.High);
if (result)
{
_steps = ESteps.Done;
@ -486,7 +441,7 @@ namespace YooAsset
{
if (_bundleInfo == null)
return string.Empty;
return _bundleInfo.GetCacheLoadPath();
return _bundleInfo.Bundle.CachedFilePath;
}
}
}

View File

@ -65,7 +65,7 @@ namespace YooAsset
if (OwnerBundle.IsDestroyed)
throw new System.Exception("Should never get here !");
Status = EStatus.Fail;
LastError = $"The bundle {OwnerBundle.MainBundleInfo.BundleName} has been destroyed by unity bugs !";
LastError = $"The bundle {OwnerBundle.MainBundleInfo.Bundle.BundleName} has been destroyed by unity bugs !";
InvokeCompletion();
return;
}
@ -116,9 +116,9 @@ namespace YooAsset
if (Status == EStatus.Fail)
{
if (MainAssetInfo.AssetType == null)
LastError = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.BundleName}";
LastError = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
else
LastError = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.BundleName}";
LastError = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(LastError);
}
InvokeCompletion();

View File

@ -41,7 +41,7 @@ namespace YooAsset
internal void GetBundleDebugInfos(List<DebugBundleInfo> output)
{
var bundleInfo = new DebugBundleInfo();
bundleInfo.BundleName = OwnerBundle.MainBundleInfo.BundleName;
bundleInfo.BundleName = OwnerBundle.MainBundleInfo.Bundle.BundleName;
bundleInfo.RefCount = OwnerBundle.RefCount;
bundleInfo.Status = (int)OwnerBundle.Status;
output.Add(bundleInfo);

View File

@ -106,9 +106,9 @@ namespace YooAsset
if (Status == EStatus.Fail)
{
if (MainAssetInfo.AssetType == null)
LastError = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.BundleName}";
LastError = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
else
LastError = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.BundleName}";
LastError = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(LastError);
}
InvokeCompletion();

View File

@ -2,71 +2,46 @@
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
internal static class CacheSystem
{
private readonly static HashSet<PatchBundle> _cacheBundles = new HashSet<PatchBundle>();
private readonly static Dictionary<string, string> _cachedHashList = new Dictionary<string, string>(1000);
private static EVerifyLevel _verifyLevel = EVerifyLevel.High;
private readonly static Dictionary<string, PatchBundle> _cachedDic = new Dictionary<string, PatchBundle>(1000);
public static void Initialize(EVerifyLevel verifyLevel)
/// <summary>
/// 初始化时的验证级别
/// </summary>
public static EVerifyLevel InitVerifyLevel { private set; get; }
public static void Initialize(EVerifyLevel initVerifyLevel)
{
_verifyLevel = verifyLevel;
InitVerifyLevel = initVerifyLevel;
}
public static void DestroyAll()
{
_cacheBundles.Clear();
_cachedDic.Clear();
}
public static void WriteInfoFileForCachedFile()
{
}
public static void ReadInfoFileForCachedFile()
{
}
public static void GetCachingDiskSpaceUsed()
{
}
public static void GetCachingDiskSpaceFree()
{
}
public static bool IsCached(PatchBundle patchBundle)
{
return false;
}
public static void ClearCache()
{
}
/// <summary>
/// 查询是否为验证文件
/// 注意:被收录的文件完整性是绝对有效的
/// </summary>
public static bool ContainsVerifyFile(PatchBundle patchBundle)
public static bool IsCached(PatchBundle patchBundle)
{
string fileHash = patchBundle.FileHash;
if (_cachedHashList.ContainsKey(fileHash))
if (_cachedDic.ContainsKey(fileHash))
{
string fileName = _cachedHashList[fileHash];
string filePath = SandboxHelper.MakeCacheFilePath(fileName);
string filePath = patchBundle.CachedFilePath;
if (File.Exists(filePath))
{
return true;
}
else
{
_cachedHashList.Remove(fileHash);
YooLogger.Error($"Cache file is missing : {fileName}");
_cachedDic.Remove(fileHash);
YooLogger.Error($"Cache file is missing : {filePath}");
return false;
}
}
@ -77,31 +52,47 @@ namespace YooAsset
}
/// <summary>
/// 缓存验证过的文件
/// 缓存补丁包文件
/// </summary>
public static void CacheVerifyFile(PatchBundle patchBundle)
public static void CacheBundle(PatchBundle patchBundle)
{
string fileHash = patchBundle.FileHash;
string fileName = patchBundle.FileName;
if (_cachedHashList.ContainsKey(fileHash) == false)
if (_cachedDic.ContainsKey(fileHash) == false)
{
YooLogger.Log($"Cache verify file : {fileName}");
_cachedHashList.Add(fileHash, fileName);
string filePath = patchBundle.CachedFilePath;
YooLogger.Log($"Cache verify file : {filePath}");
_cachedDic.Add(fileHash, patchBundle);
}
}
/// <summary>
/// 验证补丁包文件
/// </summary>
public static bool VerifyBundle(PatchBundle patchBundle, EVerifyLevel verifyLevel)
{
return VerifyContentInternal(patchBundle.CachedFilePath, patchBundle.FileSize, patchBundle.FileCRC, verifyLevel);
}
/// <summary>
/// 验证并缓存补丁包文件
/// </summary>
public static bool VerifyAndCacheBundle(PatchBundle patchBundle, EVerifyLevel verifyLevel)
{
if (VerifyContentInternal(patchBundle.CachedFilePath, patchBundle.FileSize, patchBundle.FileCRC, verifyLevel))
{
CacheBundle(patchBundle);
return true;
}
else
{
return false;
}
}
/// <summary>
/// 验证文件完整性
/// </summary>
public static bool CheckContentIntegrity(string filePath, long fileSize, string fileCRC)
{
return CheckContentIntegrity(_verifyLevel, filePath, fileSize, fileCRC);
}
/// <summary>
/// 验证文件完整性
/// </summary>
public static bool CheckContentIntegrity(EVerifyLevel verifyLevel, string filePath, long fileSize, string fileCRC)
public static bool VerifyContentInternal(string filePath, long fileSize, string fileCRC, EVerifyLevel verifyLevel)
{
try
{

View File

@ -48,7 +48,7 @@ namespace YooAsset
foreach (var patchBundle in localPatchManifest.BundleList)
{
// 忽略缓存文件
if (CacheSystem.ContainsVerifyFile(patchBundle))
if (CacheSystem.IsCached(patchBundle))
continue;
// 忽略APP资源
@ -62,7 +62,7 @@ namespace YooAsset
// 注意:在弱联网模式下,我们需要验证指定资源版本的所有资源完整性
if (weaklyUpdate)
{
string filePath = SandboxHelper.MakeCacheFilePath(patchBundle.FileName);
string filePath = patchBundle.CachedFilePath;
if (File.Exists(filePath))
_waitingList.Add(patchBundle);
else
@ -70,7 +70,7 @@ namespace YooAsset
}
else
{
string filePath = SandboxHelper.MakeCacheFilePath(patchBundle.FileName);
string filePath = patchBundle.CachedFilePath;
if (File.Exists(filePath))
_waitingList.Add(patchBundle);
}
@ -124,14 +124,14 @@ namespace YooAsset
private bool VerifyFile(PatchBundle patchBundle)
{
string filePath = SandboxHelper.MakeCacheFilePath(patchBundle.FileName);
string filePath = patchBundle.CachedFilePath;
ThreadInfo info = new ThreadInfo(filePath, patchBundle);
return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), info);
}
private void VerifyInThread(object infoObj)
{
ThreadInfo info = (ThreadInfo)infoObj;
info.Result = CacheSystem.CheckContentIntegrity(info.FilePath, info.Bundle.FileSize, info.Bundle.FileCRC);
info.Result = CacheSystem.VerifyBundle(info.Bundle, CacheSystem.InitVerifyLevel);
_syncContext.Post(VerifyCallback, info);
}
private void VerifyCallback(object obj)
@ -140,17 +140,17 @@ namespace YooAsset
if (info.Result)
{
VerifySuccessCount++;
CacheSystem.CacheVerifyFile(info.Bundle);
CacheSystem.CacheBundle(info.Bundle);
}
else
{
VerifyFailCount++;
YooLogger.Warning($"Failed to verify file : {info.Bundle.CachedFilePath}");
// NOTE不期望删除断点续传的资源文件
/*
YooLogger.Warning($"Failed to verify file : {info.FilePath}");
if (File.Exists(info.FilePath))
File.Delete(info.FilePath);
if (File.Exists(patchBundle.CachedBundleFilePath))
File.Delete(patchBundle.CachedBundleFilePath);
*/
}
_verifyingList.Remove(info.Bundle);
@ -173,7 +173,7 @@ namespace YooAsset
foreach (var patchBundle in localPatchManifest.BundleList)
{
// 忽略缓存文件
if (CacheSystem.ContainsVerifyFile(patchBundle))
if (CacheSystem.IsCached(patchBundle))
continue;
// 忽略APP资源
@ -187,7 +187,7 @@ namespace YooAsset
// 注意:在弱联网模式下,我们需要验证指定资源版本的所有资源完整性
if (weaklyUpdate)
{
string filePath = SandboxHelper.MakeCacheFilePath(patchBundle.FileName);
string filePath = patchBundle.CachedFilePath;
if (File.Exists(filePath))
_waitingList.Add(patchBundle);
else
@ -195,7 +195,7 @@ namespace YooAsset
}
else
{
string filePath = SandboxHelper.MakeCacheFilePath(patchBundle.FileName);
string filePath = patchBundle.CachedFilePath;
if (File.Exists(filePath))
_waitingList.Add(patchBundle);
}
@ -234,22 +234,19 @@ namespace YooAsset
private void VerifyFile(PatchBundle patchBundle)
{
string filePath = SandboxHelper.MakeCacheFilePath(patchBundle.FileName);
bool result = CacheSystem.CheckContentIntegrity(filePath, patchBundle.FileSize, patchBundle.FileCRC);
if (result)
if (CacheSystem.VerifyAndCacheBundle(patchBundle, CacheSystem.InitVerifyLevel))
{
VerifySuccessCount++;
CacheSystem.CacheVerifyFile(patchBundle);
}
else
{
VerifyFailCount++;
YooLogger.Warning($"Failed to verify file : {patchBundle.CachedFilePath}");
// NOTE不期望删除断点续传的资源文件
/*
YooLogger.Warning($"Failed to verify file : {info.FilePath}");
if (File.Exists(info.FilePath))
File.Delete(info.FilePath);
if (File.Exists(patchBundle.CachedBundleFilePath))
File.Delete(patchBundle.CachedBundleFilePath);
*/
}
}

View File

@ -70,13 +70,13 @@ namespace YooAsset
public static DownloaderBase BeginDownload(BundleInfo bundleInfo, int failedTryAgain, int timeout = 60)
{
// 查询存在的下载器
if (_downloaderDic.TryGetValue(bundleInfo.FileHash, out var downloader))
if (_downloaderDic.TryGetValue(bundleInfo.Bundle.CachedFilePath, out var downloader))
{
return downloader;
}
// 如果资源已经缓存
if (CacheSystem.ContainsVerifyFile(bundleInfo.LoadBundle))
if (CacheSystem.IsCached(bundleInfo.Bundle))
{
var tempDownloader = new TempDownloader(bundleInfo);
return tempDownloader;
@ -84,15 +84,15 @@ namespace YooAsset
// 创建新的下载器
{
YooLogger.Log($"Beginning to download file : {bundleInfo.FileName} URL : {bundleInfo.RemoteMainURL}");
FileUtility.CreateFileDirectory(bundleInfo.GetCacheLoadPath());
YooLogger.Log($"Beginning to download file : {bundleInfo.Bundle.FileName} URL : {bundleInfo.RemoteMainURL}");
FileUtility.CreateFileDirectory(bundleInfo.Bundle.CachedFilePath);
DownloaderBase newDownloader;
if (bundleInfo.FileSize >= _breakpointResumeFileSize)
if (bundleInfo.Bundle.FileSize >= _breakpointResumeFileSize)
newDownloader = new HttpDownloader(bundleInfo);
else
newDownloader = new FileDownloader(bundleInfo);
newDownloader.SendRequest(failedTryAgain, timeout);
_downloaderDic.Add(bundleInfo.FileHash, newDownloader);
_downloaderDic.Add(bundleInfo.Bundle.CachedFilePath, newDownloader);
return newDownloader;
}
}

View File

@ -6,6 +6,7 @@ namespace YooAsset
protected enum ESteps
{
None,
CheckLocalFile,
CreateDownload,
CheckDownload,
TryAgain,
@ -54,7 +55,7 @@ namespace YooAsset
{
_failedTryAgain = failedTryAgain;
_timeout = timeout;
_steps = ESteps.CreateDownload;
_steps = ESteps.CheckLocalFile;
}
}
public abstract void Update();

View File

@ -29,6 +29,19 @@ namespace YooAsset
if (IsDone())
return;
// 检测本地文件
if (_steps == ESteps.CheckLocalFile)
{
if (CacheSystem.VerifyAndCacheBundle(_bundleInfo.Bundle, EVerifyLevel.High))
{
_steps = ESteps.Succeed;
}
else
{
_steps = ESteps.CreateDownload;
}
}
// 创建下载器
if (_steps == ESteps.CreateDownload)
{
@ -42,7 +55,7 @@ namespace YooAsset
_requestURL = GetRequestURL();
_webRequest = new UnityWebRequest(_requestURL, UnityWebRequest.kHttpVerbGET);
DownloadHandlerFile handler = new DownloadHandlerFile(_bundleInfo.GetCacheLoadPath());
DownloadHandlerFile handler = new DownloadHandlerFile(_bundleInfo.Bundle.CachedFilePath);
handler.removeFileOnAbort = true;
_webRequest.downloadHandler = handler;
_webRequest.disposeDownloadHandlerOnDispose = true;
@ -61,8 +74,9 @@ namespace YooAsset
return;
}
// 检查网络错误
bool hasError = false;
// 检查网络错误
#if UNITY_2020_3_OR_NEWER
if (_webRequest.result != UnityWebRequest.Result.Success)
{
@ -80,22 +94,18 @@ namespace YooAsset
// 检查文件完整性
if (hasError == false)
{
// 注意:如果文件验证失败需要删除文件
if (CacheSystem.CheckContentIntegrity(_bundleInfo.GetCacheLoadPath(), _bundleInfo.FileSize, _bundleInfo.FileCRC) == false)
if (CacheSystem.VerifyAndCacheBundle(_bundleInfo.Bundle, EVerifyLevel.High) == false)
{
hasError = true;
_lastError = $"Verification failed";
_lastError = $"Verify bundle content failed : {_bundleInfo.Bundle.FileName}";
}
}
if (hasError == false)
// 如果下载失败
if (hasError)
{
_steps = ESteps.Succeed;
CacheSystem.CacheVerifyFile(_bundleInfo.LoadBundle);
}
else
{
string cacheFilePath = _bundleInfo.GetCacheLoadPath();
// 下载失败后删除文件
string cacheFilePath = _bundleInfo.Bundle.CachedFilePath;
if (File.Exists(cacheFilePath))
File.Delete(cacheFilePath);
@ -111,6 +121,11 @@ namespace YooAsset
_steps = ESteps.Failed;
}
}
else
{
_lastError = string.Empty;
_steps = ESteps.Succeed;
}
// 释放下载器
DisposeWebRequest();

View File

@ -21,8 +21,6 @@ namespace YooAsset
private bool _running = true;
private string _url;
private string _savePath;
private string _fileName;
private string _fileCRC;
private long _fileSize;
private int _timeout;
@ -50,12 +48,10 @@ namespace YooAsset
/// <summary>
/// 开始下载
/// </summary>
public void Run(string url, string savePath, string fileName, string fileCRC, long fileSize, int timeout)
public void Run(string url, string savePath, long fileSize, int timeout)
{
_url = url;
_savePath = savePath;
_fileName = fileName;
_fileCRC = fileCRC;
_fileSize = fileSize;
_timeout = timeout;
@ -153,22 +149,6 @@ namespace YooAsset
fileStream.Close();
}
// 验证下载文件完整性
if (DownloadedBytes == (ulong)_fileSize)
{
bool verfiyResult = CacheSystem.CheckContentIntegrity(_savePath, _fileSize, _fileCRC);
if (verfiyResult == false)
{
Error = $"Verify download content failed : {_fileName}";
if (File.Exists(_savePath))
File.Delete(_savePath);
}
}
else
{
Error = $"Download content is incomplete : {_fileName}";
}
IsDone = true;
}
}
@ -188,6 +168,20 @@ namespace YooAsset
if (IsDone())
return;
// 检测本地文件
if (_steps == ESteps.CheckLocalFile)
{
if (CacheSystem.VerifyAndCacheBundle(_bundleInfo.Bundle, EVerifyLevel.High))
{
_steps = ESteps.Succeed;
}
else
{
_steps = ESteps.CreateDownload;
}
}
// 创建下载器
if (_steps == ESteps.CreateDownload)
{
// 重置变量
@ -197,10 +191,11 @@ namespace YooAsset
_requestURL = GetRequestURL();
_threadDownloader = new ThreadDownloader();
_threadDownloader.Run(_requestURL, _bundleInfo.GetCacheLoadPath(), _bundleInfo.FileName, _bundleInfo.FileCRC, _bundleInfo.FileSize, _timeout);
_threadDownloader.Run(_requestURL, _bundleInfo.Bundle.CachedFilePath, _bundleInfo.Bundle.FileSize, _timeout);
_steps = ESteps.CheckDownload;
}
// 检测下载结果
if (_steps == ESteps.CheckDownload)
{
_downloadProgress = _threadDownloader.DownloadProgress;
@ -208,10 +203,35 @@ namespace YooAsset
if (_threadDownloader.IsDone == false)
return;
bool hasError = false;
// 检查下载错误
if (_threadDownloader.HasError())
{
hasError = true;
_lastError = _threadDownloader.Error;
}
// 检查文件完整性
if (hasError == false)
{
if (CacheSystem.VerifyAndCacheBundle(_bundleInfo.Bundle, EVerifyLevel.High) == false)
{
hasError = true;
_lastError = $"Verify bundle content failed : {_bundleInfo.Bundle.FileName}";
}
else
{
// 验证失败后删除文件
string cacheFilePath = _bundleInfo.Bundle.CachedFilePath;
if (File.Exists(cacheFilePath))
File.Delete(cacheFilePath);
}
}
// 如果下载失败
if (hasError)
{
// 失败后重新尝试
if (_failedTryAgain > 0)
{
@ -226,7 +246,7 @@ namespace YooAsset
}
else
{
CacheSystem.CacheVerifyFile(_bundleInfo.LoadBundle);
_lastError = string.Empty;
_steps = ESteps.Succeed;
}
}

View File

@ -6,7 +6,7 @@ namespace YooAsset
public TempDownloader(BundleInfo bundleInfo) : base(bundleInfo)
{
_downloadProgress = 1f;
_downloadedBytes = (ulong)bundleInfo.FileSize;
_downloadedBytes = (ulong)bundleInfo.Bundle.FileSize;
_steps = ESteps.Succeed;
}

View File

@ -12,22 +12,9 @@ namespace YooAsset
LoadFromEditor,
}
public readonly PatchBundle LoadBundle;
public readonly PatchBundle Bundle;
public readonly ELoadMode LoadMode;
private string _streamingPath;
private string _cachePath;
/// <summary>
/// 资源包名称
/// </summary>
public string BundleName { private set; get; }
/// <summary>
/// 文件名称
/// </summary>
public string FileName { private set; get; }
/// <summary>
/// 远端下载地址
/// </summary>
@ -43,147 +30,35 @@ namespace YooAsset
/// </summary>
public string EditorAssetPath { private set; get; }
/// <summary>
/// 文件哈希值
/// </summary>
public string FileHash
{
get
{
if (LoadBundle == null)
return string.Empty;
else
return LoadBundle.FileHash;
}
}
/// <summary>
/// 校验的CRC
/// </summary>
public string FileCRC
{
get
{
if (LoadBundle == null)
return string.Empty;
else
return LoadBundle.FileCRC;
}
}
/// <summary>
/// 文件大小
/// </summary>
public long FileSize
{
get
{
if (LoadBundle == null)
return 0;
else
return LoadBundle.FileSize;
}
}
/// <summary>
/// 是否为加密文件
/// </summary>
public bool IsEncrypted
{
get
{
if (LoadBundle == null)
return false;
else
return LoadBundle.IsEncrypted;
}
}
/// <summary>
/// 是否为原生文件
/// </summary>
public bool IsRawFile
{
get
{
if (LoadBundle == null)
return false;
else
return LoadBundle.IsRawFile;
}
}
/// <summary>
/// 身份是否无效
/// </summary>
public bool IsInvalid
{
get
{
return LoadBundle == null;
}
}
private BundleInfo()
{
}
public BundleInfo(PatchBundle patchBundle, ELoadMode loadMode, string mainURL, string fallbackURL)
{
LoadBundle = patchBundle;
Bundle = patchBundle;
LoadMode = loadMode;
BundleName = patchBundle.BundleName;
FileName = patchBundle.FileName;
RemoteMainURL = mainURL;
RemoteFallbackURL = fallbackURL;
EditorAssetPath = string.Empty;
}
public BundleInfo(PatchBundle patchBundle, ELoadMode loadMode, string editorAssetPath)
{
LoadBundle = patchBundle;
Bundle = patchBundle;
LoadMode = loadMode;
BundleName = patchBundle.BundleName;
FileName = patchBundle.FileName;
RemoteMainURL = string.Empty;
RemoteFallbackURL = string.Empty;
EditorAssetPath = editorAssetPath;
}
public BundleInfo(PatchBundle patchBundle, ELoadMode loadMode)
{
LoadBundle = patchBundle;
Bundle = patchBundle;
LoadMode = loadMode;
BundleName = patchBundle.BundleName;
FileName = patchBundle.FileName;
RemoteMainURL = string.Empty;
RemoteFallbackURL = string.Empty;
EditorAssetPath = string.Empty;
}
/// <summary>
/// 获取流文件夹的加载路径
/// </summary>
public string GetStreamingLoadPath()
{
if (LoadBundle == null)
return string.Empty;
if (string.IsNullOrEmpty(_streamingPath))
_streamingPath = PathHelper.MakeStreamingLoadPath(LoadBundle.FileName);
return _streamingPath;
}
/// <summary>
/// 获取缓存文件夹的加载路径
/// </summary>
public string GetCacheLoadPath()
{
if (LoadBundle == null)
return string.Empty;
if (string.IsNullOrEmpty(_cachePath))
_cachePath = SandboxHelper.MakeCacheFilePath(LoadBundle.FileName);
return _cachePath;
}
/// <summary>
/// 是否为JAR包内文件

View File

@ -86,7 +86,7 @@ namespace YooAsset
TotalDownloadCount = downloadList.Count;
foreach (var patchBundle in downloadList)
{
TotalDownloadBytes += patchBundle.FileSize;
TotalDownloadBytes += patchBundle.Bundle.FileSize;
}
}
}
@ -138,7 +138,7 @@ namespace YooAsset
// 下载成功
_removeList.Add(downloader);
CurrentDownloadCount++;
CurrentDownloadBytes += bundleInfo.FileSize;
CurrentDownloadBytes += bundleInfo.Bundle.FileSize;
}
// 移除已经完成的下载器(无论成功或失败)
@ -170,7 +170,7 @@ namespace YooAsset
var operation = DownloadSystem.BeginDownload(bundleInfo, _failedTryAgain);
_downloaders.Add(operation);
_downloadList.RemoveAt(index);
OnStartDownloadFileCallback?.Invoke(bundleInfo.BundleName, bundleInfo.FileSize);
OnStartDownloadFileCallback?.Invoke(bundleInfo.Bundle.BundleName, bundleInfo.Bundle.FileSize);
}
}
@ -180,7 +180,7 @@ namespace YooAsset
if (_failedList.Count > 0)
{
var failedDownloader = _failedList[0];
string fileName = failedDownloader.GetBundleInfo().BundleName;
string fileName = failedDownloader.GetBundleInfo().Bundle.BundleName;
Error = $"Failed to download file : {fileName}";
_steps = ESteps.Done;
Status = EOperationStatus.Failed;

View File

@ -198,7 +198,7 @@ namespace YooAsset
foreach (var patchBundle in _remotePatchManifest.BundleList)
{
// 忽略缓存文件
if (CacheSystem.ContainsVerifyFile(patchBundle))
if (CacheSystem.IsCached(patchBundle))
continue;
// 忽略APP资源
@ -209,16 +209,6 @@ namespace YooAsset
continue;
}
// 注意:通过比对文件大小做快速的文件校验!
// 注意:在初始化的时候会去做最终校验!
string filePath = SandboxHelper.MakeCacheFilePath(patchBundle.FileName);
if (File.Exists(filePath))
{
long fileSize = FileUtility.GetFileSize(filePath);
if (fileSize == patchBundle.FileSize)
continue;
}
downloadList.Add(patchBundle);
}

View File

@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.IO;
namespace YooAsset
{
@ -11,11 +12,6 @@ namespace YooAsset
/// </summary>
public string BundleName;
/// <summary>
/// 内容哈希值
/// </summary>
public string ContentHash;
/// <summary>
/// 文件哈希值
/// </summary>
@ -62,11 +58,43 @@ namespace YooAsset
/// </summary>
public string FileName { private set; get; }
/// <summary>
/// 缓存文件路径
/// </summary>
private string _cachedFilePath;
public string CachedFilePath
{
get
{
if (string.IsNullOrEmpty(_cachedFilePath) == false)
return _cachedFilePath;
public PatchBundle(string bundleName, string contentHash, string fileHash, string fileCRC, long fileSize, string[] tags)
string cacheRoot = SandboxHelper.GetCacheFolderPath();
_cachedFilePath = $"{cacheRoot}/{FileName}";
return _cachedFilePath;
}
}
/// <summary>
/// 内置文件路径
/// </summary>
private string _streamingFilePath;
public string StreamingFilePath
{
get
{
if (string.IsNullOrEmpty(_streamingFilePath) == false)
return _streamingFilePath;
_streamingFilePath = PathHelper.MakeStreamingLoadPath(FileName);
return _streamingFilePath;
}
}
public PatchBundle(string bundleName, string fileHash, string fileCRC, long fileSize, string[] tags)
{
BundleName = bundleName;
ContentHash = contentHash;
FileHash = fileHash;
FileCRC = fileCRC;
FileSize = fileSize;

View File

@ -131,7 +131,7 @@ namespace YooAsset
foreach (var patchBundle in LocalPatchManifest.BundleList)
{
// 忽略缓存文件
if (CacheSystem.ContainsVerifyFile(patchBundle))
if (CacheSystem.IsCached(patchBundle))
continue;
// 忽略APP资源
@ -163,7 +163,7 @@ namespace YooAsset
foreach (var patchBundle in LocalPatchManifest.BundleList)
{
// 忽略缓存文件
if (CacheSystem.ContainsVerifyFile(patchBundle))
if (CacheSystem.IsCached(patchBundle))
continue;
// 忽略APP资源
@ -233,7 +233,7 @@ namespace YooAsset
foreach (var patchBundle in checkList)
{
// 忽略缓存文件
if (CacheSystem.ContainsVerifyFile(patchBundle))
if (CacheSystem.IsCached(patchBundle))
continue;
// 忽略APP资源
@ -269,7 +269,7 @@ namespace YooAsset
continue;
// 忽略缓存文件
if (CacheSystem.ContainsVerifyFile(patchBundle))
if (CacheSystem.IsCached(patchBundle))
continue;
// 查询DLC资源
@ -279,7 +279,7 @@ namespace YooAsset
}
}
return ConvertToUnpackList(downloadList);
return PatchHelper.ConvertToUnpackList(downloadList);
}
/// <summary>
@ -301,13 +301,13 @@ namespace YooAsset
continue;
// 忽略缓存文件
if (CacheSystem.ContainsVerifyFile(patchBundle))
if (CacheSystem.IsCached(patchBundle))
continue;
downloadList.Add(patchBundle);
}
return ConvertToUnpackList(downloadList);
return PatchHelper.ConvertToUnpackList(downloadList);
}
// WEB相关
@ -339,26 +339,6 @@ namespace YooAsset
return bundleInfo;
}
// 解压相关
public List<BundleInfo> ConvertToUnpackList(List<PatchBundle> unpackList)
{
List<BundleInfo> result = new List<BundleInfo>(unpackList.Count);
foreach (var patchBundle in unpackList)
{
var bundleInfo = ConvertToUnpackInfo(patchBundle);
result.Add(bundleInfo);
}
return result;
}
public BundleInfo ConvertToUnpackInfo(PatchBundle patchBundle)
{
// 注意:我们把流加载路径指定为远端下载地址
string streamingPath = PathHelper.MakeStreamingLoadPath(patchBundle.FileName);
streamingPath = PathHelper.ConvertToWWWPath(streamingPath);
BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromRemote, streamingPath, streamingPath);
return bundleInfo;
}
// 设置资源清单
internal void SetAppPatchManifest(PatchManifest patchManifest)
{
@ -377,7 +357,7 @@ namespace YooAsset
throw new Exception("Should never get here !");
// 查询沙盒资源
if (CacheSystem.ContainsVerifyFile(patchBundle))
if (CacheSystem.IsCached(patchBundle))
{
BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromCache);
return bundleInfo;

View File

@ -43,9 +43,19 @@ namespace YooAsset
if (patchBundle == null)
throw new Exception("Should never get here !");
// 查询沙盒资源
if (CacheSystem.IsCached(patchBundle))
{
BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromCache);
return bundleInfo;
}
// 查询APP资源
{
BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromStreaming);
return bundleInfo;
}
}
BundleInfo IBundleServices.GetBundleInfo(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)

View File

@ -5,7 +5,6 @@ namespace YooAsset
{
public string BundleName;
public string FileHash;
public string FileCRC;
}
public interface IDecryptionServices

View File

@ -109,14 +109,6 @@ namespace YooAsset
{
return PathHelper.MakePersistentLoadPath(CacheFolderName);
}
/// <summary>
/// 获取缓存文件的存储路径
/// </summary>
public static string MakeCacheFilePath(string fileName)
{
return PathHelper.MakePersistentLoadPath($"{CacheFolderName}/{fileName}");
}
}
/// <summary>
@ -140,5 +132,26 @@ namespace YooAsset
}
return result.ToArray();
}
/// <summary>
/// 资源解压相关
/// </summary>
public static List<BundleInfo> ConvertToUnpackList(List<PatchBundle> unpackList)
{
List<BundleInfo> result = new List<BundleInfo>(unpackList.Count);
foreach (var patchBundle in unpackList)
{
var bundleInfo = ConvertToUnpackInfo(patchBundle);
result.Add(bundleInfo);
}
return result;
}
public static BundleInfo ConvertToUnpackInfo(PatchBundle patchBundle)
{
// 注意:我们把流加载路径指定为远端下载地址
string streamingPath = PathHelper.ConvertToWWWPath(patchBundle.StreamingFilePath);
BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromStreaming, streamingPath, streamingPath);
return bundleInfo;
}
}
}

View File

@ -127,7 +127,7 @@ namespace YooAsset
}
/// <summary>
/// 创建文件
/// 创建文件(如果已经存在则删除旧文件)
/// </summary>
public static void CreateFile(string filePath, string content)
{

View File

@ -205,6 +205,11 @@ namespace YooAsset
CacheSystem.Initialize(hostPlayModeParameters.VerifyLevel);
DownloadSystem.Initialize(hostPlayModeParameters.BreakpointResumeFileSize);
}
else
{
CacheSystem.Initialize(EVerifyLevel.Low);
DownloadSystem.Initialize(int.MaxValue);
}
// 初始化资源系统
InitializationOperation initializeOperation;
@ -518,7 +523,7 @@ namespace YooAsset
}
BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
if (bundleInfo.IsRawFile == false)
if (bundleInfo.Bundle.IsRawFile == false)
{
string error = $"Cannot load asset bundle file using {nameof(GetRawFileAsync)} interfaces !";
YooLogger.Warning(error);