15 · 加密与发布
本章讲解如何用 SDK 加密资源并发布游戏到各平台。
即解即用加密
灵泛引擎的加密方案是即解即用——资源保持散文件部署,读取时检测加密头并按需解密。
LFEN 格式
加密后的文件使用 LFEN 格式:
LFEN(4字节魔数) | 版本(1) | nonce(12) | tag(16) | 密文- 加密算法:AES-256-GCM
- 每个文件独立 nonce,防重放攻击
- 读取时自动检测 LFEN 魔数头,加密则解密,不加密则直接使用
加密范围
按文件类型勾选加密,不是全量加密:
| 类型 | 是否加密 | 说明 |
|---|---|---|
.story | ✅ 推荐 | 剧本源码,最需要保护 |
.png / .jpg | 可选 | 图片资源 |
.wav / .mp3 | 可选 | 音频资源 |
.mp4 | 可选 | 视频 |
.dll / .exe | ❌ | 二进制不需要(.NET 自有保护) |
全类型可加密
引擎支持全类型文件加密。你可以根据需求勾选——只加密 .story,或加密所有资源。
SDK 发布流程
1. 打开构建页
在 SDK 中打开项目,点击左侧「构建」。
2. 配置加密
| 配置项 | 说明 |
|---|---|
| 资源加密总开关 | 开启后按文件类型勾选 |
| 文件类型勾选 | 勾选要加密的扩展名 |
| 密钥分片数 | 1~8,默认 1(分片存储增加逆向难度) |
3. 选择平台
选择目标平台对应的 .csproj:
| 平台 | 项目后缀 |
|---|---|
| Windows | .Desktop.Windows.csproj |
| Linux | .Desktop.Linux.csproj |
| macOS | .Desktop.Mac.csproj |
| Android | .Android.csproj |
| iOS | .iOS.csproj |
| Browser | .Browser.csproj |
4. 构建
SDK 自动执行:
- 杀掉项目目录下运行的进程(防 PDB 锁定)
- 生成
GeneratedKeys.cs(密钥,放核心项目Security/目录) dotnet publish平台项目- 原地加密
Stories/和Media/中的指定文件 - 生成
manifest.lfmanifest(清单)
密钥注入
GeneratedKeys.cs
SDK 的 KeyInjector 自动生成密钥文件:
csharp
// Security/GeneratedKeys.cs(自动生成,不要手动编辑)
namespace MyGame.Security;
public class GeneratedKeyProvider : IEncryptionKeyProvider
{
private static readonly byte[] _combined = new byte[] { ... };
public byte[]? GetKey() => GetKeyArray();
public static ReadOnlySpan<byte> GetKey() => _combined;
public static byte[] GetKeyArray() => _combined;
}密钥分片
分片数 > 1 时,密钥被拆分存储在多个位置,静态构造函数合并:
csharp
// 分片 1
private static readonly byte[] _s1 = new byte[] { 0xAB, 0xCD, ... };
// 分片 2
private static readonly byte[] _s2 = new byte[] { 0xEF, 0x12, ... };
static GeneratedKeyProvider()
{
_combined = new byte[_s1.Length + _s2.Length];
_s1.CopyTo(_combined, 0);
_s2.CopyTo(_combined, _s1.Length);
}分片的作用
分片不增加加密强度,但增加逆向工程难度——密钥碎片散布在代码中,不容易一次性提取。
DI 注册
在 ServiceExtensions.cs 中注册密钥提供者:
csharp
public static IServiceCollection AddGameSecurity(this IServiceCollection services)
{
services.AddSingleton<IEncryptionKeyProvider, GeneratedKeyProvider>();
return services;
}发布产物
publish/
├── MyGame.exe # 可执行文件
├── LingFanEngine.dll # 引擎 DLL
├── Stories/ # 剧本(部分已加密)
│ ├── title/
│ │ └── title_main.story ← LFEN 格式
│ └── chapter1/
├── Media/ # 媒体资源(部分已加密)
│ ├── Images/
│ └── Audio/
├── manifest.lfmanifest # 加密清单
└── *.dll # 其他依赖散文件部署
引擎不打包资源。Stories/ 和 Media/ 保持散文件结构。这让补丁更新很简单——只需替换改动的文件。
跨平台发布
Windows
bash
dotnet publish -c Release -r win-x64
dotnet publish -c Release -r win-arm64macOS
bash
dotnet publish -c Release -r osx-arm64 # Apple Silicon
dotnet publish -c Release -r osx-x64 # IntelLinux
bash
dotnet publish -c Release -r linux-x64Android / iOS / Browser
需要对应的平台项目,SDK 会自动处理依赖和配置。
AOT 编译
灵泛引擎完全 AOT 友好。启用 AOT 获得更快启动和更低内存:
xml
<!-- 在平台 .csproj 中 -->
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>AOT 注意事项
- 禁止反射和动态代码生成
- JSON 序列化用 source generator(引擎已内置)
- 第三方库需确认 AOT 兼容
补丁更新
由于散文件部署,补丁更新很简单:
- 替换改动的
.story/.png/.wav文件 - 如果启用了加密,新文件也需要用相同密钥加密
- 更新
manifest.lfmanifest
玩家只需下载增量文件,不需要重新下载整个游戏。
动手练习
发布你的第一个游戏:
- 在 SDK 中打开项目
- 点击「构建」
- 开启资源加密,勾选
.story - 选择 Windows 平台
- 点击构建
- 在
bin/Release/下找到发布产物 - 运行
MyGame.exe验证
下一步
所有功能都学完了!最后一章完整作品将组装一个完整的示例游戏。