mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
增加MiniGameFileSystem的支持,增加EncryptType的解密枚举类型,以及ResourceModule解密方法实现
增加MiniGameFileSystem的支持,增加EncryptType的解密枚举类型,以及ResourceModule解密方法实现
This commit is contained in:
@@ -17,6 +17,7 @@ namespace TEngine.Editor.Inspector
|
|||||||
};
|
};
|
||||||
|
|
||||||
private SerializedProperty _playMode = null;
|
private SerializedProperty _playMode = null;
|
||||||
|
private SerializedProperty _encryptionType = null;
|
||||||
private SerializedProperty _updatableWhilePlaying = null;
|
private SerializedProperty _updatableWhilePlaying = null;
|
||||||
private SerializedProperty _milliseconds = null;
|
private SerializedProperty _milliseconds = null;
|
||||||
private SerializedProperty _minUnloadUnusedAssetsInterval = null;
|
private SerializedProperty _minUnloadUnusedAssetsInterval = null;
|
||||||
@@ -56,6 +57,8 @@ namespace TEngine.Editor.Inspector
|
|||||||
_playMode.enumValueIndex = selectedIndex;
|
_playMode.enumValueIndex = selectedIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.PropertyField(_encryptionType);
|
||||||
}
|
}
|
||||||
EditorGUILayout.PropertyField(_updatableWhilePlaying);
|
EditorGUILayout.PropertyField(_updatableWhilePlaying);
|
||||||
|
|
||||||
@@ -220,6 +223,7 @@ namespace TEngine.Editor.Inspector
|
|||||||
private void OnEnable()
|
private void OnEnable()
|
||||||
{
|
{
|
||||||
_playMode = serializedObject.FindProperty("playMode");
|
_playMode = serializedObject.FindProperty("playMode");
|
||||||
|
_encryptionType = serializedObject.FindProperty("encryptionType");
|
||||||
_updatableWhilePlaying = serializedObject.FindProperty("updatableWhilePlaying");
|
_updatableWhilePlaying = serializedObject.FindProperty("updatableWhilePlaying");
|
||||||
_milliseconds = serializedObject.FindProperty("milliseconds");
|
_milliseconds = serializedObject.FindProperty("milliseconds");
|
||||||
_minUnloadUnusedAssetsInterval = serializedObject.FindProperty("minUnloadUnusedAssetsInterval");
|
_minUnloadUnusedAssetsInterval = serializedObject.FindProperty("minUnloadUnusedAssetsInterval");
|
||||||
|
@@ -0,0 +1,27 @@
|
|||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 资源模块的加密类型枚举。
|
||||||
|
/// <remarks>用于定义资源加载时的不同加密方式。</remarks>
|
||||||
|
/// </summary>
|
||||||
|
public enum EncryptionType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 无加密。
|
||||||
|
/// <remarks>资源将以原始形式加载,不进行任何加密处理。</remarks>
|
||||||
|
/// </summary>
|
||||||
|
None,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 文件偏移加密。
|
||||||
|
/// <remarks>通过在文件开头添加偏移量来隐藏真实文件内容的加密方式。</remarks>
|
||||||
|
/// </summary>
|
||||||
|
FileOffSet,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 文件流加密。
|
||||||
|
/// <remarks>使用加密流对文件内容进行加密处理的加密方式。</remarks>
|
||||||
|
/// </summary>
|
||||||
|
FileStream,
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 18468bde9ea948729cd7eab8a2d6e598
|
||||||
|
timeCreated: 1742356779
|
@@ -25,6 +25,11 @@ namespace TEngine
|
|||||||
/// 获取或设置运行模式。
|
/// 获取或设置运行模式。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
EPlayMode PlayMode { get; set; }
|
EPlayMode PlayMode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源加密方式。
|
||||||
|
/// </summary>
|
||||||
|
EncryptionType EncryptionType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否边玩边下载。
|
/// 是否边玩边下载。
|
||||||
|
@@ -179,6 +179,55 @@ namespace TEngine
|
|||||||
return 32;
|
return 32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region WebDecryptionServices
|
||||||
|
/// <summary>
|
||||||
|
/// 资源文件偏移加载解密类
|
||||||
|
/// </summary>
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -200,9 +249,14 @@ public class BundleStream : FileStream
|
|||||||
public override int Read(byte[] array, int offset, int count)
|
public override int Read(byte[] array, int offset, int count)
|
||||||
{
|
{
|
||||||
var index = base.Read(array, offset, 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;
|
return index;
|
||||||
|
@@ -5,6 +5,9 @@ using System.Threading;
|
|||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using YooAsset;
|
using YooAsset;
|
||||||
|
#if UNITY_WEBGL && WEIXINMINIGAME && !UNITY_EDITOR
|
||||||
|
using WeChatWASM;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace TEngine
|
namespace TEngine
|
||||||
{
|
{
|
||||||
@@ -22,6 +25,8 @@ namespace TEngine
|
|||||||
/// 资源系统运行模式。
|
/// 资源系统运行模式。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public EPlayMode PlayMode { get; set; } = EPlayMode.OfflinePlayMode;
|
public EPlayMode PlayMode { get; set; } = EPlayMode.OfflinePlayMode;
|
||||||
|
|
||||||
|
public EncryptionType EncryptionType { get; set; } = EncryptionType.None;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置异步系统参数,每帧执行消耗的最大时间切片(单位:毫秒)
|
/// 设置异步系统参数,每帧执行消耗的最大时间切片(单位:毫秒)
|
||||||
@@ -164,12 +169,14 @@ namespace TEngine
|
|||||||
createParameters.EditorFileSystemParameters = FileSystemParameters.CreateDefaultEditorFileSystemParameters(packageRoot);
|
createParameters.EditorFileSystemParameters = FileSystemParameters.CreateDefaultEditorFileSystemParameters(packageRoot);
|
||||||
initializationOperation = package.InitializeAsync(createParameters);
|
initializationOperation = package.InitializeAsync(createParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IDecryptionServices decryptionServices = CreateDecryptionServices();
|
||||||
|
|
||||||
// 单机运行模式
|
// 单机运行模式
|
||||||
if (playMode == EPlayMode.OfflinePlayMode)
|
if (playMode == EPlayMode.OfflinePlayMode)
|
||||||
{
|
{
|
||||||
var createParameters = new OfflinePlayModeParameters();
|
var createParameters = new OfflinePlayModeParameters();
|
||||||
createParameters.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();
|
createParameters.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(decryptionServices);
|
||||||
initializationOperation = package.InitializeAsync(createParameters);
|
initializationOperation = package.InitializeAsync(createParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,8 +187,8 @@ namespace TEngine
|
|||||||
string fallbackHostServer = FallbackHostServerURL;
|
string fallbackHostServer = FallbackHostServerURL;
|
||||||
IRemoteServices remoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
|
IRemoteServices remoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
|
||||||
var createParameters = new HostPlayModeParameters();
|
var createParameters = new HostPlayModeParameters();
|
||||||
createParameters.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();
|
createParameters.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(decryptionServices);
|
||||||
createParameters.CacheFileSystemParameters = FileSystemParameters.CreateDefaultCacheFileSystemParameters(remoteServices);
|
createParameters.CacheFileSystemParameters = FileSystemParameters.CreateDefaultCacheFileSystemParameters(remoteServices, decryptionServices);
|
||||||
initializationOperation = package.InitializeAsync(createParameters);
|
initializationOperation = package.InitializeAsync(createParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,10 +197,14 @@ namespace TEngine
|
|||||||
{
|
{
|
||||||
var createParameters = new WebPlayModeParameters();
|
var createParameters = new WebPlayModeParameters();
|
||||||
#if UNITY_WEBGL && WEIXINMINIGAME && !UNITY_EDITOR
|
#if UNITY_WEBGL && WEIXINMINIGAME && !UNITY_EDITOR
|
||||||
|
IWebDecryptionServices webDecryptionServices = CreateWebDecryptionServices();
|
||||||
|
|
||||||
|
// 注意:如果有子目录,请修改此处!
|
||||||
|
string packageRoot = $"{WeChatWASM.WX.env.USER_DATA_PATH}/__GAME_FILE_CACHE";
|
||||||
string defaultHostServer = HostServerURL;
|
string defaultHostServer = HostServerURL;
|
||||||
string fallbackHostServer = FallbackHostServerURL;
|
string fallbackHostServer = FallbackHostServerURL;
|
||||||
IRemoteServices remoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
|
IRemoteServices remoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
|
||||||
createParameters.WebServerFileSystemParameters = WechatFileSystemCreater.CreateWechatFileSystemParameters(remoteServices);
|
createParameters.WebServerFileSystemParameters = WechatFileSystemCreater.CreateFileSystemParameters(packageRoot, remoteServices, webDecryptionServices);
|
||||||
#else
|
#else
|
||||||
createParameters.WebServerFileSystemParameters = FileSystemParameters.CreateDefaultWebServerFileSystemParameters();
|
createParameters.WebServerFileSystemParameters = FileSystemParameters.CreateDefaultWebServerFileSystemParameters();
|
||||||
#endif
|
#endif
|
||||||
@@ -207,6 +218,32 @@ namespace TEngine
|
|||||||
return initializationOperation;
|
return initializationOperation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建解密服务。
|
||||||
|
/// </summary>
|
||||||
|
private IDecryptionServices CreateDecryptionServices()
|
||||||
|
{
|
||||||
|
return EncryptionType switch
|
||||||
|
{
|
||||||
|
EncryptionType.FileOffSet => new FileOffsetDecryption(),
|
||||||
|
EncryptionType.FileStream => new FileStreamDecryption(),
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建Web解密服务。
|
||||||
|
/// </summary>
|
||||||
|
private IWebDecryptionServices CreateWebDecryptionServices()
|
||||||
|
{
|
||||||
|
return EncryptionType switch
|
||||||
|
{
|
||||||
|
EncryptionType.FileOffSet => new FileOffsetWebDecryption(),
|
||||||
|
EncryptionType.FileStream => new FileStreamWebDecryption(),
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取当前资源包版本。
|
/// 获取当前资源包版本。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@@ -89,6 +89,14 @@ namespace TEngine
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private EncryptionType encryptionType = EncryptionType.None;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源模块的加密类型。
|
||||||
|
/// </summary>
|
||||||
|
public EncryptionType EncryptionType => encryptionType;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否支持边玩边下载。
|
/// 是否支持边玩边下载。
|
||||||
@@ -238,6 +246,7 @@ namespace TEngine
|
|||||||
|
|
||||||
_resourceModule.DefaultPackageName = PackageName;
|
_resourceModule.DefaultPackageName = PackageName;
|
||||||
_resourceModule.PlayMode = PlayMode;
|
_resourceModule.PlayMode = PlayMode;
|
||||||
|
_resourceModule.EncryptionType = encryptionType;
|
||||||
_resourceModule.Milliseconds = milliseconds;
|
_resourceModule.Milliseconds = milliseconds;
|
||||||
_resourceModule.HostServerURL = Settings.UpdateSetting.GetResDownLoadPath();
|
_resourceModule.HostServerURL = Settings.UpdateSetting.GetResDownLoadPath();
|
||||||
_resourceModule.FallbackHostServerURL = Settings.UpdateSetting.GetFallbackResDownLoadPath();
|
_resourceModule.FallbackHostServerURL = Settings.UpdateSetting.GetFallbackResDownLoadPath();
|
||||||
|
@@ -4,7 +4,8 @@
|
|||||||
"references": [
|
"references": [
|
||||||
"GUID:e34a5702dd353724aa315fb8011f08c3",
|
"GUID:e34a5702dd353724aa315fb8011f08c3",
|
||||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||||
"GUID:6055be8ebefd69e48b49212b09b47b2f"
|
"GUID:6055be8ebefd69e48b49212b09b47b2f",
|
||||||
|
"GUID:5efd170ecd8084500bed5692932fe14e"
|
||||||
],
|
],
|
||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
|
Reference in New Issue
Block a user