update test sample

增加cache file system单元测试
This commit is contained in:
何冠峰
2025-07-17 21:26:13 +08:00
parent ac7ee16017
commit db159428c6
42 changed files with 890 additions and 269 deletions

View File

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

View File

@@ -0,0 +1,94 @@
using System;
using System.IO;
using System.Text;
using System.Collections;
using UnityEngine;
using YooAsset;
/// <summary>
/// 文件偏移加密方式
/// </summary>
public class TestFileOffsetEncryption : IEncryptionServices
{
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
{
// 说明对TestRes3资源目录进行加密
if (fileInfo.BundleName.Contains("_testres3_"))
{
int offset = 32;
byte[] fileData = File.ReadAllBytes(fileInfo.FileLoadPath);
var encryptedData = new byte[fileData.Length + offset];
Buffer.BlockCopy(fileData, 0, encryptedData, offset, fileData.Length);
EncryptResult result = new EncryptResult();
result.Encrypted = true;
result.EncryptedData = encryptedData;
return result;
}
else
{
EncryptResult result = new EncryptResult();
result.Encrypted = false;
return result;
}
}
}
/// <summary>
/// 资源文件偏移解密类
/// </summary>
public class TestFileOffsetDecryption : IDecryptionServices
{
/// <summary>
/// 同步方式获取解密的资源包对象
/// 注意:加载流对象在资源包对象释放的时候会自动释放
/// </summary>
DecryptResult IDecryptionServices.LoadAssetBundle(DecryptFileInfo fileInfo)
{
DecryptResult decryptResult = new DecryptResult();
decryptResult.ManagedStream = null;
decryptResult.Result = AssetBundle.LoadFromFile(fileInfo.FileLoadPath, fileInfo.FileLoadCRC, GetFileOffset());
return decryptResult;
}
/// <summary>
/// 异步方式获取解密的资源包对象
/// 注意:加载流对象在资源包对象释放的时候会自动释放
/// </summary>
DecryptResult IDecryptionServices.LoadAssetBundleAsync(DecryptFileInfo fileInfo)
{
DecryptResult decryptResult = new DecryptResult();
decryptResult.ManagedStream = null;
decryptResult.CreateRequest = AssetBundle.LoadFromFileAsync(fileInfo.FileLoadPath, fileInfo.FileLoadCRC, GetFileOffset());
return decryptResult;
}
/// <summary>
/// 后备方式获取解密的资源包对象
/// </summary>
DecryptResult IDecryptionServices.LoadAssetBundleFallback(DecryptFileInfo fileInfo)
{
return new DecryptResult();
}
/// <summary>
/// 获取解密的字节数据
/// </summary>
byte[] IDecryptionServices.ReadFileData(DecryptFileInfo fileInfo)
{
throw new System.NotImplementedException();
}
/// <summary>
/// 获取解密的文本数据
/// </summary>
string IDecryptionServices.ReadFileText(DecryptFileInfo fileInfo)
{
throw new System.NotImplementedException();
}
private static ulong GetFileOffset()
{
return 32;
}
}

View File

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

View File

@@ -0,0 +1,155 @@
using System;
using System.IO;
using System.Text;
using System.Collections;
using UnityEngine;
using YooAsset;
/// <summary>
/// 资源文件解密流
/// </summary>
public class BundleStream : FileStream
{
public const byte KEY = 64;
public BundleStream(string path, FileMode mode, FileAccess access, FileShare share) : base(path, mode, access, share)
{
}
public BundleStream(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>
/// 文件流加密方式
/// </summary>
public class TestFileStreamEncryption : IEncryptionServices
{
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
{
// 说明对TestRes3资源目录进行加密
if (fileInfo.BundleName.Contains("_testres3_"))
{
var fileData = File.ReadAllBytes(fileInfo.FileLoadPath);
for (int i = 0; i < fileData.Length; i++)
{
fileData[i] ^= BundleStream.KEY;
}
EncryptResult result = new EncryptResult();
result.Encrypted = true;
result.EncryptedData = fileData;
return result;
}
else
{
EncryptResult result = new EncryptResult();
result.Encrypted = false;
return result;
}
}
}
/// <summary>
/// 资源文件流解密类
/// </summary>
public class TestFileStreamDecryption : IDecryptionServices
{
/// <summary>
/// 同步方式获取解密的资源包对象
/// 注意:加载流对象在资源包对象释放的时候会自动释放
/// </summary>
DecryptResult IDecryptionServices.LoadAssetBundle(DecryptFileInfo fileInfo)
{
BundleStream bundleStream = new BundleStream(fileInfo.FileLoadPath, FileMode.Open, FileAccess.Read, FileShare.Read);
DecryptResult decryptResult = new DecryptResult();
decryptResult.ManagedStream = bundleStream;
decryptResult.Result = AssetBundle.LoadFromStream(bundleStream, fileInfo.FileLoadCRC, GetManagedReadBufferSize());
return decryptResult;
}
/// <summary>
/// 异步方式获取解密的资源包对象
/// 注意:加载流对象在资源包对象释放的时候会自动释放
/// </summary>
DecryptResult IDecryptionServices.LoadAssetBundleAsync(DecryptFileInfo fileInfo)
{
BundleStream bundleStream = new BundleStream(fileInfo.FileLoadPath, FileMode.Open, FileAccess.Read, FileShare.Read);
DecryptResult decryptResult = new DecryptResult();
decryptResult.ManagedStream = bundleStream;
decryptResult.CreateRequest = AssetBundle.LoadFromStreamAsync(bundleStream, fileInfo.FileLoadCRC, GetManagedReadBufferSize());
return decryptResult;
}
/// <summary>
/// 后备方式获取解密的资源包对象
/// </summary>
DecryptResult IDecryptionServices.LoadAssetBundleFallback(DecryptFileInfo fileInfo)
{
return new DecryptResult();
}
/// <summary>
/// 获取解密的字节数据
/// </summary>
byte[] IDecryptionServices.ReadFileData(DecryptFileInfo fileInfo)
{
throw new System.NotImplementedException();
}
/// <summary>
/// 获取解密的文本数据
/// </summary>
string IDecryptionServices.ReadFileText(DecryptFileInfo fileInfo)
{
throw new System.NotImplementedException();
}
private static uint GetManagedReadBufferSize()
{
return 1024;
}
}
/// <summary>
/// WebGL平台解密类
/// 注意WebGL平台支持内存解密
/// </summary>
public class TestWebFileMemoryDecryption : IWebDecryptionServices
{
public WebDecryptResult LoadAssetBundle(WebDecryptFileInfo fileInfo)
{
/*
byte[] copyData = new byte[fileInfo.FileData.Length];
Buffer.BlockCopy(fileInfo.FileData, 0, copyData, 0, fileInfo.FileData.Length);
for (int i = 0; i < copyData.Length; i++)
{
copyData[i] ^= BundleStream.KEY;
}
WebDecryptResult decryptResult = new WebDecryptResult();
decryptResult.Result = AssetBundle.LoadFromMemory(copyData);
return decryptResult;
*/
for (int i = 0; i < fileInfo.FileData.Length; i++)
{
fileInfo.FileData[i] ^= BundleStream.KEY;
}
WebDecryptResult decryptResult = new WebDecryptResult();
decryptResult.Result = AssetBundle.LoadFromMemory(fileInfo.FileData);
return decryptResult;
}
}

View File

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

View File

@@ -89,7 +89,7 @@ public class T0_InitYooAssets : IPrebuildSetup, IPostBuildCleanup
YooAsset.Editor.AssetBundleCollectorSettingData.CreateCollector(panelGroup, collector1);
}
// 预制体
// 预制体构建到一个AB
var prefabGroup = YooAsset.Editor.AssetBundleCollectorSettingData.CreateGroup(testPackage, "PrefabGroup");
{
var collector1 = new YooAsset.Editor.AssetBundleCollector();
@@ -169,14 +169,30 @@ public class T0_InitYooAssets : IPrebuildSetup, IPostBuildCleanup
collector1.CollectorGUID = "e082d492b9da65e499cee3495be3645d"; //TestRes3/music目录
collector1.CollectorType = YooAsset.Editor.ECollectorType.MainAssetCollector;
collector1.PackRuleName = nameof(YooAsset.Editor.PackSeparately);
YooAsset.Editor.AssetBundleCollectorSettingData.CreateCollector(referenceGroup, collector1);
YooAsset.Editor.AssetBundleCollectorSettingData.CreateCollector(encryptGroup, collector1);
var collector2 = new YooAsset.Editor.AssetBundleCollector();
collector2.CollectPath = "";
collector2.CollectorGUID = "8c5a1726d94498e4cbe30f5f510cc796"; //TestRes3/prefab目录
collector2.CollectorType = YooAsset.Editor.ECollectorType.MainAssetCollector;
collector2.PackRuleName = nameof(YooAsset.Editor.PackSeparately);
YooAsset.Editor.AssetBundleCollectorSettingData.CreateCollector(referenceGroup, collector2);
YooAsset.Editor.AssetBundleCollectorSettingData.CreateCollector(encryptGroup, collector2);
var collector3 = new YooAsset.Editor.AssetBundleCollector();
collector3.CollectPath = "";
collector3.CollectorGUID = "401af1ca0abf3ae4594631e5f71bfe27"; //TestRes3/unpack目录
collector3.CollectorType = YooAsset.Editor.ECollectorType.MainAssetCollector;
collector3.AssetTags = "unpack";
collector3.PackRuleName = nameof(YooAsset.Editor.PackSeparately);
YooAsset.Editor.AssetBundleCollectorSettingData.CreateCollector(encryptGroup, collector3);
var collector4 = new YooAsset.Editor.AssetBundleCollector();
collector4.CollectPath = "";
collector4.CollectorGUID = "35f454fb80a715047bcf0ce30c7c4f18"; //TestRes3/import目录
collector4.CollectorType = YooAsset.Editor.ECollectorType.MainAssetCollector;
collector4.AssetTags = "import";
collector4.PackRuleName = nameof(YooAsset.Editor.PackSeparately);
YooAsset.Editor.AssetBundleCollectorSettingData.CreateCollector(encryptGroup, collector4);
}
}
private static void CreateRawBundlePackageCollector()

View File

@@ -24,7 +24,7 @@ public class T1_TestEditorFileSystem : IPrebuildSetup, IPostBuildCleanup
simulateParams.InvokeAssmeblyName = "YooAsset.Test.Editor";
simulateParams.InvokeClassFullName = "TestPackageBuilder";
simulateParams.InvokeMethodName = "BuildPackage";
var simulateResult = PakcageInvokeBuilder.InvokeBuilder(simulateParams);
var simulateResult = PackageInvokeBuilder.InvokeBuilder(simulateParams);
UnityEditor.EditorPrefs.SetString(ASSET_BUNDLE_PACKAGE_ROOT_KEY, simulateResult.PackageRootDirectory);
}
@@ -35,7 +35,7 @@ public class T1_TestEditorFileSystem : IPrebuildSetup, IPostBuildCleanup
simulateParams.InvokeAssmeblyName = "YooAsset.Test.Editor";
simulateParams.InvokeClassFullName = "TestPackageBuilder";
simulateParams.InvokeMethodName = "BuildPackage";
var simulateResult = PakcageInvokeBuilder.InvokeBuilder(simulateParams);
var simulateResult = PackageInvokeBuilder.InvokeBuilder(simulateParams);
UnityEditor.EditorPrefs.SetString(RAW_BUNDLE_PACKAGE_ROOT_KEY, simulateResult.PackageRootDirectory);
}
#endif

View File

@@ -11,8 +11,8 @@ using YooAsset;
public class T2_TestBuldinFileSystem : IPrebuildSetup, IPostBuildCleanup
{
private const string ASSET_BUNDLE_PACKAGE_ROOT_KEY = "T2_ASSET_BUNDLE_PACKAGE_ROOT_KEY";
private const string RAW_BUNDLE_PACKAGE_ROOT_KEY = "T2_RAW_BUNDLE_PACKAGE_ROOT_KEY";
public const string ASSET_BUNDLE_PACKAGE_ROOT_KEY = "T2_ASSET_BUNDLE_PACKAGE_ROOT_KEY";
public const string RAW_BUNDLE_PACKAGE_ROOT_KEY = "T2_RAW_BUNDLE_PACKAGE_ROOT_KEY";
void IPrebuildSetup.Setup()
{
@@ -24,7 +24,7 @@ public class T2_TestBuldinFileSystem : IPrebuildSetup, IPostBuildCleanup
buildParams.InvokeAssmeblyName = "YooAsset.Test.Editor";
buildParams.InvokeClassFullName = "TestPackageBuilder";
buildParams.InvokeMethodName = "BuildPackage";
var simulateResult = PakcageInvokeBuilder.InvokeBuilder(buildParams);
var simulateResult = PackageInvokeBuilder.InvokeBuilder(buildParams);
UnityEditor.EditorPrefs.SetString(ASSET_BUNDLE_PACKAGE_ROOT_KEY, simulateResult.PackageRootDirectory);
}
@@ -35,7 +35,7 @@ public class T2_TestBuldinFileSystem : IPrebuildSetup, IPostBuildCleanup
buildParams.InvokeAssmeblyName = "YooAsset.Test.Editor";
buildParams.InvokeClassFullName = "TestPackageBuilder";
buildParams.InvokeMethodName = "BuildPackage";
var simulateResult = PakcageInvokeBuilder.InvokeBuilder(buildParams);
var simulateResult = PackageInvokeBuilder.InvokeBuilder(buildParams);
UnityEditor.EditorPrefs.SetString(RAW_BUNDLE_PACKAGE_ROOT_KEY, simulateResult.PackageRootDirectory);
}
#endif

View File

@@ -6,6 +6,9 @@ using UnityEngine;
using NUnit.Framework;
using YooAsset;
/// <summary>
/// 测试加载加密文件
/// </summary>
public class TestBundleEncryption
{
public IEnumerator RuntimeTester()
@@ -39,245 +42,27 @@ public class TestBundleEncryption
Assert.IsNotNull(audioSource.clip);
}
// 试听三秒钟
yield return new WaitForSeconds(3f);
yield return new WaitForSeconds(1f);
}
}
/// <summary>
/// 文件流加密方式
/// </summary>
public class TestFileStreamEncryption : IEncryptionServices
/* 资源代码流程
* 内置文件解压(加载器)
BuildinFileSystem::LoadBundleFile()
{
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
{
// 说明对TestRes3资源目录进行加密
if (fileInfo.BundleName.Contains("_testres3_"))
{
var fileData = File.ReadAllBytes(fileInfo.FileLoadPath);
for (int i = 0; i < fileData.Length; i++)
{
fileData[i] ^= BundleStream.KEY;
}
EncryptResult result = new EncryptResult();
result.Encrypted = true;
result.EncryptedData = fileData;
return result;
}
else
{
EncryptResult result = new EncryptResult();
result.Encrypted = false;
return result;
}
}
_unpackFileSystem.LoadBundleFile(bundle);
}
/// <summary>
/// 文件偏移加密方式
/// </summary>
public class TestFileOffsetEncryption : IEncryptionServices
UnpackFileSystem::LoadAssetBundleOperation()
{
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
{
// 说明对TestRes3资源目录进行加密
if (fileInfo.BundleName.Contains("_testres3_"))
{
int offset = 32;
byte[] fileData = File.ReadAllBytes(fileInfo.FileLoadPath);
var encryptedData = new byte[fileData.Length + offset];
Buffer.BlockCopy(fileData, 0, encryptedData, offset, fileData.Length);
EncryptResult result = new EncryptResult();
result.Encrypted = true;
result.EncryptedData = encryptedData;
return result;
}
else
{
EncryptResult result = new EncryptResult();
result.Encrypted = false;
return result;
}
}
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60);
_unpackFileSystem.DownloadFileAsync(_bundle, options);
}
/// <summary>
/// 资源文件解密流
/// </summary>
public class BundleStream : FileStream
UnpackFileSystem::DownloadFileAsync()
{
public const byte KEY = 64;
public BundleStream(string path, FileMode mode, FileAccess access, FileShare share) : base(path, mode, access, share)
{
}
public BundleStream(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;
}
//RemoteServices返回内置文件路径
string mainURL = RemoteServices.GetRemoteMainURL(bundle.FileName);
string fallbackURL = RemoteServices.GetRemoteFallbackURL(bundle.FileName);
options.SetURL(mainURL, fallbackURL);
return new DownloadPackageBundleOperation(bundle, options);
}
/// <summary>
/// 资源文件流解密类
/// </summary>
public class TestFileStreamDecryption : IDecryptionServices
{
/// <summary>
/// 同步方式获取解密的资源包对象
/// 注意:加载流对象在资源包对象释放的时候会自动释放
/// </summary>
DecryptResult IDecryptionServices.LoadAssetBundle(DecryptFileInfo fileInfo)
{
BundleStream bundleStream = new BundleStream(fileInfo.FileLoadPath, FileMode.Open, FileAccess.Read, FileShare.Read);
DecryptResult decryptResult = new DecryptResult();
decryptResult.ManagedStream = bundleStream;
decryptResult.Result = AssetBundle.LoadFromStream(bundleStream, fileInfo.FileLoadCRC, GetManagedReadBufferSize());
return decryptResult;
}
/// <summary>
/// 异步方式获取解密的资源包对象
/// 注意:加载流对象在资源包对象释放的时候会自动释放
/// </summary>
DecryptResult IDecryptionServices.LoadAssetBundleAsync(DecryptFileInfo fileInfo)
{
BundleStream bundleStream = new BundleStream(fileInfo.FileLoadPath, FileMode.Open, FileAccess.Read, FileShare.Read);
DecryptResult decryptResult = new DecryptResult();
decryptResult.ManagedStream = bundleStream;
decryptResult.CreateRequest = AssetBundle.LoadFromStreamAsync(bundleStream, fileInfo.FileLoadCRC, GetManagedReadBufferSize());
return decryptResult;
}
/// <summary>
/// 后备方式获取解密的资源包对象
/// </summary>
DecryptResult IDecryptionServices.LoadAssetBundleFallback(DecryptFileInfo fileInfo)
{
return new DecryptResult();
}
/// <summary>
/// 获取解密的字节数据
/// </summary>
byte[] IDecryptionServices.ReadFileData(DecryptFileInfo fileInfo)
{
throw new System.NotImplementedException();
}
/// <summary>
/// 获取解密的文本数据
/// </summary>
string IDecryptionServices.ReadFileText(DecryptFileInfo fileInfo)
{
throw new System.NotImplementedException();
}
private static uint GetManagedReadBufferSize()
{
return 1024;
}
}
/// <summary>
/// 资源文件偏移解密类
/// </summary>
public class TestFileOffsetDecryption : IDecryptionServices
{
/// <summary>
/// 同步方式获取解密的资源包对象
/// 注意:加载流对象在资源包对象释放的时候会自动释放
/// </summary>
DecryptResult IDecryptionServices.LoadAssetBundle(DecryptFileInfo fileInfo)
{
DecryptResult decryptResult = new DecryptResult();
decryptResult.ManagedStream = null;
decryptResult.Result = AssetBundle.LoadFromFile(fileInfo.FileLoadPath, fileInfo.FileLoadCRC, GetFileOffset());
return decryptResult;
}
/// <summary>
/// 异步方式获取解密的资源包对象
/// 注意:加载流对象在资源包对象释放的时候会自动释放
/// </summary>
DecryptResult IDecryptionServices.LoadAssetBundleAsync(DecryptFileInfo fileInfo)
{
DecryptResult decryptResult = new DecryptResult();
decryptResult.ManagedStream = null;
decryptResult.CreateRequest = AssetBundle.LoadFromFileAsync(fileInfo.FileLoadPath, fileInfo.FileLoadCRC, GetFileOffset());
return decryptResult;
}
/// <summary>
/// 后备方式获取解密的资源包对象
/// </summary>
DecryptResult IDecryptionServices.LoadAssetBundleFallback(DecryptFileInfo fileInfo)
{
return new DecryptResult();
}
/// <summary>
/// 获取解密的字节数据
/// </summary>
byte[] IDecryptionServices.ReadFileData(DecryptFileInfo fileInfo)
{
throw new System.NotImplementedException();
}
/// <summary>
/// 获取解密的文本数据
/// </summary>
string IDecryptionServices.ReadFileText(DecryptFileInfo fileInfo)
{
throw new System.NotImplementedException();
}
private static ulong GetFileOffset()
{
return 32;
}
}
/// <summary>
/// WebGL平台解密类
/// 注意WebGL平台支持内存解密
/// </summary>
public class TestWebFileStreamDecryption : IWebDecryptionServices
{
public WebDecryptResult LoadAssetBundle(WebDecryptFileInfo fileInfo)
{
/*
byte[] copyData = new byte[fileInfo.FileData.Length];
Buffer.BlockCopy(fileInfo.FileData, 0, copyData, 0, fileInfo.FileData.Length);
for (int i = 0; i < copyData.Length; i++)
{
copyData[i] ^= BundleStream.KEY;
}
WebDecryptResult decryptResult = new WebDecryptResult();
decryptResult.Result = AssetBundle.LoadFromMemory(copyData);
return decryptResult;
*/
for (int i = 0; i < fileInfo.FileData.Length; i++)
{
fileInfo.FileData[i] ^= BundleStream.KEY;
}
WebDecryptResult decryptResult = new WebDecryptResult();
decryptResult.Result = AssetBundle.LoadFromMemory(fileInfo.FileData);
return decryptResult;
}
}
*/

View File

@@ -0,0 +1,47 @@
using System;
using System.IO;
using System.Text;
using System.Collections;
using UnityEngine;
using NUnit.Framework;
using YooAsset;
/// <summary>
/// 测试内置文件解压
/// </summary>
public class TestBundleUnpacker
{
public IEnumerator RuntimeTester()
{
ResourcePackage package = YooAssets.GetPackage(TestDefine.AssetBundlePackageName);
Assert.IsNotNull(package);
var resourceUnpacker = package.CreateResourceUnpacker("unpack", 10, 1);
Assert.AreEqual(resourceUnpacker.TotalDownloadCount, 2);
yield return resourceUnpacker;
Assert.AreEqual(EOperationStatus.Succeed, resourceUnpacker.Status);
// 等待一秒
yield return new WaitForSeconds(1f);
}
}
/* 资源代码流程
* 内置文件解压(解压器)
BundleInfo::CreateDownloader()
{
return _buildFileSystem.DownloadFileAsync(Bundle, options);
}
BuildinFileSystem::DownloadFileAsync()
{
options.ImportFilePath = xxxxxx;
_unpackFileSystem.DownloadFileAsync(bundle, options);
}
UnpackFileSystem::DownloadFileAsync()
{
string mainURL = ConvertToWWWPath(options.ImportFilePath);
options.SetURL(mainURL, mainURL);
return new DownloadPackageBundleOperation(bundle, options);
}
*/

View File

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

View File

@@ -3,18 +3,115 @@ using System.IO;
using System.Text;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.U2D;
using UnityEngine.TestTools;
using NUnit.Framework;
using YooAsset;
public class T3_TestCacheFileSystem : IPrebuildSetup, IPostBuildCleanup
{
public void Setup()
{
throw new NotImplementedException();
}
public void Cleanup()
{
throw new NotImplementedException();
}
[UnityTest]
public IEnumerator A_InitializePackage()
{
// 清空旧的缓存目录
string projectPath = Path.GetDirectoryName(Application.dataPath);
string cacheRoot = $"{projectPath}/yoo";
Directory.Delete(cacheRoot, true);
// 拷贝打包资源到本地服务器
{
string packageRoot = string.Empty;
#if UNITY_EDITOR
packageRoot = UnityEditor.EditorPrefs.GetString(T2_TestBuldinFileSystem.ASSET_BUNDLE_PACKAGE_ROOT_KEY);
#endif
if (Directory.Exists(packageRoot) == false)
throw new Exception($"Not found package root : {packageRoot}");
string testServerDirectory = "C://xampp/htdocs/CDN/Android/Test";
}
// 初始化资源包 ASSET_BUNDLE
{
var package = YooAssets.CreatePackage(TestDefine.AssetBundlePackageName);
// 初始化资源包
var initParams = new HostPlayModeParameters();
var fileDecryption = new TestFileStreamDecryption();
var manifestProcess = new TestProcessManifest();
string hostServerIP = "http://127.0.0.1/CDN/Android/Test/";
var remoteServices = new TestRemoteServices(hostServerIP);
initParams.BuildinFileSystemParameters = null;
initParams.CacheFileSystemParameters = FileSystemParameters.CreateDefaultCacheFileSystemParameters(remoteServices, fileDecryption);
initParams.CacheFileSystemParameters.AddParameter(FileSystemParametersDefine.MANIFEST_SERVICES, manifestProcess);
var initializeOp = package.InitializeAsync(initParams);
yield return initializeOp;
if (initializeOp.Status != EOperationStatus.Succeed)
Debug.LogError(initializeOp.Error);
Assert.AreEqual(EOperationStatus.Succeed, initializeOp.Status);
// 请求资源版本
var requetVersionOp = package.RequestPackageVersionAsync();
yield return requetVersionOp;
if (requetVersionOp.Status != EOperationStatus.Succeed)
Debug.LogError(requetVersionOp.Error);
Assert.AreEqual(EOperationStatus.Succeed, requetVersionOp.Status);
// 更新资源清单
var updateManifestOp = package.UpdatePackageManifestAsync(requetVersionOp.PackageVersion);
yield return updateManifestOp;
if (updateManifestOp.Status != EOperationStatus.Succeed)
Debug.LogError(updateManifestOp.Error);
Assert.AreEqual(EOperationStatus.Succeed, updateManifestOp.Status);
}
}
private class TestRemoteServices : IRemoteServices
{
private readonly string _localServerRoot;
public TestRemoteServices(string localServerRoot)
{
_localServerRoot = localServerRoot;
}
string IRemoteServices.GetRemoteMainURL(string fileName)
{
return $"{_localServerRoot}/{fileName}";
}
string IRemoteServices.GetRemoteFallbackURL(string fileName)
{
return $"{_localServerRoot}/{fileName}";
}
}
[UnityTest]
public IEnumerator B1_TestBundlePlaying()
{
var tester = new TestBundlePlaying();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator B2_TestBundleImporter()
{
var tester = new TestBundleImporter();
yield return tester.RuntimeTester();
}
[UnityTest]
public IEnumerator B3_TestBundleDownloader()
{
var tester = new TestBundleDownloader();
yield return tester.RuntimeTester();
}
}

View File

@@ -0,0 +1,47 @@
using System;
using System.IO;
using System.Text;
using System.Collections;
using UnityEngine;
using NUnit.Framework;
using YooAsset;
/// <summary>
/// 测试远端文件下载
/// </summary>
public class TestBundleDownloader
{
public IEnumerator RuntimeTester()
{
ResourcePackage package = YooAssets.GetPackage(TestDefine.AssetBundlePackageName);
Assert.IsNotNull(package);
var downloader = package.CreateResourceDownloader(10, 1);
if (downloader.TotalDownloadCount == 0)
{
Assert.Fail($"Test downloader not found any file !");
}
downloader.BeginDownload();
downloader.DownloadFinishCallback = (DownloaderFinishData data) =>
{
if (data.Succeed == false)
Assert.Fail($"Test downloader failed ! {downloader.Error}");
};
// 等待一秒
yield return new WaitForSeconds(1f);
}
}
/* 资源代码流程
* 远端文件下载(下载器)
CacheFileSystem::DownloadFileAsync()
{
//RemoteServices返回CDN文件路径
string mainURL = RemoteServices.GetRemoteMainURL(bundle.FileName);
string fallbackURL = RemoteServices.GetRemoteFallbackURL(bundle.FileName);
options.SetURL(mainURL, fallbackURL);
return new DownloadPackageBundleOperation(bundle, options);
}
*/

View File

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

View File

@@ -0,0 +1,57 @@
using System;
using System.IO;
using System.Text;
using System.Collections;
using UnityEngine;
using NUnit.Framework;
using YooAsset;
/// <summary>
/// 测试本地文件导入
/// </summary>
public class TestBundleImporter
{
public IEnumerator RuntimeTester()
{
ResourcePackage package = YooAssets.GetPackage(TestDefine.AssetBundlePackageName);
Assert.IsNotNull(package);
string packageRoot = UnityEditor.EditorPrefs.GetString(T2_TestBuldinFileSystem.ASSET_BUNDLE_PACKAGE_ROOT_KEY);
DirectoryInfo packageDir = new DirectoryInfo(packageRoot);
string fileRoot = $"{packageDir.Parent.FullName}/OutputCache";
ImportFileInfo fileInfoA = new ImportFileInfo();
fileInfoA.FilePath = $"{fileRoot}/assets_samples_test_sample_testres3_import_prefab_importa.bundle.encrypt";
fileInfoA.BundleName = "assets_samples_test_sample_testres3_import_prefab_importa.bundle";
ImportFileInfo fileInfoB = new ImportFileInfo();
fileInfoB.FilePath = $"{fileRoot}/assets_samples_test_sample_testres3_import_prefab_importb.bundle.encrypt";
fileInfoB.BundleName = "assets_samples_test_sample_testres3_import_prefab_importb.bundle";
ImportFileInfo[] importInfos = { fileInfoA, fileInfoB };
var unpacker = package.CreateResourceImporter(importInfos, 10, 1);
Assert.AreEqual(unpacker.TotalDownloadCount, 2);
unpacker.BeginDownload();
yield return unpacker;
Assert.AreEqual(EOperationStatus.Succeed, unpacker.Status);
// 等待一秒
yield return new WaitForSeconds(1f);
}
}
/* 资源代码流程
* 本地文件导入(导入器)
BundleInfo::CreateDownloader()
{
options.ImportFilePath = _importFilePath;
return _cacheFileSystem.DownloadFileAsync(Bundle, options);
}
CacheFileSystem::DownloadFileAsync()
{
string mainURL = ConvertToWWWPath(options.ImportFilePath);
options.SetURL(mainURL, mainURL);
return new DownloadPackageBundleOperation(bundle, options);
}
*/

View File

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

View File

@@ -0,0 +1,71 @@
using System;
using System.IO;
using System.Text;
using System.Collections;
using UnityEngine;
using NUnit.Framework;
using YooAsset;
/// <summary>
/// 测试边玩边下
/// </summary>
public class TestBundlePlaying
{
public IEnumerator RuntimeTester()
{
ResourcePackage package = YooAssets.GetPackage(TestDefine.AssetBundlePackageName);
Assert.IsNotNull(package);
if (package.IsNeedDownloadFromRemote("panel_a") == false)
{
Assert.Fail("Load bundle is already existed !");
}
if (package.IsNeedDownloadFromRemote("panel_b") == false)
{
Assert.Fail("Load bundle is already existed !");
}
// 测试异步加载
{
var assetsHandle = package.LoadAssetAsync<GameObject>("panel_a");
yield return assetsHandle;
Assert.AreEqual(EOperationStatus.Succeed, assetsHandle.Status);
}
// 测试同步加载
{
var assetsHandle = package.LoadAssetSync<GameObject>("panel_b");
yield return assetsHandle;
Assert.AreEqual(EOperationStatus.Failed, assetsHandle.Status);
yield return new WaitForSeconds(1f);
assetsHandle = package.LoadAssetSync<GameObject>("panel_b");
yield return assetsHandle;
Assert.AreEqual(EOperationStatus.Succeed, assetsHandle.Status);
}
// 等待一秒
yield return new WaitForSeconds(1f);
}
}
/* 资源代码流程
* 远端文件下载(加载器)
CacheFileSystem::LoadBundleFile()
{
_cacheFileSystem.LoadBundleFile(bundle);
}
CacheFileSystem::LoadAssetBundleOperation()
{
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60);
_cacheFileSystem.DownloadFileAsync(_bundle, options);
}
CacheFileSystem::DownloadFileAsync()
{
//RemoteServices返回CDN文件路径
string mainURL = RemoteServices.GetRemoteMainURL(bundle.FileName);
string fallbackURL = RemoteServices.GetRemoteFallbackURL(bundle.FileName);
options.SetURL(mainURL, fallbackURL);
return new DownloadPackageBundleOperation(bundle, options);
}
*/

View File

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

View File

@@ -1,6 +1,6 @@

public class TestDefine
{
public const string AssetBundlePackageName = "AssetBundlePackage";
public const string RawBundlePackageName = "RawBundlePackage";
public const string AssetBundlePackageName = "AssetBundleTestPackage";
public const string RawBundlePackageName = "RawBundleTestPackage";
}

View File

@@ -35,6 +35,7 @@ public class TestLoadPanel
Assert.IsNotNull(instantiateOp.Result);
TestLogger.Log(this, instantiateOp.Result.name);
GameObject.Destroy(instantiateOp.Result);
}
}
}

View File

@@ -42,6 +42,7 @@ public class TestLoadPrefab
Assert.IsNotNull(instantiateOp.Result);
TestLogger.Log(this, instantiateOp.Result.name);
GameObject.Destroy(instantiateOp.Result);
}
// 同步加载指定预制体
@@ -57,6 +58,7 @@ public class TestLoadPrefab
Assert.IsNotNull(instantiateOp.Result);
TestLogger.Log(this, instantiateOp.Result.name);
GameObject.Destroy(instantiateOp.Result);
}
}
}

View File

@@ -36,10 +36,6 @@ SpriteAtlas:
bindAsDefault: 1
isAtlasV2: 0
cachedData: {fileID: 0}
packedSpriteRenderDataKeys:
- 379c45e0c5ba5e54e8df03f52e4c7680: 21300000
- fcab35236e33438448805a9211b0cc19: 21300000
- 3b8db7241fc8ff54e9dea6fc64cfd7e5: 21300000
m_MasterAtlas: {fileID: 0}
m_PackedSprites:
- {fileID: 21300000, guid: 379c45e0c5ba5e54e8df03f52e4c7680, type: 3}

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,33 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &3418152319973048114
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7029742931587134142}
m_Layer: 0
m_Name: prefab_importA
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &7029742931587134142
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3418152319973048114}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 10, z: 5}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

View File

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

View File

@@ -0,0 +1,33 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &3418152319973048114
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7029742931587134142}
m_Layer: 0
m_Name: prefab_importB
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &7029742931587134142
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3418152319973048114}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 10, z: 5}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8a3d81de5069340469960fcef3ac152d
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -10,7 +10,6 @@ GameObject:
m_Component:
- component: {fileID: 1740794871874781600}
- component: {fileID: 8364371343008149393}
- component: {fileID: 7423861191467597400}
m_Layer: 0
m_Name: prefab_audioA
m_TagString: Untagged
@@ -129,11 +128,3 @@ AudioSource:
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
--- !u!81 &7423861191467597400
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3749121449083481702}
m_Enabled: 1

View File

@@ -10,7 +10,6 @@ GameObject:
m_Component:
- component: {fileID: 1740794871874781600}
- component: {fileID: 8364371343008149393}
- component: {fileID: 7423861191467597400}
m_Layer: 0
m_Name: prefab_audioB
m_TagString: Untagged
@@ -129,11 +128,3 @@ AudioSource:
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
--- !u!81 &7423861191467597400
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3749121449083481702}
m_Enabled: 1

View File

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

View File

@@ -0,0 +1,33 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &3418152319973048114
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7029742931587134142}
m_Layer: 0
m_Name: prefab_unpackA
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &7029742931587134142
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3418152319973048114}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 10, z: 5}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 73dbe212a75e3c247b96f50c2a2c5321
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,33 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &3418152319973048114
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7029742931587134142}
m_Layer: 0
m_Name: prefab_unpackB
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &7029742931587134142
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3418152319973048114}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 10, z: 5}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

View File

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

View File

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