diff --git a/UnityProject/Assets/TEngine/Editor/Inspector/ResourceModuleDriverInspector.cs b/UnityProject/Assets/TEngine/Editor/Inspector/ResourceModuleDriverInspector.cs
index 9f5b93e9..0d524d5c 100644
--- a/UnityProject/Assets/TEngine/Editor/Inspector/ResourceModuleDriverInspector.cs
+++ b/UnityProject/Assets/TEngine/Editor/Inspector/ResourceModuleDriverInspector.cs
@@ -17,6 +17,7 @@ namespace TEngine.Editor.Inspector
};
private SerializedProperty _playMode = null;
+ private SerializedProperty _encryptionType = null;
private SerializedProperty _updatableWhilePlaying = null;
private SerializedProperty _milliseconds = null;
private SerializedProperty _minUnloadUnusedAssetsInterval = null;
@@ -56,6 +57,8 @@ namespace TEngine.Editor.Inspector
_playMode.enumValueIndex = selectedIndex;
}
}
+
+ EditorGUILayout.PropertyField(_encryptionType);
}
EditorGUILayout.PropertyField(_updatableWhilePlaying);
@@ -220,6 +223,7 @@ namespace TEngine.Editor.Inspector
private void OnEnable()
{
_playMode = serializedObject.FindProperty("playMode");
+ _encryptionType = serializedObject.FindProperty("encryptionType");
_updatableWhilePlaying = serializedObject.FindProperty("updatableWhilePlaying");
_milliseconds = serializedObject.FindProperty("milliseconds");
_minUnloadUnusedAssetsInterval = serializedObject.FindProperty("minUnloadUnusedAssetsInterval");
diff --git a/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/EncryptionType.cs b/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/EncryptionType.cs
new file mode 100644
index 00000000..1bef99ca
--- /dev/null
+++ b/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/EncryptionType.cs
@@ -0,0 +1,27 @@
+namespace TEngine
+{
+ ///
+ /// 资源模块的加密类型枚举。
+ /// 用于定义资源加载时的不同加密方式。
+ ///
+ public enum EncryptionType
+ {
+ ///
+ /// 无加密。
+ /// 资源将以原始形式加载,不进行任何加密处理。
+ ///
+ None,
+
+ ///
+ /// 文件偏移加密。
+ /// 通过在文件开头添加偏移量来隐藏真实文件内容的加密方式。
+ ///
+ FileOffSet,
+
+ ///
+ /// 文件流加密。
+ /// 使用加密流对文件内容进行加密处理的加密方式。
+ ///
+ FileStream,
+ }
+}
\ No newline at end of file
diff --git a/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/EncryptionType.cs.meta b/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/EncryptionType.cs.meta
new file mode 100644
index 00000000..23f5acfc
--- /dev/null
+++ b/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/EncryptionType.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 18468bde9ea948729cd7eab8a2d6e598
+timeCreated: 1742356779
\ No newline at end of file
diff --git a/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/IResourceModule.cs b/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/IResourceModule.cs
index b1bfefb5..13139a41 100644
--- a/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/IResourceModule.cs
+++ b/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/IResourceModule.cs
@@ -25,6 +25,11 @@ namespace TEngine
/// 获取或设置运行模式。
///
EPlayMode PlayMode { get; set; }
+
+ ///
+ /// 资源加密方式。
+ ///
+ EncryptionType EncryptionType { get; set; }
///
/// 是否边玩边下载。
diff --git a/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/ResourceModule.Services.cs b/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/ResourceModule.Services.cs
index 63342075..2b9aea16 100644
--- a/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/ResourceModule.Services.cs
+++ b/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/ResourceModule.Services.cs
@@ -179,6 +179,55 @@ namespace TEngine
return 32;
}
}
+
+
+ #region WebDecryptionServices
+ ///
+ /// 资源文件偏移加载解密类
+ ///
+ public class FileOffsetWebDecryption : IWebDecryptionServices
+ {
+ public WebDecryptResult LoadAssetBundle(WebDecryptFileInfo fileInfo)
+ {
+ int offset = GetFileOffset();
+ byte[] decryptedData = new byte[fileInfo.FileData.Length - offset];
+ Buffer.BlockCopy(fileInfo.FileData, offset, decryptedData, 0, decryptedData.Length);
+ // 从内存中加载AssetBundle
+ WebDecryptResult decryptResult = new WebDecryptResult();
+ decryptResult.Result = AssetBundle.LoadFromMemory(decryptedData);
+ return decryptResult;
+ }
+
+ private static int GetFileOffset()
+ {
+ return 32;
+ }
+ }
+
+ public class FileStreamWebDecryption : IWebDecryptionServices
+ {
+ public WebDecryptResult LoadAssetBundle(WebDecryptFileInfo fileInfo)
+ {
+ // 优化:使用Buffer批量操作替代逐字节异或
+ byte[] decryptedData = new byte[fileInfo.FileData.Length];
+ Buffer.BlockCopy(fileInfo.FileData, 0, decryptedData, 0, fileInfo.FileData.Length);
+
+ // 批量异或解密(性能优化)
+ int batchSize = sizeof(ulong);
+ int length = decryptedData.Length / batchSize * batchSize;
+ for (int i = 0; i < length; i += batchSize)
+ {
+ ulong value = BitConverter.ToUInt64(decryptedData, i);
+ value ^= BundleStream.KEY;
+ Buffer.BlockCopy(BitConverter.GetBytes(value), 0, decryptedData, i, batchSize);
+ }
+
+ WebDecryptResult decryptResult = new WebDecryptResult();
+ decryptResult.Result = AssetBundle.LoadFromMemory(decryptedData);
+ return decryptResult;
+ }
+ }
+ #endregion
}
///
@@ -200,9 +249,14 @@ public class BundleStream : FileStream
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++)
+ // 批量异或解密(性能优化)
+ int batchSize = sizeof(ulong);
+ int length = array.Length / batchSize * batchSize;
+ for (int i = 0; i < length; i += batchSize)
{
- array[i] ^= KEY;
+ ulong value = BitConverter.ToUInt64(array, i);
+ value ^= BundleStream.KEY;
+ Buffer.BlockCopy(BitConverter.GetBytes(value), 0, array, i, batchSize);
}
return index;
diff --git a/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/ResourceModule.cs b/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/ResourceModule.cs
index 41fa6d5c..bc0bd3e4 100644
--- a/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/ResourceModule.cs
+++ b/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/ResourceModule.cs
@@ -5,6 +5,9 @@ using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
using YooAsset;
+#if UNITY_WEBGL && WEIXINMINIGAME && !UNITY_EDITOR
+using WeChatWASM;
+#endif
namespace TEngine
{
@@ -22,6 +25,8 @@ namespace TEngine
/// 资源系统运行模式。
///
public EPlayMode PlayMode { get; set; } = EPlayMode.OfflinePlayMode;
+
+ public EncryptionType EncryptionType { get; set; } = EncryptionType.None;
///
/// 设置异步系统参数,每帧执行消耗的最大时间切片(单位:毫秒)
@@ -164,12 +169,14 @@ namespace TEngine
createParameters.EditorFileSystemParameters = FileSystemParameters.CreateDefaultEditorFileSystemParameters(packageRoot);
initializationOperation = package.InitializeAsync(createParameters);
}
-
+
+ IDecryptionServices decryptionServices = CreateDecryptionServices();
+
// 单机运行模式
if (playMode == EPlayMode.OfflinePlayMode)
{
var createParameters = new OfflinePlayModeParameters();
- createParameters.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();
+ createParameters.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(decryptionServices);
initializationOperation = package.InitializeAsync(createParameters);
}
@@ -180,8 +187,8 @@ namespace TEngine
string fallbackHostServer = FallbackHostServerURL;
IRemoteServices remoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
var createParameters = new HostPlayModeParameters();
- createParameters.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();
- createParameters.CacheFileSystemParameters = FileSystemParameters.CreateDefaultCacheFileSystemParameters(remoteServices);
+ createParameters.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(decryptionServices);
+ createParameters.CacheFileSystemParameters = FileSystemParameters.CreateDefaultCacheFileSystemParameters(remoteServices, decryptionServices);
initializationOperation = package.InitializeAsync(createParameters);
}
@@ -190,10 +197,14 @@ namespace TEngine
{
var createParameters = new WebPlayModeParameters();
#if UNITY_WEBGL && WEIXINMINIGAME && !UNITY_EDITOR
+ IWebDecryptionServices webDecryptionServices = CreateWebDecryptionServices();
+
+ // 注意:如果有子目录,请修改此处!
+ string packageRoot = $"{WeChatWASM.WX.env.USER_DATA_PATH}/__GAME_FILE_CACHE";
string defaultHostServer = HostServerURL;
string fallbackHostServer = FallbackHostServerURL;
IRemoteServices remoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
- createParameters.WebServerFileSystemParameters = WechatFileSystemCreater.CreateWechatFileSystemParameters(remoteServices);
+ createParameters.WebServerFileSystemParameters = WechatFileSystemCreater.CreateFileSystemParameters(packageRoot, remoteServices, webDecryptionServices);
#else
createParameters.WebServerFileSystemParameters = FileSystemParameters.CreateDefaultWebServerFileSystemParameters();
#endif
@@ -207,6 +218,32 @@ namespace TEngine
return initializationOperation;
}
+ ///
+ /// 创建解密服务。
+ ///
+ private IDecryptionServices CreateDecryptionServices()
+ {
+ return EncryptionType switch
+ {
+ EncryptionType.FileOffSet => new FileOffsetDecryption(),
+ EncryptionType.FileStream => new FileStreamDecryption(),
+ _ => null
+ };
+ }
+
+ ///
+ /// 创建Web解密服务。
+ ///
+ private IWebDecryptionServices CreateWebDecryptionServices()
+ {
+ return EncryptionType switch
+ {
+ EncryptionType.FileOffSet => new FileOffsetWebDecryption(),
+ EncryptionType.FileStream => new FileStreamWebDecryption(),
+ _ => null
+ };
+ }
+
///
/// 获取当前资源包版本。
///
diff --git a/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/ResourceModuleDriver.cs b/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/ResourceModuleDriver.cs
index 1b9cd83b..edc7b789 100644
--- a/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/ResourceModuleDriver.cs
+++ b/UnityProject/Assets/TEngine/Runtime/Module/ResourceModule/ResourceModuleDriver.cs
@@ -89,6 +89,14 @@ namespace TEngine
#endif
}
}
+
+ [SerializeField]
+ private EncryptionType encryptionType = EncryptionType.None;
+
+ ///
+ /// 资源模块的加密类型。
+ ///
+ public EncryptionType EncryptionType => encryptionType;
///
/// 是否支持边玩边下载。
@@ -238,6 +246,7 @@ namespace TEngine
_resourceModule.DefaultPackageName = PackageName;
_resourceModule.PlayMode = PlayMode;
+ _resourceModule.EncryptionType = encryptionType;
_resourceModule.Milliseconds = milliseconds;
_resourceModule.HostServerURL = Settings.UpdateSetting.GetResDownLoadPath();
_resourceModule.FallbackHostServerURL = Settings.UpdateSetting.GetFallbackResDownLoadPath();
diff --git a/UnityProject/Assets/TEngine/Runtime/TEngine.Runtime.asmdef b/UnityProject/Assets/TEngine/Runtime/TEngine.Runtime.asmdef
index a8a92395..69d2ab01 100644
--- a/UnityProject/Assets/TEngine/Runtime/TEngine.Runtime.asmdef
+++ b/UnityProject/Assets/TEngine/Runtime/TEngine.Runtime.asmdef
@@ -4,7 +4,8 @@
"references": [
"GUID:e34a5702dd353724aa315fb8011f08c3",
"GUID:f51ebe6a0ceec4240a699833d6309b23",
- "GUID:6055be8ebefd69e48b49212b09b47b2f"
+ "GUID:6055be8ebefd69e48b49212b09b47b2f",
+ "GUID:5efd170ecd8084500bed5692932fe14e"
],
"includePlatforms": [],
"excludePlatforms": [],