最近用HybridCLR做热更,热更dll也是AssetBundle,如果不做加密处理,也就意味着资源和热更代码全都赤果果暴露出来了。
GF框架内置的AssetBundle工具自带简单的加密功能:
勾选AB包底部下拉菜单可以选中不同的加载AB方式,不同的加载方式会走DefaultLoadResourceAgentHelper不同的加载方法;
Load From File: 回调ReadFile(string fullPath)方法;
其它:回调ParseBytes(byte[] bytes)方法;
DefaultLoadResourceAgentHelper已经根据AB选择的加载方式,处理了是否解密。所以只需要设置AB的加载方式名称结尾带有Quick Decrypt 和 Decrypt都会自带加密解密功能。使用的加密算法分别为GameFramework.Utility.Encryption.GetQuickXorBytes();GameFramework.Utility.Encryption.GetXorBytes();
自定义加密解密:
加密AB:
首先在AB编辑器中,设置所有AB包的加载方式为Load From Memory,此方式会走LoadResourceAgentHelper的ParseBytes(byte[] bytes)方法,需重写此方法处理解密逻辑;
自定义一个编辑器类AssetBuildHandler : IBuildEventHandler, 继承IBuildEventHandler,实现OnPostprocessPlatform接口,工具打包出AB文件后会回调此方法,在方法中遍历加密AB文件;
- public void OnPostprocessPlatform(Platform platform, string workingPath, bool outputPackageSelected, string outputPackagePath, bool outputFullSelected, string outputFullPath, bool outputPackedSelected, string outputPackedPath, bool isSuccess)
- {
- string targetPath = string.Empty;
- bool copyToStreamingAssets = false;
- if (outputPackageSelected)
- {
- targetPath = outputPackagePath;
- copyToStreamingAssets = true;
- }
- else if (outputPackedSelected)
- {
- targetPath = outputPackedPath;
- copyToStreamingAssets = true;
- }
- else if (outputFullSelected)
- {
- targetPath = outputFullPath;
- }
- if (string.IsNullOrEmpty(targetPath))
- {
- Debug.LogErrorFormat("targetPath is null.");
- return;
- }
- string[] fileNames = Directory.GetFiles(targetPath, "*", SearchOption.AllDirectories);
- string streamingAssetsPath = Path.Combine(Application.dataPath, "StreamingAssets");
- foreach (string fileName in fileNames)
- {
- var abAssetName = fileName.Substring(targetPath.Length);
- string destFileName = Path.Combine(streamingAssetsPath, abAssetName);
- FileInfo destFileInfo = new FileInfo(destFileName);
- if (!destFileInfo.Directory.Exists)
- {
- destFileInfo.Directory.Create();
- }
- //GameFrameworkVersion.dat和GameFrameworkList.dat不能加密
- if (ConstBuiltin.IsEncrypt && !abAssetName.StartsWith("GameFrameworkVersion.") && !abAssetName.StartsWith("GameFrameworkList."))
- {
- EncryptFile(fileName);
- }
-
- if (copyToStreamingAssets) File.Copy(fileName, destFileName);
- }
- if (isSuccess)
- {
- if (outputFullSelected || outputFullSelected)
- {
- EditorUtility.RevealInFinder(targetPath);
- }
- }
- }
-
- private void EncryptFile(string resFile)
- {
- var data_bytes = File.ReadAllBytes(resFile);
- data_bytes = UtilityBuiltin.XOR.QuickXor(data_bytes, ConstBuiltin.RES_KEY);
- File.WriteAllBytes(resFile, data_bytes);
- }
在AB包Build工具界面选择自己定义的AssetBuildHandler,然后打包即可:
解密:
自定义EncryptLoadResourceAgentHelper继承DefaultLoadResourceAgentHelper,重写ParseBytes(byte[] bytes)方法;
由于前面AB包选择了加载方式为Load From Memory,所以会走ParseBytes方法,然后处理解密即可。
-
- using GameFramework.FileSystem;
- using UnityEngine;
- using UnityGameFramework.Runtime;
- public class EncryptLoadResourceAgentHelper : DefaultLoadResourceAgentHelper
- {
- public override void ParseBytes(byte[] bytes)
- {
- if (ConstBuiltin.IsEncrypt)
- {
- bytes = UtilityBuiltin.XOR.QuickXor(bytes, ConstBuiltin.RES_KEY);
- }
-
- base.ParseBytes(bytes);
- }
- }