using System; using System.IO; using System.Text; using System.Collections; using UnityEngine; using NUnit.Framework; using YooAsset; public class TestBundleEncryption { public IEnumerator RuntimeTester() { ResourcePackage package = YooAssets.GetPackage(TestDefine.AssetBundlePackageName); Assert.IsNotNull(package); // 加载音乐播放预制体 { var assetHandle = package.LoadAssetAsync("prefab_audio"); yield return assetHandle; Assert.AreEqual(EOperationStatus.Succeed, assetHandle.Status); var go = assetHandle.InstantiateSync(Vector3.zero, Quaternion.identity); Assert.IsNotNull(go); var audioSource = go.GetComponent(); Assert.IsNotNull(audioSource.clip); } // 试听三秒钟 yield return new WaitForSeconds(3f); } } /// /// 文件流加密方式 /// public class FileStreamTestEncryption : 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; } } } /// /// 文件偏移加密方式 /// public class FileOffsetTestEncryption : 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; } } } /// /// 资源文件解密流 /// 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; } } /// /// 资源文件流解密类 /// public class FileStreamTestDecryption : IDecryptionServices { /// /// 同步方式获取解密的资源包对象 /// 注意:加载流对象在资源包对象释放的时候会自动释放 /// 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; } /// /// 异步方式获取解密的资源包对象 /// 注意:加载流对象在资源包对象释放的时候会自动释放 /// 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; } /// /// 获取解密的字节数据 /// byte[] IDecryptionServices.ReadFileData(DecryptFileInfo fileInfo) { throw new System.NotImplementedException(); } /// /// 获取解密的文本数据 /// string IDecryptionServices.ReadFileText(DecryptFileInfo fileInfo) { throw new System.NotImplementedException(); } private static uint GetManagedReadBufferSize() { return 1024; } } /// /// 资源文件偏移解密类 /// public class FileOffsetTestDecryption : IDecryptionServices { /// /// 同步方式获取解密的资源包对象 /// 注意:加载流对象在资源包对象释放的时候会自动释放 /// DecryptResult IDecryptionServices.LoadAssetBundle(DecryptFileInfo fileInfo) { DecryptResult decryptResult = new DecryptResult(); decryptResult.ManagedStream = null; decryptResult.Result = AssetBundle.LoadFromFile(fileInfo.FileLoadPath, fileInfo.FileLoadCRC, GetFileOffset()); return decryptResult; } /// /// 异步方式获取解密的资源包对象 /// 注意:加载流对象在资源包对象释放的时候会自动释放 /// DecryptResult IDecryptionServices.LoadAssetBundleAsync(DecryptFileInfo fileInfo) { DecryptResult decryptResult = new DecryptResult(); decryptResult.ManagedStream = null; decryptResult.CreateRequest = AssetBundle.LoadFromFileAsync(fileInfo.FileLoadPath, fileInfo.FileLoadCRC, GetFileOffset()); return decryptResult; } /// /// 获取解密的字节数据 /// byte[] IDecryptionServices.ReadFileData(DecryptFileInfo fileInfo) { throw new System.NotImplementedException(); } /// /// 获取解密的文本数据 /// string IDecryptionServices.ReadFileText(DecryptFileInfo fileInfo) { throw new System.NotImplementedException(); } private static ulong GetFileOffset() { return 32; } } /// /// WebGL平台解密类 /// 注意:WebGL平台支持内存解密 /// public class WebFileStreamTestDecryption : 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; } }