feat : support encrypted ArchiveBundle

This commit is contained in:
何冠峰
2026-05-28 12:02:59 +08:00
parent d5a9b9f0f4
commit 289dee326b
118 changed files with 1139 additions and 311 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: abd6a8bd2f0d3844b83930abb6014d83
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,122 @@
using System;
using System.IO;
using YooAsset;
/// <summary>
/// Bundle 加密和解密示例
/// 注意:示例代码仅演示接口用法,实际项目请替换密钥和加密算法。
/// </summary>
public static class BundleEncryptionSample
{
private const byte XOR_KEY = 64;
private const int FILE_OFFSET = 32;
/// <summary>
/// 内存模式加密器:将加密后的完整文件数据返回给构建管线。
/// </summary>
public class MemoryEncryptor : IBundleEncryptor
{
public BundleEncryptResult Encrypt(BundleEncryptArgs args)
{
byte[] data = File.ReadAllBytes(args.FilePath);
Xor(data);
return new BundleEncryptResult(true, data);
}
}
/// <summary>
/// 内存模式解密器:运行时返回解密后的完整文件数据。
/// </summary>
public class MemoryDecryptor : IBundleMemoryDecryptor
{
byte[] IBundleMemoryDecryptor.GetDecryptedData(BundleDecryptArgs args)
{
byte[] data = args.FileData;
if (data == null)
data = FileUtility.ReadAllBytes(args.FilePath);
Xor(data);
return data;
}
}
/// <summary>
/// 偏移模式加密器:在文件头部插入固定长度的数据。
/// </summary>
public class OffsetEncryptor : IBundleEncryptor
{
public BundleEncryptResult Encrypt(BundleEncryptArgs args)
{
byte[] data = File.ReadAllBytes(args.FilePath);
byte[] encryptedData = new byte[data.Length + FILE_OFFSET];
Buffer.BlockCopy(data, 0, encryptedData, FILE_OFFSET, data.Length);
return new BundleEncryptResult(true, encryptedData);
}
}
/// <summary>
/// 偏移模式解密器:运行时返回真实 Bundle 数据起始偏移。
/// </summary>
public class OffsetDecryptor : IBundleOffsetDecryptor
{
long IBundleOffsetDecryptor.GetFileOffset(BundleDecryptArgs args)
{
return FILE_OFFSET;
}
}
/// <summary>
/// 流模式加密器:示例中使用 XOR 加密整个文件。
/// </summary>
public class StreamEncryptor : IBundleEncryptor
{
public BundleEncryptResult Encrypt(BundleEncryptArgs args)
{
byte[] data = File.ReadAllBytes(args.FilePath);
Xor(data);
return new BundleEncryptResult(true, data);
}
}
/// <summary>
/// 流模式解密器:运行时返回一个读取时自动解密的文件流。
/// </summary>
public class StreamDecryptor : IBundleStreamDecryptor
{
Stream IBundleStreamDecryptor.CreateDecryptionStream(BundleDecryptArgs args)
{
return new XorFileStream(args.FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
}
int IBundleStreamDecryptor.GetBufferSize(BundleDecryptArgs args)
{
return 1024;
}
}
private class XorFileStream : FileStream
{
public XorFileStream(string path, FileMode mode, FileAccess access, FileShare share)
: base(path, mode, access, share)
{
}
public override int Read(byte[] array, int offset, int count)
{
int read = base.Read(array, offset, count);
for (int i = offset; i < offset + read; i++)
{
array[i] ^= XOR_KEY;
}
return read;
}
}
private static void Xor(byte[] data)
{
for (int i = 0; i < data.Length; i++)
{
data[i] ^= XOR_KEY;
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 9d03e8f2341d4c74886f1e7aef83d0c6
guid: 9d21463d1d8d4a72a4f7e929b2f7a325
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -71,7 +71,7 @@ public static class TestPackageBuilder
buildParameters.ClearBuildCacheFiles = true;
buildParameters.UseAssetDependencyDB = true;
buildParameters.BuiltinShadersBundleName = builtinShaderBundleName;
buildParameters.BundleEncryptor = new TestFileStreamEncryption();
buildParameters.BundleEncryptor = new TestAssetBundleEncryptor();
buildParameters.ManifestEncryptor = new TestManifestEncryptor();
buildParameters.ManifestDecryptor = new TestManifestDecryptor();
@@ -115,7 +115,7 @@ public static class TestPackageBuilder
buildParameters.CompressOption = ECompressOption.LZ4;
buildParameters.ClearBuildCacheFiles = true;
buildParameters.UseAssetDependencyDB = true;
buildParameters.BundleEncryptor = new TestFileStreamEncryption();
buildParameters.BundleEncryptor = new TestAssetBundleEncryptor();
buildParameters.ManifestEncryptor = new TestManifestEncryptor();
buildParameters.ManifestDecryptor = new TestManifestDecryptor();
@@ -157,6 +157,7 @@ public static class TestPackageBuilder
buildParameters.BundledCopyParams = string.Empty;
buildParameters.ClearBuildCacheFiles = true;
buildParameters.UseAssetDependencyDB = true;
buildParameters.BundleEncryptor = new TestRawBundleEncryptor();
var pipeline = new RawFileBuildPipeline();
BuildResult buildResult = pipeline.Run(buildParameters, false);
@@ -197,6 +198,7 @@ public static class TestPackageBuilder
buildParameters.ClearBuildCacheFiles = true;
buildParameters.UseAssetDependencyDB = true;
buildParameters.FileAlignment = 4;
buildParameters.BundleEncryptor = new TestArchiveBundleEncryptor();
var pipeline = new ArchiveFileBuildPipeline();
BuildResult buildResult = pipeline.Run(buildParameters, false);

View File

@@ -14,6 +14,7 @@ using YooAsset;
/// 2. 同步加载归档子文件,验证 GetBytes() 和 GetText() 均返回有效数据archive_file_b
/// 3. 重复加载同一归档子文件验证缓存命中不会失败archive_file_c
/// 4. 释放句柄并卸载后重新加载验证卸载保护和重载链路正常archive_file_e
/// 5. 加载加密归档子文件,验证 Memory 解密路径archive_file_x / archive_file_y
/// </remarks>
public class TestLoadArchiveBundle
{
@@ -103,5 +104,44 @@ public class TestLoadArchiveBundle
Assert.AreNotSame(previousObj, reloadedObj);
reloadHandle.Release();
}
// 异步加载加密归档子文件,验证 Memory 解密路径
{
var assetHandle = package.LoadAssetAsync<RawFileObject>("archive_file_x");
yield return assetHandle;
Assert.AreEqual(EOperationStatus.Succeeded, assetHandle.Status);
var rawFileObject = assetHandle.GetAssetObject<RawFileObject>();
Assert.IsNotNull(rawFileObject);
byte[] fileBytes = rawFileObject.GetBytes();
Assert.IsNotNull(fileBytes);
Assert.Greater(fileBytes.Length, 0);
string fileText = rawFileObject.GetText();
Assert.IsNotNull(fileText);
Assert.IsNotEmpty(fileText);
Assert.AreEqual("this is archive file x !", fileText);
assetHandle.Release();
}
// 同步加载加密归档子文件,验证 Memory 解密路径
{
var assetHandle = package.LoadAssetSync<RawFileObject>("archive_file_y");
Assert.AreEqual(EOperationStatus.Succeeded, assetHandle.Status);
var rawFileObject = assetHandle.GetAssetObject<RawFileObject>();
Assert.IsNotNull(rawFileObject);
byte[] fileBytes = rawFileObject.GetBytes();
Assert.IsNotNull(fileBytes);
Assert.Greater(fileBytes.Length, 0);
string fileText = rawFileObject.GetText();
Assert.IsNotNull(fileText);
Assert.IsNotEmpty(fileText);
Assert.AreEqual("this is archive file y !", fileText);
assetHandle.Release();
}
}
}

View File

@@ -4,15 +4,17 @@ using NUnit.Framework;
using YooAsset;
/// <summary>
/// 测试 RawFileObject 加载
/// 测试 RawBundle 加载
/// </summary>
/// <remarks>
/// 覆盖 API: LoadAssetAsync(RawFileObject) / LoadAssetSync(RawFileObject)
/// 测试内容:
/// 1. 异步通过 RawFileObject 加载,验证 GetBytes() 和 GetText() 均返回有效数据raw_file_c
/// 2. 同步通过 RawFileObject 加载,验证 GetBytes() 和 GetText() 均返回有效数据raw_file_d
/// 3. 异步加载加密 RawBundle验证 Memory 解密路径raw_file_x
/// 4. 同步加载加密 RawBundle验证 Memory 解密路径raw_file_y
/// </remarks>
public class TestLoadRawFileObject
public class TestLoadRawBundle
{
public IEnumerator RuntimeTester()
{
@@ -55,5 +57,44 @@ public class TestLoadRawFileObject
Assert.IsNotEmpty(fileText);
assetHandle.Release();
}
// 测试异步加载加密 RawBundle通过 RawFileObject 获取二进制数据和文本数据
{
var assetHandle = package.LoadAssetAsync<RawFileObject>("raw_file_x");
yield return assetHandle;
Assert.AreEqual(EOperationStatus.Succeeded, assetHandle.Status);
var rawFileObject = assetHandle.GetAssetObject<RawFileObject>();
Assert.IsNotNull(rawFileObject);
byte[] fileBytes = rawFileObject.GetBytes();
Assert.IsNotNull(fileBytes);
Assert.Greater(fileBytes.Length, 0);
string fileText = rawFileObject.GetText();
Assert.IsNotNull(fileText);
Assert.IsNotEmpty(fileText);
Assert.AreEqual("this is raw file x !", fileText);
assetHandle.Release();
}
// 测试同步加载加密 RawBundle通过 RawFileObject 获取二进制数据和文本数据
{
var assetHandle = package.LoadAssetSync<RawFileObject>("raw_file_y");
Assert.AreEqual(EOperationStatus.Succeeded, assetHandle.Status);
var rawFileObject = assetHandle.GetAssetObject<RawFileObject>();
Assert.IsNotNull(rawFileObject);
byte[] fileBytes = rawFileObject.GetBytes();
Assert.IsNotNull(fileBytes);
Assert.Greater(fileBytes.Length, 0);
string fileText = rawFileObject.GetText();
Assert.IsNotNull(fileText);
Assert.IsNotEmpty(fileText);
Assert.AreEqual("this is raw file y !", fileText);
assetHandle.Release();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c281ef07d441fc9458a3fa7be72b24c5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -14,7 +14,7 @@ using YooAsset;
/// 覆盖 API: LoadAssetAsync (SpriteAtlas)
/// 测试内容:
/// 1. 异步加载 SpriteAtlas 资源,验证加载状态和资源对象非空
/// 2. 从图集中获取三个精灵(bullet、pause、rocket),验证均非空
/// 2. 从图集中获取三个精灵(sprite_a、sprite_b、sprite_c),验证均非空
/// </remarks>
public class TestLoadSpriteAtlas
{
@@ -30,13 +30,13 @@ public class TestLoadSpriteAtlas
var spriteAtlas = assetHandle.AssetObject as SpriteAtlas;
Assert.IsNotNull(spriteAtlas);
var sprite1 = spriteAtlas.GetSprite("bullet");
var sprite1 = spriteAtlas.GetSprite("sprite_a");
Assert.IsNotNull(sprite1);
var sprite2 = spriteAtlas.GetSprite("pause");
var sprite2 = spriteAtlas.GetSprite("sprite_b");
Assert.IsNotNull(sprite2);
var sprite3 = spriteAtlas.GetSprite("rocket");
var sprite3 = spriteAtlas.GetSprite("sprite_c");
Assert.IsNotNull(sprite3);
assetHandle.Release();
}

View File

@@ -0,0 +1,20 @@
using YooAsset;
/// <summary>
/// ArchiveBundle 解密器
/// </summary>
public class TestArchiveBundleDecryptor : IBundleMemoryDecryptor
{
byte[] IBundleMemoryDecryptor.GetDecryptedData(BundleDecryptArgs args)
{
byte[] data = args.FileData;
if (data == null)
data = FileUtility.ReadAllBytes(args.FilePath);
for (int i = 0; i < data.Length; i++)
{
data[i] ^= TestArchiveBundleEncryptor.KEY;
}
return data;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2ae99256961d47c09ef5a633f5d48c68
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,24 @@
using System.IO;
using YooAsset;
/// <summary>
/// ArchiveBundle 加密器
/// </summary>
public class TestArchiveBundleEncryptor : IBundleEncryptor
{
public const byte KEY = 0x5A;
public BundleEncryptResult Encrypt(BundleEncryptArgs fileInfo)
{
string bundleName = fileInfo.BundleName.ToLowerInvariant();
if (bundleName.Contains("_testres6_encryptfiles_") == false)
return new BundleEncryptResult(false, null);
byte[] fileData = File.ReadAllBytes(fileInfo.FilePath);
for (int i = 0; i < fileData.Length; i++)
{
fileData[i] ^= KEY;
}
return new BundleEncryptResult(true, fileData);
}
}

View File

@@ -0,0 +1,20 @@
using YooAsset;
/// <summary>
/// AssetBundle 解密器
/// </summary>
public class TestAssetBundleDecryptor : IBundleMemoryDecryptor
{
byte[] IBundleMemoryDecryptor.GetDecryptedData(BundleDecryptArgs args)
{
byte[] data = args.FileData;
if (data == null)
data = FileUtility.ReadAllBytes(args.FilePath);
for (int i = 0; i < data.Length; i++)
{
data[i] ^= TestAssetBundleEncryptor.KEY;
}
return data;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 502b8de579fc3e04ab0c61064b344b50
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,26 @@
using System.IO;
using YooAsset;
/// <summary>
/// AssetBundle 加密器
/// </summary>
public class TestAssetBundleEncryptor : IBundleEncryptor
{
public const byte KEY = 0x5A;
public BundleEncryptResult Encrypt(BundleEncryptArgs fileInfo)
{
string bundleName = fileInfo.BundleName.ToLowerInvariant();
if (bundleName.Contains("_testres_encryptfiles_") == false &&
bundleName.Contains("_testres3_importfiles_") == false &&
bundleName.Contains("_testres3_unpackfiles_") == false)
return new BundleEncryptResult(false, null);
byte[] fileData = File.ReadAllBytes(fileInfo.FilePath);
for (int i = 0; i < fileData.Length; i++)
{
fileData[i] ^= KEY;
}
return new BundleEncryptResult(true, fileData);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 09c441a23eaa4be486ad910c9dcfa401
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,123 +0,0 @@
using System;
using System.IO;
using YooAsset;
/// <summary>
/// XOR 解密文件流,读取时自动对每个字节执行异或解密
/// </summary>
public class TestBundleStream : FileStream
{
public const byte KEY = 64;
public TestBundleStream(string path, FileMode mode, FileAccess access, FileShare share) : base(path, mode, access, share)
{
}
public TestBundleStream(string path, FileMode mode) : base(path, mode)
{
}
public override int Read(byte[] array, int offset, int count)
{
var index = base.Read(array, offset, count);
for (int i = 0; i < array.Length; i++)
{
array[i] ^= KEY;
}
return index;
}
}
/// <summary>
/// 流模式 XOR 加密器,对 TestRes3 目录的 Bundle 进行逐字节异或加密
/// </summary>
public class TestFileStreamEncryption : IBundleEncryptor
{
public BundleEncryptResult Encrypt(BundleEncryptArgs fileInfo)
{
// 说明对TestRes3资源目录进行加密
if (fileInfo.BundleName.Contains("_testres3_"))
{
var fileData = File.ReadAllBytes(fileInfo.FilePath);
for (int i = 0; i < fileData.Length; i++)
{
fileData[i] ^= TestBundleStream.KEY;
}
return new BundleEncryptResult(true, fileData);
}
else
{
return new BundleEncryptResult(false, null);
}
}
}
/// <summary>
/// 偏移模式加密器,在 Bundle 文件头部插入固定长度的空白偏移
/// </summary>
public class TestFileOffsetEncryption : IBundleEncryptor
{
public BundleEncryptResult Encrypt(BundleEncryptArgs fileInfo)
{
// 说明对TestRes3资源目录进行加密
if (fileInfo.BundleName.Contains("_testres3_"))
{
int offset = 32;
byte[] fileData = File.ReadAllBytes(fileInfo.FilePath);
var encryptedData = new byte[fileData.Length + offset];
Buffer.BlockCopy(fileData, 0, encryptedData, offset, fileData.Length);
return new BundleEncryptResult(true, encryptedData);
}
else
{
return new BundleEncryptResult(false, null);
}
}
}
/// <summary>
/// 偏移模式解密器,返回固定的文件偏移量以跳过加密头
/// </summary>
public class TestFileOffsetDecryption : IBundleOffsetDecryptor
{
private const long FILE_OFFSET = 32;
long IBundleOffsetDecryptor.GetFileOffset(BundleDecryptArgs args)
{
return FILE_OFFSET;
}
}
/// <summary>
/// 内存模式 XOR 解密器,将整个 Bundle 读入内存后逐字节异或解密
/// </summary>
public class TestFileMemoryDecryption : IBundleMemoryDecryptor
{
byte[] IBundleMemoryDecryptor.GetDecryptedData(BundleDecryptArgs args)
{
byte[] data = args.FileData;
// 注意:如果数据为空,自行加载文件数据。
if (data == null)
data = FileUtility.ReadAllBytes(args.FilePath);
for (int i = 0; i < data.Length; i++)
{
data[i] ^= TestBundleStream.KEY;
}
return data;
}
}
/// <summary>
/// 流模式解密器,返回 TestBundleStream 实现读取时自动解密
/// </summary>
public class TestFileStreamDecryption : IBundleStreamDecryptor
{
Stream IBundleStreamDecryptor.CreateDecryptionStream(BundleDecryptArgs args)
{
var fileStream = new TestBundleStream(args.FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
return fileStream;
}
int IBundleStreamDecryptor.GetBufferSize(BundleDecryptArgs args)
{
return 1024;
}
}

View File

@@ -0,0 +1,12 @@
using YooAsset;
/// <summary>
/// 资源清单解密器
/// </summary>
public class TestManifestDecryptor : IManifestDecryptor
{
byte[] IManifestDecryptor.Decrypt(byte[] fileData)
{
return TestXorCrypto.Crypto(fileData, TestManifestEncryptor.KEY);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6c2d2ff26d5d4d4d9ac08ba6a420d3f1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,27 +1,17 @@
using System;
using System.Text;
using System.Collections;
using YooAsset;
/// <summary>
/// 测试用清单加密器,使用 XOR 方式加密清单数据
/// 资源清单加密器
/// </summary>
public class TestManifestEncryptor : IManifestEncryptor
{
public const string KEY = "YOO";
byte[] IManifestEncryptor.Encrypt(byte[] fileData)
{
return TestXorCrypto.Crypto(fileData, "YOO");
}
}
/// <summary>
/// 测试用清单解密器,使用 XOR 方式解密清单数据
/// </summary>
public class TestManifestDecryptor : IManifestDecryptor
{
byte[] IManifestDecryptor.Decrypt(byte[] fileData)
{
return TestXorCrypto.Crypto(fileData, "YOO");
return TestXorCrypto.Crypto(fileData, KEY);
}
}
@@ -62,7 +52,7 @@ public class TestXorCrypto
/// <returns>处理后的字节数组</returns>
public static byte[] Crypto(byte[] data, string key)
{
byte[] keyBytes = System.Text.Encoding.UTF8.GetBytes(key);
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
return Crypto(data, keyBytes);
}
}
}

View File

@@ -0,0 +1,20 @@
using YooAsset;
/// <summary>
/// RawBundle 解密器
/// </summary>
public class TestRawBundleDecryptor : IBundleMemoryDecryptor
{
byte[] IBundleMemoryDecryptor.GetDecryptedData(BundleDecryptArgs args)
{
byte[] data = args.FileData;
if (data == null)
data = FileUtility.ReadAllBytes(args.FilePath);
for (int i = 0; i < data.Length; i++)
{
data[i] ^= TestRawBundleEncryptor.KEY;
}
return data;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7bf91e81ab6e85b4eb4f478fcd1e7261
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,24 @@
using System.IO;
using YooAsset;
/// <summary>
/// RawBundle 加密器
/// </summary>
public class TestRawBundleEncryptor : IBundleEncryptor
{
public const byte KEY = 0x6B;
public BundleEncryptResult Encrypt(BundleEncryptArgs fileInfo)
{
string bundleName = fileInfo.BundleName.ToLowerInvariant();
if (bundleName.Contains("_testres5_encryptfiles_") == false)
return new BundleEncryptResult(false, null);
byte[] fileData = File.ReadAllBytes(fileInfo.FilePath);
for (int i = 0; i < fileData.Length; i++)
{
fileData[i] ^= KEY;
}
return new BundleEncryptResult(true, fileData);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d84195bebf934e44b8d73d46ba0ce838
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -170,26 +170,30 @@ public class T0_InitYooAssets : IPrebuildSetup, IPostBuildCleanup
{
var collector1 = new YooAsset.Editor.BundleCollector();
collector1.CollectPath = "";
collector1.CollectorGUID = "e082d492b9da65e499cee3495be3645d"; //TestRes3/encrypt目录
collector1.CollectorGUID = "e082d492b9da65e499cee3495be3645d"; //TestRes/EncryptFiles目录
collector1.CollectorType = YooAsset.Editor.ECollectorType.MainAssetCollector;
collector1.PackRuleName = nameof(YooAsset.Editor.PackSeparately);
YooAsset.Editor.BundleCollectorSettingData.CreateCollector(encryptGroup, collector1);
}
// 拷贝测试文件
var copyGroup = YooAsset.Editor.BundleCollectorSettingData.CreateGroup(testPackage, "CopyGroup");
{
var collector1 = new YooAsset.Editor.BundleCollector();
collector1.CollectPath = "";
collector1.CollectorGUID = "35f454fb80a715047bcf0ce30c7c4f18"; //TestRes3/ImportFiles目录
collector1.CollectorType = YooAsset.Editor.ECollectorType.MainAssetCollector;
collector1.AssetTags = "import";
collector1.PackRuleName = nameof(YooAsset.Editor.PackSeparately);
YooAsset.Editor.BundleCollectorSettingData.CreateCollector(copyGroup, collector1);
var collector2 = new YooAsset.Editor.BundleCollector();
collector2.CollectPath = "";
collector2.CollectorGUID = "35f454fb80a715047bcf0ce30c7c4f18"; //TestRes3/import目录
collector2.CollectorGUID = "401af1ca0abf3ae4594631e5f71bfe27"; //TestRes3/UnpackFiles目录
collector2.CollectorType = YooAsset.Editor.ECollectorType.MainAssetCollector;
collector2.AssetTags = "import";
collector2.AssetTags = "unpack";
collector2.PackRuleName = nameof(YooAsset.Editor.PackSeparately);
YooAsset.Editor.BundleCollectorSettingData.CreateCollector(encryptGroup, collector2);
var collector3 = new YooAsset.Editor.BundleCollector();
collector3.CollectPath = "";
collector3.CollectorGUID = "401af1ca0abf3ae4594631e5f71bfe27"; //TestRes3/unpack目录
collector3.CollectorType = YooAsset.Editor.ECollectorType.MainAssetCollector;
collector3.AssetTags = "unpack";
collector3.PackRuleName = nameof(YooAsset.Editor.PackSeparately);
YooAsset.Editor.BundleCollectorSettingData.CreateCollector(encryptGroup, collector3);
YooAsset.Editor.BundleCollectorSettingData.CreateCollector(copyGroup, collector2);
}
// 卸载测试文件
@@ -230,10 +234,17 @@ public class T0_InitYooAssets : IPrebuildSetup, IPostBuildCleanup
{
var collector1 = new YooAsset.Editor.BundleCollector();
collector1.CollectPath = "";
collector1.CollectorGUID = "fddaaf9430e24344196cc82ac3d006b4"; //TestRes/RawFiles目录
collector1.CollectorGUID = "fddaaf9430e24344196cc82ac3d006b4"; //TestRes5/RawFiles目录
collector1.CollectorType = YooAsset.Editor.ECollectorType.MainAssetCollector;
collector1.PackRuleName = nameof(YooAsset.Editor.PackRawFile);
YooAsset.Editor.BundleCollectorSettingData.CreateCollector(rawFileGroup, collector1);
var collector2 = new YooAsset.Editor.BundleCollector();
collector2.CollectPath = "";
collector2.CollectorGUID = "9378c52809165094cb532c1678355a3c"; //TestRes5/EncryptFiles目录
collector2.CollectorType = YooAsset.Editor.ECollectorType.MainAssetCollector;
collector2.PackRuleName = nameof(YooAsset.Editor.PackRawFile);
YooAsset.Editor.BundleCollectorSettingData.CreateCollector(rawFileGroup, collector2);
}
}
private static void CreateArchiveBundlePackageCollector()
@@ -247,10 +258,17 @@ public class T0_InitYooAssets : IPrebuildSetup, IPostBuildCleanup
{
var collector1 = new YooAsset.Editor.BundleCollector();
collector1.CollectPath = "";
collector1.CollectorGUID = "c0444018376a7cd4ead6a671035617d6"; //TestRes/ArchiveFiles目录
collector1.CollectorGUID = "c0444018376a7cd4ead6a671035617d6"; //TestRes6/ArchiveFiles目录
collector1.CollectorType = YooAsset.Editor.ECollectorType.MainAssetCollector;
collector1.PackRuleName = nameof(YooAsset.Editor.PackCollector);
YooAsset.Editor.BundleCollectorSettingData.CreateCollector(archiveFileGroup, collector1);
var collector2 = new YooAsset.Editor.BundleCollector();
collector2.CollectPath = "";
collector2.CollectorGUID = "5bf4f68676550434291dbdee4da52f65"; //TestRes6/EncryptFiles目录
collector2.CollectorType = YooAsset.Editor.ECollectorType.MainAssetCollector;
collector2.PackRuleName = nameof(YooAsset.Editor.PackCollector);
YooAsset.Editor.BundleCollectorSettingData.CreateCollector(archiveFileGroup, collector2);
}
}
#endif

View File

@@ -23,7 +23,7 @@ public class T1_TestEditorFileSystem : IPrebuildSetup, IPostBuildCleanup
void IPrebuildSetup.Setup()
{
#if UNITY_EDITOR
// 构建资源包
// 构建 AssetBundlePackage
{
var simulateParams = new PackageBuildParameters(TestConsts.AssetBundlePackageName);
simulateParams.BuildPipelineName = "EditorSimulateBuildPipeline";
@@ -35,7 +35,7 @@ public class T1_TestEditorFileSystem : IPrebuildSetup, IPostBuildCleanup
UnityEditor.EditorPrefs.SetString(ASSET_BUNDLE_PACKAGE_ROOT_KEY, simulateResult.PackageRootDirectory);
}
// 构建原生资源包
// 构建 RawBundlePackage
{
var simulateParams = new PackageBuildParameters(TestConsts.RawBundlePackageName);
simulateParams.BuildPipelineName = "EditorSimulateBuildPipeline";
@@ -47,7 +47,7 @@ public class T1_TestEditorFileSystem : IPrebuildSetup, IPostBuildCleanup
UnityEditor.EditorPrefs.SetString(RAW_BUNDLE_PACKAGE_ROOT_KEY, simulateResult.PackageRootDirectory);
}
// 构建归档资源包
// 构建 ArchiveBundlePackage
{
var simulateParams = new PackageBuildParameters(TestConsts.ArchiveBundlePackageName);
simulateParams.BuildPipelineName = "EditorSimulateBuildPipeline";
@@ -68,7 +68,7 @@ public class T1_TestEditorFileSystem : IPrebuildSetup, IPostBuildCleanup
[UnityTest]
public IEnumerator A_InitializePackage()
{
// 初始化资源包 ASSET_BUNDLE
// 初始化 AssetBundlePackage
{
string packageRoot = string.Empty;
#if UNITY_EDITOR
@@ -104,7 +104,7 @@ public class T1_TestEditorFileSystem : IPrebuildSetup, IPostBuildCleanup
Assert.AreEqual(EOperationStatus.Succeeded, loadPackageManifestOp.Status);
}
// 初始化资源包 RAW_BUNDLE
// 初始化 RawBundlePackage
{
string packageRoot = string.Empty;
#if UNITY_EDITOR
@@ -140,7 +140,7 @@ public class T1_TestEditorFileSystem : IPrebuildSetup, IPostBuildCleanup
Assert.AreEqual(EOperationStatus.Succeeded, loadPackageManifestOp.Status);
}
// 初始化资源包 ARCHIVE_BUNDLE
// 初始化 ArchiveBundlePackage
{
string packageRoot = string.Empty;
#if UNITY_EDITOR
@@ -248,9 +248,9 @@ public class T1_TestEditorFileSystem : IPrebuildSetup, IPostBuildCleanup
}
[UnityTest]
public IEnumerator B11_TestLoadRawFileObject()
public IEnumerator B11_TestLoadRawBundle()
{
var tester = new TestLoadRawFileObject();
var tester = new TestLoadRawBundle();
yield return tester.RuntimeTester();
}

View File

@@ -23,7 +23,7 @@ public class T2_TestBuiltinFileSystem : IPrebuildSetup, IPostBuildCleanup
void IPrebuildSetup.Setup()
{
#if UNITY_EDITOR
// 构建AssetBundlePackage
// 构建 AssetBundlePackage
{
var buildParams = new PackageBuildParameters(TestConsts.AssetBundlePackageName);
buildParams.BuildPipelineName = "ScriptableBuildPipeline";
@@ -34,7 +34,7 @@ public class T2_TestBuiltinFileSystem : IPrebuildSetup, IPostBuildCleanup
UnityEditor.EditorPrefs.SetString(ASSET_BUNDLE_PACKAGE_ROOT_KEY, simulateResult.PackageRootDirectory);
}
// 构建RawBundlePackage
// 构建 RawBundlePackage
{
var buildParams = new PackageBuildParameters(TestConsts.RawBundlePackageName);
buildParams.BuildPipelineName = "RawFileBuildPipeline";
@@ -45,7 +45,7 @@ public class T2_TestBuiltinFileSystem : IPrebuildSetup, IPostBuildCleanup
UnityEditor.EditorPrefs.SetString(RAW_BUNDLE_PACKAGE_ROOT_KEY, simulateResult.PackageRootDirectory);
}
// 构建ArchiveBundlePackage
// 构建 ArchiveBundlePackage
{
var buildParams = new PackageBuildParameters(TestConsts.ArchiveBundlePackageName);
buildParams.BuildPipelineName = "ArchiveFileBuildPipeline";
@@ -65,7 +65,7 @@ public class T2_TestBuiltinFileSystem : IPrebuildSetup, IPostBuildCleanup
[UnityTest]
public IEnumerator A_InitializePackage()
{
// 初始化资源包 ASSET_BUNDLE
// 初始化 AssetBundlePackage
{
string packageRoot = string.Empty;
#if UNITY_EDITOR
@@ -81,7 +81,7 @@ public class T2_TestBuiltinFileSystem : IPrebuildSetup, IPostBuildCleanup
var manifestServices = new TestManifestDecryptor();
initParams.BuiltinFileSystemParameters = FileSystemParameters.CreateDefaultBuiltinFileSystemParameters(packageRoot);
initParams.BuiltinFileSystemParameters.AddParameter(EFileSystemParameter.ManifestDecryptor, manifestServices);
initParams.BuiltinFileSystemParameters.AddParameter(EFileSystemParameter.AssetbundleDecryptor, new TestFileStreamDecryption());
initParams.BuiltinFileSystemParameters.AddParameter(EFileSystemParameter.AssetBundleDecryptor, new TestAssetBundleDecryptor());
var initializeOp = package.InitializePackageAsync(initParams);
yield return initializeOp;
if (initializeOp.Status != EOperationStatus.Succeeded)
@@ -104,7 +104,7 @@ public class T2_TestBuiltinFileSystem : IPrebuildSetup, IPostBuildCleanup
Assert.AreEqual(EOperationStatus.Succeeded, loadPackageManifestOp.Status);
}
// 初始化资源包 RAW_BUNDLE
// 初始化 RawBundlePackage
{
string packageRoot = string.Empty;
#if UNITY_EDITOR
@@ -118,6 +118,7 @@ public class T2_TestBuiltinFileSystem : IPrebuildSetup, IPostBuildCleanup
// 初始化资源包
var initParams = new OfflinePlayModeOptions();
initParams.BuiltinFileSystemParameters = FileSystemParameters.CreateDefaultBuiltinFileSystemParameters(packageRoot);
initParams.BuiltinFileSystemParameters.AddParameter(EFileSystemParameter.RawBundleDecryptor, new TestRawBundleDecryptor());
var initializeOp = package.InitializePackageAsync(initParams);
yield return initializeOp;
if (initializeOp.Status != EOperationStatus.Succeeded)
@@ -140,7 +141,7 @@ public class T2_TestBuiltinFileSystem : IPrebuildSetup, IPostBuildCleanup
Assert.AreEqual(EOperationStatus.Succeeded, loadPackageManifestOp.Status);
}
// 初始化资源包 ARCHIVE_BUNDLE
// 初始化 ArchiveBundlePackage
{
string packageRoot = string.Empty;
#if UNITY_EDITOR
@@ -154,6 +155,7 @@ public class T2_TestBuiltinFileSystem : IPrebuildSetup, IPostBuildCleanup
// 初始化资源包
var initParams = new OfflinePlayModeOptions();
initParams.BuiltinFileSystemParameters = FileSystemParameters.CreateDefaultBuiltinFileSystemParameters(packageRoot);
initParams.BuiltinFileSystemParameters.AddParameter(EFileSystemParameter.ArchiveBundleDecryptor, new TestArchiveBundleDecryptor());
var initializeOp = package.InitializePackageAsync(initParams);
yield return initializeOp;
if (initializeOp.Status != EOperationStatus.Succeeded)
@@ -248,9 +250,9 @@ public class T2_TestBuiltinFileSystem : IPrebuildSetup, IPostBuildCleanup
}
[UnityTest]
public IEnumerator B11_TestLoadRawFileObject()
public IEnumerator B11_TestLoadRawBundle()
{
var tester = new TestLoadRawFileObject();
var tester = new TestLoadRawBundle();
yield return tester.RuntimeTester();
}
@@ -290,9 +292,9 @@ public class T2_TestBuiltinFileSystem : IPrebuildSetup, IPostBuildCleanup
}
[UnityTest]
public IEnumerator C01_TestBundleEncryption()
public IEnumerator C01_TestAssetBundleDecryption()
{
var tester = new TestBundleEncryption();
var tester = new TestAssetBundleDecryption();
yield return tester.RuntimeTester();
}

View File

@@ -1,30 +1,32 @@
using System;
using System.Text;
using System.Collections;
using UnityEngine;
using NUnit.Framework;
using YooAsset;
/// <summary>
/// 测试加载加密文件
/// 测试加载加密的 AssetBundle 资源
/// </summary>
/// <remarks>
/// 覆盖 API: LoadAssetAsync / LoadAssetSync / InstantiateSync
/// 测试内容:
/// 1. 异步加载加密预制体prefab_encryptA验证加载成功并实例化
/// 2. 同步加载加密的预制体prefab_encryptB验证加载成功并实例化
/// 1. 使用 Memory 解密器加载加密预制体prefab_encrypt_x / prefab_encrypt_y
/// </remarks>
public class TestBundleEncryption
public class TestAssetBundleDecryption
{
public IEnumerator RuntimeTester()
{
ResourcePackage package = YooAssets.GetPackage(TestConsts.AssetBundlePackageName);
Assert.IsNotNull(package);
yield return TestEncryptedPrefabPair(package, "prefab_encrypt_x", "prefab_encrypt_y");
}
private IEnumerator TestEncryptedPrefabPair(ResourcePackage package, string asyncLocation, string syncLocation)
{
Assert.IsNotNull(package);
// 异步加载加密的预制体
// 说明:测试内置文件解压
{
var assetHandle = package.LoadAssetAsync<GameObject>("prefab_encryptA");
var assetHandle = package.LoadAssetAsync<GameObject>(asyncLocation);
yield return assetHandle;
Assert.AreEqual(EOperationStatus.Succeeded, assetHandle.Status);
@@ -36,9 +38,8 @@ public class TestBundleEncryption
}
// 同步加载加密的预制体
// 说明:测试内置文件解压
{
var assetHandle = package.LoadAssetSync<GameObject>("prefab_encryptB");
var assetHandle = package.LoadAssetSync<GameObject>(syncLocation);
Assert.AreEqual(EOperationStatus.Succeeded, assetHandle.Status);
var options = new InstantiateOptions(true, Vector3.zero, Quaternion.identity);
@@ -48,4 +49,4 @@ public class TestBundleEncryption
assetHandle.Release();
}
}
}
}

View File

@@ -34,7 +34,11 @@ public class T3_TestCacheFileSystem : IPrebuildSetup, IPostBuildCleanup
if (Directory.Exists(cacheRoot))
Directory.Delete(cacheRoot, true);
// 拷贝打包资源到本地服务器
// 清空旧的本地服务器测试目录
if (Directory.Exists(TestConsts.TestServerDirectory))
Directory.Delete(TestConsts.TestServerDirectory, true);
// 拷贝 AssetBundlePackage 到本地服务器
{
string packageRoot = string.Empty;
#if UNITY_EDITOR
@@ -46,7 +50,31 @@ public class T3_TestCacheFileSystem : IPrebuildSetup, IPostBuildCleanup
CopyDirectory(packageRoot, TestConsts.TestServerDirectory);
}
// 初始化资源包 ASSET_BUNDLE
// 拷贝 RawBundlePackage 到本地服务器
{
string packageRoot = string.Empty;
#if UNITY_EDITOR
packageRoot = UnityEditor.EditorPrefs.GetString(T2_TestBuiltinFileSystem.RAW_BUNDLE_PACKAGE_ROOT_KEY);
#endif
if (Directory.Exists(packageRoot) == false)
throw new Exception($"Not found package root : {packageRoot}");
CopyDirectory(packageRoot, TestConsts.TestServerDirectory);
}
// 拷贝 ArchiveBundlePackage 到本地服务器
{
string packageRoot = string.Empty;
#if UNITY_EDITOR
packageRoot = UnityEditor.EditorPrefs.GetString(T2_TestBuiltinFileSystem.ARCHIVE_BUNDLE_PACKAGE_ROOT_KEY);
#endif
if (Directory.Exists(packageRoot) == false)
throw new Exception($"Not found package root : {packageRoot}");
CopyDirectory(packageRoot, TestConsts.TestServerDirectory);
}
// 初始化 AssetBundlePackage
{
var package = YooAssets.CreatePackage(TestConsts.AssetBundlePackageName);
@@ -58,7 +86,71 @@ public class T3_TestCacheFileSystem : IPrebuildSetup, IPostBuildCleanup
initParams.BuiltinFileSystemParameters = null;
initParams.CacheFileSystemParameters = FileSystemParameters.CreateDefaultSandboxFileSystemParameters(remoteService);
initParams.CacheFileSystemParameters.AddParameter(EFileSystemParameter.ManifestDecryptor, manifestServices);
initParams.CacheFileSystemParameters.AddParameter(EFileSystemParameter.AssetbundleDecryptor, new TestFileStreamDecryption());
initParams.CacheFileSystemParameters.AddParameter(EFileSystemParameter.AssetBundleDecryptor, new TestAssetBundleDecryptor());
var initializeOp = package.InitializePackageAsync(initParams);
yield return initializeOp;
if (initializeOp.Status != EOperationStatus.Succeeded)
Debug.LogError(initializeOp.Error);
Assert.AreEqual(EOperationStatus.Succeeded, initializeOp.Status);
// 请求资源版本
var requestVersionOp = package.RequestPackageVersionAsync();
yield return requestVersionOp;
if (requestVersionOp.Status != EOperationStatus.Succeeded)
Debug.LogError(requestVersionOp.Error);
Assert.AreEqual(EOperationStatus.Succeeded, requestVersionOp.Status);
// 更新资源清单
var loadPackageManifestOptions = new LoadPackageManifestOptions(requestVersionOp.PackageVersion, 60);
var loadPackageManifestOp = package.LoadPackageManifestAsync(loadPackageManifestOptions);
yield return loadPackageManifestOp;
if (loadPackageManifestOp.Status != EOperationStatus.Succeeded)
Debug.LogError(loadPackageManifestOp.Error);
Assert.AreEqual(EOperationStatus.Succeeded, loadPackageManifestOp.Status);
}
// 初始化 RawBundlePackage
{
var package = YooAssets.CreatePackage(TestConsts.RawBundlePackageName);
// 初始化资源包
var initParams = new HostPlayModeOptions();
var remoteService = new TestRemoteService(TestConsts.TestServerURL);
initParams.BuiltinFileSystemParameters = null;
initParams.CacheFileSystemParameters = FileSystemParameters.CreateDefaultSandboxFileSystemParameters(remoteService);
initParams.CacheFileSystemParameters.AddParameter(EFileSystemParameter.RawBundleDecryptor, new TestRawBundleDecryptor());
var initializeOp = package.InitializePackageAsync(initParams);
yield return initializeOp;
if (initializeOp.Status != EOperationStatus.Succeeded)
Debug.LogError(initializeOp.Error);
Assert.AreEqual(EOperationStatus.Succeeded, initializeOp.Status);
// 请求资源版本
var requestVersionOp = package.RequestPackageVersionAsync();
yield return requestVersionOp;
if (requestVersionOp.Status != EOperationStatus.Succeeded)
Debug.LogError(requestVersionOp.Error);
Assert.AreEqual(EOperationStatus.Succeeded, requestVersionOp.Status);
// 更新资源清单
var loadPackageManifestOptions = new LoadPackageManifestOptions(requestVersionOp.PackageVersion, 60);
var loadPackageManifestOp = package.LoadPackageManifestAsync(loadPackageManifestOptions);
yield return loadPackageManifestOp;
if (loadPackageManifestOp.Status != EOperationStatus.Succeeded)
Debug.LogError(loadPackageManifestOp.Error);
Assert.AreEqual(EOperationStatus.Succeeded, loadPackageManifestOp.Status);
}
// 初始化 ArchiveBundlePackage
{
var package = YooAssets.CreatePackage(TestConsts.ArchiveBundlePackageName);
// 初始化资源包
var initParams = new HostPlayModeOptions();
var remoteService = new TestRemoteService(TestConsts.TestServerURL);
initParams.BuiltinFileSystemParameters = null;
initParams.CacheFileSystemParameters = FileSystemParameters.CreateDefaultSandboxFileSystemParameters(remoteService);
initParams.CacheFileSystemParameters.AddParameter(EFileSystemParameter.ArchiveBundleDecryptor, new TestArchiveBundleDecryptor());
var initializeOp = package.InitializePackageAsync(initParams);
yield return initializeOp;
if (initializeOp.Status != EOperationStatus.Succeeded)
@@ -120,14 +212,182 @@ public class T3_TestCacheFileSystem : IPrebuildSetup, IPostBuildCleanup
}
[UnityTest]
public IEnumerator C04_TestClearCache()
public IEnumerator D01_TestAsyncTask()
{
var tester = new TestAsyncTask();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator D02_TestAsyncCompleted()
{
var tester = new TestAsyncCompleted();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator D03_TestLoadAsset()
{
var tester = new TestLoadAsset();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator D04_TestLoadSubAssets()
{
var tester = new TestLoadSubAssets();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator D05_TestLoadAllAssets()
{
var tester = new TestLoadAllAssets();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator D06_TestLoadGameObject()
{
var tester = new TestLoadGameObject();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator D07_TestLoadSpriteAtlas()
{
var tester = new TestLoadSpriteAtlas();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator D08_TestLoadScriptableObject()
{
var tester = new TestLoadScriptableObject();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator D09_TestLoadScene()
{
var tester = new TestLoadScene();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator D10_TestLoadBundleFile()
{
var tester = new TestLoadBundleFile();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator D11_TestLoadRawBundle()
{
var tester = new TestLoadRawBundle();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator D12_TestLoadArchiveBundle()
{
var tester = new TestLoadArchiveBundle();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator D13_TestEnsureBundleFile_RawBundle()
{
var tester = new TestEnsureBundleFile();
yield return tester.RuntimeTester_RawBundle();
}
[UnityTest]
public IEnumerator D14_TestEnsureBundleFile_AssetBundle()
{
var tester = new TestEnsureBundleFile();
yield return tester.RuntimeTester_AssetBundle();
}
[UnityTest]
public IEnumerator D15_TestEnsureBundleFile_ArchiveBundle()
{
var tester = new TestEnsureBundleFile();
yield return tester.RuntimeTester_ArchiveBundle();
}
[UnityTest]
public IEnumerator D16_TestUniTask()
{
var tester = new TestUniTask();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator E01_TestGetPackageInfo()
{
var tester = new TestGetPackageInfo();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator E02_TestGetAssetInfo()
{
var tester = new TestGetAssetInfo();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator E03_TestIsLocationValid()
{
var tester = new TestIsLocationValid();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator E04_TestLoadInvalidAsset()
{
var tester = new TestLoadInvalidAsset();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator E05_TestDuplicateLoad()
{
var tester = new TestDuplicateLoad();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator E06_TestHandleRelease()
{
var tester = new TestHandleRelease();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator E07_TestBundleFileRelease()
{
var tester = new TestBundleFileRelease();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator E08_TestUnloadAllAssets()
{
var tester = new TestUnloadAllAssets();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator F01_TestClearCache()
{
var tester = new TestClearCache();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator C05_TestClearManifest()
public IEnumerator F02_TestClearManifest()
{
var tester = new TestClearManifest();
yield return tester.RuntimeTester();
@@ -137,7 +397,7 @@ public class T3_TestCacheFileSystem : IPrebuildSetup, IPostBuildCleanup
public IEnumerator Z_DestroyPackage()
{
var tester = new TestDestroyPackage();
yield return tester.RuntimeTester(false);
yield return tester.RuntimeTester(true, true);
}
private static void CopyDirectory(string sourceDir, string targetDir)

View File

@@ -12,8 +12,8 @@ using YooAsset;
/// 覆盖 API: GetDownloadSize / LoadAssetAsync / LoadAssetSync / UnloadUnusedAssetsAsync
/// 测试内容:
/// 1. 验证目标远端资源的下载大小非零(尚未缓存)
/// 2. 异步加载远端资源prefab_encryptA),验证首次加载触发下载并最终成功
/// 3. 同步加载远端资源prefab_encryptB),首次应失败并触发后台下载
/// 2. 异步加载远端资源prefab_encrypt_x),验证首次加载触发下载并最终成功
/// 3. 同步加载远端资源prefab_encrypt_y),首次应失败并触发后台下载
/// 4. 释放失败的 Handle 并清理资源,等待下载完成后再次同步加载,验证成功
/// </remarks>
public class TestBundlePlaying
@@ -23,18 +23,18 @@ public class TestBundlePlaying
ResourcePackage package = YooAssets.GetPackage(TestConsts.AssetBundlePackageName);
Assert.IsNotNull(package);
if (package.GetDownloadSize("prefab_encryptA") == 0)
if (package.GetDownloadSize("prefab_encrypt_x") == 0)
{
Assert.Fail("Load bundle is already existed !");
}
if (package.GetDownloadSize("prefab_encryptB") == 0)
if (package.GetDownloadSize("prefab_encrypt_y") == 0)
{
Assert.Fail("Load bundle is already existed !");
}
// 测试异步加载远端资源
{
var assetsHandle = package.LoadAssetAsync<GameObject>("prefab_encryptA");
var assetsHandle = package.LoadAssetAsync<GameObject>("prefab_encrypt_x");
yield return assetsHandle;
Assert.AreEqual(EOperationStatus.Succeeded, assetsHandle.Status);
assetsHandle.Release();
@@ -45,7 +45,7 @@ public class TestBundlePlaying
{
// 验证失败结果
UnityEngine.TestTools.LogAssert.ignoreFailingMessages = true;
var assetsHandle = package.LoadAssetSync<GameObject>("prefab_encryptB");
var assetsHandle = package.LoadAssetSync<GameObject>("prefab_encrypt_y");
UnityEngine.TestTools.LogAssert.ignoreFailingMessages = false;
Assert.AreEqual(EOperationStatus.Failed, assetsHandle.Status);
@@ -57,7 +57,7 @@ public class TestBundlePlaying
// 验证成功结果
yield return new WaitForSeconds(1f);
UnityEngine.TestTools.LogAssert.ignoreFailingMessages = true;
assetsHandle = package.LoadAssetSync<GameObject>("prefab_encryptB");
assetsHandle = package.LoadAssetSync<GameObject>("prefab_encrypt_y");
UnityEngine.TestTools.LogAssert.ignoreFailingMessages = false;
Assert.AreEqual(EOperationStatus.Succeeded, assetsHandle.Status);
assetsHandle.Release();

View File

@@ -30,12 +30,12 @@ public class TestClearCache
// ---- 1. ClearBundleFilesByLocations ----
{
var options = new ClearCacheOptions(ClearCacheMethods.ClearBundleFilesByLocations, "prefab_encryptA");
var options = new ClearCacheOptions(ClearCacheMethods.ClearBundleFilesByLocations, "prefab_encrypt_x");
var clearOp = package.ClearCacheAsync(options);
yield return clearOp;
Assert.AreEqual(EOperationStatus.Succeeded, clearOp.Status);
Assert.Greater(package.GetDownloadSize("prefab_encryptA"), 0);
Assert.Greater(package.GetDownloadSize("prefab_encrypt_x"), 0);
}
// ---- 2. ClearBundleFilesByTags ----
@@ -53,7 +53,7 @@ public class TestClearCache
yield return clearOp;
Assert.AreEqual(EOperationStatus.Succeeded, clearOp.Status);
Assert.Greater(package.GetDownloadSize("prefab_encryptA"), 0);
Assert.Greater(package.GetDownloadSize("prefab_encrypt_x"), 0);
}
// ---- 4. ClearAllBundleFiles ----

View File

@@ -12,17 +12,24 @@ using YooAsset;
/// 测试内容:
/// 1. 创建资源下载器,验证需要下载的资源数量非零
/// 2. 启动下载并等待完成,验证下载状态为成功
/// 3. 覆盖 AssetBundle、RawBundle 和 ArchiveBundle 三个包裹
/// </remarks>
public class TestResourceDownloader
{
public IEnumerator RuntimeTester()
{
ResourcePackage package = YooAssets.GetPackage(TestConsts.AssetBundlePackageName);
yield return DownloadPackage(TestConsts.AssetBundlePackageName);
yield return DownloadPackage(TestConsts.RawBundlePackageName);
yield return DownloadPackage(TestConsts.ArchiveBundlePackageName);
}
private IEnumerator DownloadPackage(string packageName)
{
ResourcePackage package = YooAssets.GetPackage(packageName);
Assert.IsNotNull(package);
var options = new ResourceDownloaderOptions(10, 1);
var downloader = package.CreateResourceDownloader(options);
Assert.AreNotEqual(0, downloader.TotalDownloadCount);
Assert.AreNotEqual(0, downloader.TotalDownloadCount, $"{packageName} no files need to download.");
downloader.StartDownload();
yield return downloader;

View File

@@ -29,13 +29,13 @@ public class TestResourceImporter
string fileRoot = $"{packageDir.Parent.FullName}/OutputCache";
var fileInfoA = new ImportBundleInfo(
filePath: $"{fileRoot}/assets_samples_test_sample_testres3_import_prefab_importa.bundle.encrypt",
bundleName: "assets_samples_test_sample_testres3_import_prefab_importa.bundle",
filePath: $"{fileRoot}/assets_samples_test_sample_testres3_importfiles_prefab_import_a.bundle.encrypt",
bundleName: "assets_samples_test_sample_testres3_importfiles_prefab_import_a.bundle",
bundleGuid: null);
var fileInfoB = new ImportBundleInfo(
filePath: $"{fileRoot}/assets_samples_test_sample_testres3_import_prefab_importb.bundle.encrypt",
bundleName: "assets_samples_test_sample_testres3_import_prefab_importb.bundle",
filePath: $"{fileRoot}/assets_samples_test_sample_testres3_importfiles_prefab_import_b.bundle.encrypt",
bundleName: "assets_samples_test_sample_testres3_importfiles_prefab_import_b.bundle",
bundleGuid: null);
ImportBundleInfo[] importInfos = { fileInfoA, fileInfoB };

View File

@@ -10,7 +10,7 @@ GameObject:
m_Component:
- component: {fileID: 1740794871874781600}
m_Layer: 0
m_Name: prefab_encryptA
m_Name: prefab_encrypt_x
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0

View File

@@ -10,7 +10,7 @@ GameObject:
m_Component:
- component: {fileID: 1740794871874781600}
m_Layer: 0
m_Name: prefab_encryptB
m_Name: prefab_encrypt_y
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0

View File

@@ -46,9 +46,9 @@ SpriteAtlas:
- {fileID: 21300000, guid: fcab35236e33438448805a9211b0cc19, type: 3}
- {fileID: 21300000, guid: 3b8db7241fc8ff54e9dea6fc64cfd7e5, type: 3}
m_PackedSpriteNamesToIndex:
- pause
- bullet
- rocket
- sprite_b
- sprite_a
- sprite_c
m_RenderDataMap: {}
m_Tag: atlas_icon
m_IsVariant: 0

View File

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 111 KiB

View File

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 104 KiB

View File

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

View File

@@ -10,7 +10,7 @@ GameObject:
m_Component:
- component: {fileID: 7029742931587134142}
m_Layer: 0
m_Name: prefab_unpackA
m_Name: prefab_import_a
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0

View File

@@ -10,7 +10,7 @@ GameObject:
m_Component:
- component: {fileID: 7029742931587134142}
m_Layer: 0
m_Name: prefab_unpackB
m_Name: prefab_import_b
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0

View File

@@ -10,7 +10,7 @@ GameObject:
m_Component:
- component: {fileID: 7029742931587134142}
m_Layer: 0
m_Name: prefab_importA
m_Name: prefab_unpack_a
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0

View File

@@ -10,7 +10,7 @@ GameObject:
m_Component:
- component: {fileID: 7029742931587134142}
m_Layer: 0
m_Name: prefab_importB
m_Name: prefab_unpack_b
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: caefa9a20bd10f54395f8ea2900d1977
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9378c52809165094cb532c1678355a3c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1 @@
this is raw file x !

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: e3bf9fcab5b44514bb6aaf7a0e700ce3
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1 @@
this is raw file y !

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 913cf046bcd71c641a1cf6f1fd900491
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2b4e5ebf72945ef4d87639537fc14dbb
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a8b52fc9f8f300d4788b43e8122c89f6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5bf4f68676550434291dbdee4da52f65
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1 @@
this is archive file x !

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 6cbf078bef6735446a92ea8d8e3e537d
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1 @@
this is archive file y !

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 984b5469ff6e0fd47bc7b19830339812
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 3cdad6e1b6dbab74e83ac0ec3c0895b4
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: