diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleFileLoader.cs b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleFileLoader.cs
index f79cf43..9e305c5 100644
--- a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleFileLoader.cs
+++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleFileLoader.cs
@@ -13,6 +13,8 @@ namespace YooAsset
None = 0,
Download,
CheckDownload,
+ Unpack,
+ CheckUnpack,
LoadFile,
CheckLoadFile,
Done,
@@ -22,8 +24,10 @@ namespace YooAsset
private string _fileLoadPath;
private bool _isWaitForAsyncComplete = false;
private bool _isShowWaitForAsyncError = false;
+ private DownloaderBase _unpacker;
private DownloaderBase _downloader;
private AssetBundleCreateRequest _createRequest;
+ private FileStream _fileStream;
public AssetBundleFileLoader(AssetSystemImpl impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
@@ -47,8 +51,22 @@ namespace YooAsset
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
+#if UNITY_ANDROID
+ EBundleLoadMethod loadMethod = (EBundleLoadMethod)MainBundleInfo.Bundle.LoadMethod;
+ if (loadMethod == EBundleLoadMethod.LoadFromMemory || loadMethod == EBundleLoadMethod.LoadFromStream)
+ {
+ _steps = ESteps.Unpack;
+ _fileLoadPath = MainBundleInfo.Bundle.CachedFilePath;
+ }
+ else
+ {
+ _steps = ESteps.LoadFile;
+ _fileLoadPath = MainBundleInfo.Bundle.StreamingFilePath;
+ }
+#else
_steps = ESteps.LoadFile;
_fileLoadPath = MainBundleInfo.Bundle.StreamingFilePath;
+#endif
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
@@ -87,7 +105,34 @@ namespace YooAsset
}
}
- // 3. 加载AssetBundle
+ // 3. 内置文件解压
+ if (_steps == ESteps.Unpack)
+ {
+ int failedTryAgain = 1;
+ var bundleInfo = HostPlayModeImpl.ConvertToUnpackInfo(MainBundleInfo.Bundle);
+ _unpacker = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain);
+ _steps = ESteps.CheckUnpack;
+ }
+
+ // 4.检测内置文件解压结果
+ if (_steps == ESteps.CheckUnpack)
+ {
+ if (_unpacker.IsDone() == false)
+ return;
+
+ if (_unpacker.HasError())
+ {
+ _steps = ESteps.Done;
+ Status = EStatus.Failed;
+ LastError = _unpacker.GetLastError();
+ }
+ else
+ {
+ _steps = ESteps.LoadFile;
+ }
+ }
+
+ // 5. 加载AssetBundle
if (_steps == ESteps.LoadFile)
{
#if UNITY_EDITOR
@@ -103,31 +148,63 @@ namespace YooAsset
#endif
// Load assetBundle file
- if (MainBundleInfo.Bundle.IsEncrypted)
- {
- if (Impl.DecryptionServices == null)
- throw new Exception($"{nameof(AssetBundleFileLoader)} need {nameof(IDecryptionServices)} : {MainBundleInfo.Bundle.BundleName}");
-
- DecryptionFileInfo fileInfo = new DecryptionFileInfo();
- fileInfo.BundleName = MainBundleInfo.Bundle.BundleName;
- fileInfo.FileHash = MainBundleInfo.Bundle.FileHash;
- ulong offset = Impl.DecryptionServices.GetFileOffset(fileInfo);
- if (_isWaitForAsyncComplete)
- CacheBundle = AssetBundle.LoadFromFile(_fileLoadPath, 0, offset);
- else
- _createRequest = AssetBundle.LoadFromFileAsync(_fileLoadPath, 0, offset);
- }
- else
+ var loadMethod = (EBundleLoadMethod)MainBundleInfo.Bundle.LoadMethod;
+ if (loadMethod == EBundleLoadMethod.Normal)
{
if (_isWaitForAsyncComplete)
CacheBundle = AssetBundle.LoadFromFile(_fileLoadPath);
else
_createRequest = AssetBundle.LoadFromFileAsync(_fileLoadPath);
}
+ else
+ {
+ if (Impl.DecryptionServices == null)
+ {
+ _steps = ESteps.Done;
+ Status = EStatus.Failed;
+ LastError = $"{nameof(IDecryptionServices)} is null : {MainBundleInfo.Bundle.BundleName}";
+ YooLogger.Error(LastError);
+ return;
+ }
+
+ DecryptFileInfo fileInfo = new DecryptFileInfo();
+ fileInfo.BundleName = MainBundleInfo.Bundle.BundleName;
+ fileInfo.FilePath = _fileLoadPath;
+
+ if (loadMethod == EBundleLoadMethod.LoadFromFileOffset)
+ {
+ ulong offset = Impl.DecryptionServices.LoadFromFileOffset(fileInfo);
+ if (_isWaitForAsyncComplete)
+ CacheBundle = AssetBundle.LoadFromFile(_fileLoadPath, 0, offset);
+ else
+ _createRequest = AssetBundle.LoadFromFileAsync(_fileLoadPath, 0, offset);
+ }
+ else if (loadMethod == EBundleLoadMethod.LoadFromMemory)
+ {
+ byte[] fileData = Impl.DecryptionServices.LoadFromMemory(fileInfo);
+ if (_isWaitForAsyncComplete)
+ CacheBundle = AssetBundle.LoadFromMemory(fileData);
+ else
+ _createRequest = AssetBundle.LoadFromMemoryAsync(fileData);
+ }
+ else if (loadMethod == EBundleLoadMethod.LoadFromStream)
+ {
+ _fileStream = Impl.DecryptionServices.LoadFromStream(fileInfo);
+ uint managedReadBufferSize = Impl.DecryptionServices.GetManagedReadBufferSize();
+ if (_isWaitForAsyncComplete)
+ CacheBundle = AssetBundle.LoadFromStream(_fileStream, 0, managedReadBufferSize);
+ else
+ _createRequest = AssetBundle.LoadFromStreamAsync(_fileStream, 0, managedReadBufferSize);
+ }
+ else
+ {
+ throw new System.NotImplementedException();
+ }
+ }
_steps = ESteps.CheckLoadFile;
}
- // 4. 检测AssetBundle加载结果
+ // 6. 检测AssetBundle加载结果
if (_steps == ESteps.CheckLoadFile)
{
if (_createRequest != null)
@@ -177,6 +254,21 @@ namespace YooAsset
}
}
+ ///
+ /// 销毁
+ ///
+ public override void Destroy(bool forceDestroy)
+ {
+ base.Destroy(forceDestroy);
+
+ if (_fileStream != null)
+ {
+ _fileStream.Close();
+ _fileStream.Dispose();
+ _fileStream = null;
+ }
+ }
+
///
/// 主线程等待异步操作完毕
///
diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleLoaderBase.cs b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleLoaderBase.cs
index 125f836..ff345ea 100644
--- a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleLoaderBase.cs
+++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleLoaderBase.cs
@@ -89,7 +89,7 @@ namespace YooAsset
///
/// 销毁
///
- public void Destroy(bool forceDestroy)
+ public virtual void Destroy(bool forceDestroy)
{
IsDestroyed = true;
diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs
index d9f7110..a626247 100644
--- a/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs
+++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/AssetBundleWebLoader.cs
@@ -17,7 +17,7 @@ namespace YooAsset
LoadCacheFile,
CheckLoadCacheFile,
LoadWebFile,
- CheckLoadWebFile,
+ CheckLoadWebFile,
TryLoadWebFile,
Done,
}
@@ -30,7 +30,7 @@ namespace YooAsset
private UnityWebRequest _webRequest;
private AssetBundleCreateRequest _createRequest;
-
+
public AssetBundleWebLoader(AssetSystemImpl impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
@@ -108,20 +108,18 @@ namespace YooAsset
#endif
// Load assetBundle file
- if (MainBundleInfo.Bundle.IsEncrypted)
+ var loadMethod = (EBundleLoadMethod)MainBundleInfo.Bundle.LoadMethod;
+ if (loadMethod == EBundleLoadMethod.Normal)
{
- if (Impl.DecryptionServices == null)
- throw new Exception($"{nameof(AssetBundleFileLoader)} need {nameof(IDecryptionServices)} : {MainBundleInfo.Bundle.BundleName}");
-
- DecryptionFileInfo fileInfo = new DecryptionFileInfo();
- fileInfo.BundleName = MainBundleInfo.Bundle.BundleName;
- fileInfo.FileHash = MainBundleInfo.Bundle.FileHash;
- ulong offset = Impl.DecryptionServices.GetFileOffset(fileInfo);
- _createRequest = AssetBundle.LoadFromFileAsync(_fileLoadPath, 0, offset);
+ _createRequest = AssetBundle.LoadFromFileAsync(_fileLoadPath);
}
else
{
- _createRequest = AssetBundle.LoadFromFileAsync(_fileLoadPath);
+ _steps = ESteps.Done;
+ Status = EStatus.Failed;
+ LastError = $"WebGL not support encrypted bundle file : {MainBundleInfo.Bundle.BundleName}";
+ YooLogger.Error(LastError);
+ return;
}
_steps = ESteps.CheckLoadCacheFile;
}
diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/EBundleLoadMethod.cs b/Assets/YooAsset/Runtime/AssetSystem/Loader/EBundleLoadMethod.cs
new file mode 100644
index 0000000..625fcce
--- /dev/null
+++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/EBundleLoadMethod.cs
@@ -0,0 +1,29 @@
+
+namespace YooAsset
+{
+ ///
+ /// Bundle文件的加载方法
+ ///
+ public enum EBundleLoadMethod
+ {
+ ///
+ /// 正常加载(不需要解密)
+ ///
+ Normal = 0,
+
+ ///
+ /// 通过文件偏移来解密加载
+ ///
+ LoadFromFileOffset = 1,
+
+ ///
+ /// 通过文件内存来解密加载
+ ///
+ LoadFromMemory = 2,
+
+ ///
+ /// 通过文件流来解密加载
+ ///
+ LoadFromStream = 3,
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/AssetSystem/Loader/EBundleLoadMethod.cs.meta b/Assets/YooAsset/Runtime/AssetSystem/Loader/EBundleLoadMethod.cs.meta
new file mode 100644
index 0000000..10eb8db
--- /dev/null
+++ b/Assets/YooAsset/Runtime/AssetSystem/Loader/EBundleLoadMethod.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5e32c14ed62806b4189d20ad48ce7631
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/AssetSystem/Operations/RawFileOperation.cs b/Assets/YooAsset/Runtime/AssetSystem/Operations/RawFileOperation.cs
index 736aac9..fb42394 100644
--- a/Assets/YooAsset/Runtime/AssetSystem/Operations/RawFileOperation.cs
+++ b/Assets/YooAsset/Runtime/AssetSystem/Operations/RawFileOperation.cs
@@ -171,14 +171,14 @@ namespace YooAsset
{
None,
Prepare,
- DownloadBuildinFile,
- CheckDownload,
+ Unpack,
+ CheckUnpack,
CheckAndCopyFile,
Done,
}
private ESteps _steps = ESteps.None;
- private DownloaderBase _downloader;
+ private DownloaderBase _unpacker;
public OfflinePlayModeRawFileOperation(BundleInfo bundleInfo, string copyPath) : base(bundleInfo, copyPath)
{
@@ -203,7 +203,7 @@ namespace YooAsset
}
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
- _steps = ESteps.DownloadBuildinFile;
+ _steps = ESteps.Unpack;
}
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
@@ -215,27 +215,27 @@ namespace YooAsset
}
}
- // 2. 下载文件
- if (_steps == ESteps.DownloadBuildinFile)
+ // 2. 内置文件解压
+ if (_steps == ESteps.Unpack)
{
- int failedTryAgain = int.MaxValue;
+ int failedTryAgain = 1;
var bundleInfo = HostPlayModeImpl.ConvertToUnpackInfo(_bundleInfo.Bundle);
- _downloader = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain);
- _steps = ESteps.CheckDownload;
+ _unpacker = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain);
+ _steps = ESteps.CheckUnpack;
}
- // 3. 检测下载结果
- if (_steps == ESteps.CheckDownload)
+ // 3. 检测内置文件解压结果
+ if (_steps == ESteps.CheckUnpack)
{
- Progress = _downloader.DownloadProgress;
- if (_downloader.IsDone() == false)
+ Progress = _unpacker.DownloadProgress;
+ if (_unpacker.IsDone() == false)
return;
- if (_downloader.HasError())
+ if (_unpacker.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
- Error = _downloader.GetLastError();
+ Error = _unpacker.GetLastError();
}
else
{
@@ -306,14 +306,16 @@ namespace YooAsset
{
None,
Prepare,
- DownloadWebFile,
- DownloadBuildinFile,
+ Download,
CheckDownload,
+ Unpack,
+ CheckUnpack,
CheckAndCopyFile,
Done,
}
private ESteps _steps = ESteps.None;
+ private DownloaderBase _unpacker;
private DownloaderBase _downloader;
internal HostPlayModeRawFileOperation(BundleInfo bundleInfo, string copyPath) : base(bundleInfo, copyPath)
@@ -339,11 +341,11 @@ namespace YooAsset
}
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
{
- _steps = ESteps.DownloadWebFile;
+ _steps = ESteps.Download;
}
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
- _steps = ESteps.DownloadBuildinFile;
+ _steps = ESteps.Unpack;
}
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
@@ -356,23 +358,14 @@ namespace YooAsset
}
// 2. 下载远端文件
- if (_steps == ESteps.DownloadWebFile)
+ if (_steps == ESteps.Download)
{
int failedTryAgain = int.MaxValue;
_downloader = DownloadSystem.BeginDownload(_bundleInfo, failedTryAgain);
_steps = ESteps.CheckDownload;
}
- // 3. 下载内置文件
- if (_steps == ESteps.DownloadBuildinFile)
- {
- int failedTryAgain = int.MaxValue;
- var bundleInfo = HostPlayModeImpl.ConvertToUnpackInfo(_bundleInfo.Bundle);
- _downloader = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain);
- _steps = ESteps.CheckDownload;
- }
-
- // 4. 检测下载结果
+ // 3. 检测下载结果
if (_steps == ESteps.CheckDownload)
{
Progress = _downloader.DownloadProgress;
@@ -391,6 +384,34 @@ namespace YooAsset
}
}
+ // 3. 解压内置文件
+ if (_steps == ESteps.Unpack)
+ {
+ int failedTryAgain = 1;
+ var bundleInfo = HostPlayModeImpl.ConvertToUnpackInfo(_bundleInfo.Bundle);
+ _unpacker = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain);
+ _steps = ESteps.CheckUnpack;
+ }
+
+ // 4. 检测解压结果
+ if (_steps == ESteps.CheckUnpack)
+ {
+ Progress = _unpacker.DownloadProgress;
+ if (_unpacker.IsDone() == false)
+ return;
+
+ if (_unpacker.HasError())
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ Error = _unpacker.GetLastError();
+ }
+ else
+ {
+ _steps = ESteps.CheckAndCopyFile;
+ }
+ }
+
// 5. 检测并拷贝原生文件
if (_steps == ESteps.CheckAndCopyFile)
{
diff --git a/Assets/YooAsset/Runtime/PatchSystem/PatchBundle.cs b/Assets/YooAsset/Runtime/PatchSystem/PatchBundle.cs
index d2b5721..7db22c7 100644
--- a/Assets/YooAsset/Runtime/PatchSystem/PatchBundle.cs
+++ b/Assets/YooAsset/Runtime/PatchSystem/PatchBundle.cs
@@ -1,6 +1,5 @@
using System;
using System.Linq;
-using System.IO;
namespace YooAsset
{
@@ -27,27 +26,21 @@ namespace YooAsset
///
public long FileSize;
+ ///
+ /// 是否为原生文件
+ ///
+ public bool IsRawFile;
+
+ ///
+ /// 加载方法
+ ///
+ public byte LoadMethod;
+
///
/// 资源包的分类标签
///
public string[] Tags;
- ///
- /// Flags
- ///
- public int Flags;
-
-
- ///
- /// 是否为原生文件
- ///
- public bool IsRawFile { private set; get; }
-
- ///
- /// 是否为加密文件
- ///
- public bool IsEncrypted { private set; get; }
-
///
/// 文件名称
///
@@ -87,37 +80,15 @@ namespace YooAsset
}
- public PatchBundle(string bundleName, string fileHash, string fileCRC, long fileSize, string[] tags)
+ public PatchBundle(string bundleName, string fileHash, string fileCRC, long fileSize, bool isRawFile, byte loadMethod, string[] tags)
{
BundleName = bundleName;
FileHash = fileHash;
FileCRC = fileCRC;
FileSize = fileSize;
- Tags = tags;
- }
-
- ///
- /// 设置Flags
- ///
- public void SetFlagsValue(bool isRawFile, bool isEncrypted)
- {
IsRawFile = isRawFile;
- IsEncrypted = isEncrypted;
-
- BitMask32 mask = new BitMask32(0);
- if (isRawFile) mask.Open(0);
- if (isEncrypted) mask.Open(1);
- Flags = mask;
- }
-
- ///
- /// 解析Flags
- ///
- public void ParseFlagsValue()
- {
- BitMask32 value = Flags;
- IsRawFile = value.Test(0);
- IsEncrypted = value.Test(1);
+ LoadMethod = loadMethod;
+ Tags = tags;
}
///
diff --git a/Assets/YooAsset/Runtime/PatchSystem/PatchManifest.cs b/Assets/YooAsset/Runtime/PatchSystem/PatchManifest.cs
index c1840f8..5b32a8d 100644
--- a/Assets/YooAsset/Runtime/PatchSystem/PatchManifest.cs
+++ b/Assets/YooAsset/Runtime/PatchSystem/PatchManifest.cs
@@ -290,7 +290,6 @@ namespace YooAsset
// BundleList
foreach (var patchBundle in patchManifest.BundleList)
{
- patchBundle.ParseFlagsValue();
patchBundle.ParseFileName(patchManifest.OutputNameStyle);
patchManifest.BundleDic.Add(patchBundle.BundleName, patchBundle);
}
diff --git a/Assets/YooAsset/Runtime/Services/IDecryptionServices.cs b/Assets/YooAsset/Runtime/Services/IDecryptionServices.cs
index bd73343..11ea5b0 100644
--- a/Assets/YooAsset/Runtime/Services/IDecryptionServices.cs
+++ b/Assets/YooAsset/Runtime/Services/IDecryptionServices.cs
@@ -1,17 +1,42 @@
namespace YooAsset
{
- public struct DecryptionFileInfo
+ public struct DecryptFileInfo
{
+ ///
+ /// 资源包名称
+ ///
public string BundleName;
- public string FileHash;
+
+ ///
+ /// 文件路径
+ ///
+ public string FilePath;
}
+ ///
+ /// 解密类服务接口
+ ///
public interface IDecryptionServices
{
///
- /// 获取加密文件的数据偏移量
+ /// 文件偏移解密方法
///
- ulong GetFileOffset(DecryptionFileInfo fileInfo);
+ ulong LoadFromFileOffset(DecryptFileInfo fileInfo);
+
+ ///
+ /// 文件内存解密方法
+ ///
+ byte[] LoadFromMemory(DecryptFileInfo fileInfo);
+
+ ///
+ /// 文件流解密方法
+ ///
+ System.IO.FileStream LoadFromStream(DecryptFileInfo fileInfo);
+
+ ///
+ /// 文件流解密的托管缓存大小
+ ///
+ uint GetManagedReadBufferSize();
}
}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/Services/IEncryptionServices.cs b/Assets/YooAsset/Runtime/Services/IEncryptionServices.cs
new file mode 100644
index 0000000..0664bfc
--- /dev/null
+++ b/Assets/YooAsset/Runtime/Services/IEncryptionServices.cs
@@ -0,0 +1,37 @@
+
+namespace YooAsset
+{
+ public struct EncryptResult
+ {
+ ///
+ /// 加密后的Bunlde文件加载方法
+ ///
+ public EBundleLoadMethod LoadMethod;
+
+ ///
+ /// 加密后的文件数据
+ ///
+ public byte[] EncryptedData;
+ }
+
+ public struct EncryptFileInfo
+ {
+ ///
+ /// 资源包名称
+ ///
+ public string BundleName;
+
+ ///
+ /// 文件路径
+ ///
+ public string FilePath;
+ }
+
+ ///
+ /// 加密服务类接口
+ ///
+ public interface IEncryptionServices
+ {
+ EncryptResult Encrypt(EncryptFileInfo fileInfo);
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/Services/IEncryptionServices.cs.meta b/Assets/YooAsset/Runtime/Services/IEncryptionServices.cs.meta
new file mode 100644
index 0000000..3991708
--- /dev/null
+++ b/Assets/YooAsset/Runtime/Services/IEncryptionServices.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 04491137351983348959c00ec4ee226a
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/Settings/YooAssetSettings.cs b/Assets/YooAsset/Runtime/Settings/YooAssetSettings.cs
index 903709b..c0f5d0c 100644
--- a/Assets/YooAsset/Runtime/Settings/YooAssetSettings.cs
+++ b/Assets/YooAsset/Runtime/Settings/YooAssetSettings.cs
@@ -24,7 +24,7 @@ namespace YooAsset
///
/// 补丁清单文件格式版本
///
- public const string PatchManifestFileVersion = "1.3.3";
+ public const string PatchManifestFileVersion = "1.3.4";
///
/// 构建输出文件夹名称