【免费下载链接】Sunrise
Destiny 2 Offline Preservation Mod
Sunrise 是一款面向老版本《Destiny 2》的离线保存 Mod(Destiny 2 Offline Preservation Mod),它把游戏装进一个本地运行的四层架构中:客户端钩子接管游戏进程,协议中间件复刻官方 BAP 通信层,本地服务器在进程内应答网络请求,持久化状态层则负责存档与账号数据的落盘。理解 Sunrise 架构,就是理解这四层如何协同让游戏完全离线运行。
一张表看懂 Sunrise 的四层架构 🗺️
| 层级 | 职责 | 核心目录 |
|---|---|---|
| 客户端钩子层 | 注入游戏进程,接管图形、网络、输入等关键调用 | Sunrise/src/client/hooks/ |
| 协议中间件层 | 解析与编码 BAP 帧、加解密、SignOn 认证 | Sunrise/src/middleware/ |
| 本地服务器层 | 进程内回环监听,应答活动、Web Service 等请求 | Sunrise/src/server/ |
| 持久化状态层 | 账号、投资进度、解锁记录等数据读写 | Sunrise/src/state/ |
入口文件 Sunrise/src/dllmain.cpp 暴露了整套生命周期的三个导出函数:SunriseInitialize(安装出口防护并初始化核心)、SunriseActivateClient(激活客户端钩子)、SunriseShutdown(干净退出),并附带一组SteamAPI_*兼容导出,为游戏提供进程内的 Steam 兼容运行时。
第一层:客户端钩子如何接管游戏进程
钩子层是 Sunrise 与游戏进程接触的唯一面。核心逻辑集中在 Sunrise/src/client/runtime/client_runtime_lifecycle.cpp,其中initialize负责建立客户端进程状态,shutdown则按依赖顺序逐个卸载钩子(graphics → cursor → polled_input → world_objects → network…),并借助 Sunrise/src/core/logging/log.h 的结构化日志记录每一步的安装结果。
钩子按功能拆分为独立子模块,几个典型例子:
- 图形钩子:Sunrise/src/client/hooks/graphics/ 对 D3D11 呈现路径做 detour,是 ImGui 菜单的渲染基础,生命周期由 graphics_hook_lifecycle.h 管理;
- 网络出口防护:Sunrise/src/client/hooks/egress/ 拦截出站连接,保证 Mod 完全离线运行、不触达任何官方服务器;
- 玩法钩子:飞移(fly)、穿墙(noclip)、无限弹药、传送、闲置覆盖等,每个都是独立目录,便于单独开关与卸载。
这种"一个钩子一个模块"的划分,是新手阅读 Sunrise 源码时最好的切入点。
第二层:协议中间件复刻了官方通信栈 📡
游戏客户端原本要与 Bungie 的 BAP 网络服务通信,Sunrise 用 Sunrise/src/middleware/ 在本地完整复刻了这一通信栈:
- BAP 帧协议:frame.h 定义了外框编码(明文帧、AES-GCM 加密帧)以及
RequestService/ResponseService全量服务号表——从活动会话创建(activityHostManager)到 Web Service 请求,客户端发出的每一类请求都有对应编号; - 加密原语:
middleware/crypto/内聚了 AES-GCM、AES-CBC、HMAC、SHA256 等自实现算法,服务于安全通道与签名流程; - SignOn 与序列化:
middleware/signon/处理登录令牌,middleware/protobuf/与middleware/encoding/负责消息的序列化与位级编解码。
这一层的设计价值在于:中间件不关心请求"来自哪里",客户端与本地服务器只共享同一套帧编解码契约,天然可测试、可裁剪。
第三层:本地服务器在进程内应答一切 🖥️
既然不连接官方服务器,就要有人扮演"服务器"。Sunrise/src/server/ 实现的正是这个角色:
- server_runtime.h 只暴露
initialize/service/shutdown三个接口,service每帧被驱动一次有界切片,避免阻塞游戏主线程; - bap_listener.h 启动一个非阻塞回环(loopback)BAP 监听器,客户端发往"官方服务器"的帧最终落在这里;
server/bap/是请求路由核心,server/activity/承担活动与任务脚本的权威运行时,server/web_service/则应答 Web Service 请求。
这种"服务器同进程化"的架构,是 Sunrise 能做到零外部依赖、零账号验证的关键。
第四层:持久化状态层让存档真正落地 💾
Sunrise/src/state/ 是数据的家。进程内会话状态由 state/runtime/state.h 统一定义——SignOn 密钥与令牌、BAP 会话密钥、活动状态、匹配状态、Steam 状态各归其位;而需要跨启动保留的数据则落在持久化存储里:
state/account/:账号档案、设置、战利品清单;state/investment/:投资解锁、奖励与库存的数据库读写,启动逻辑见 investment_store_boot.cpp;state/build_data/:以结构化子目录(abilities、bounties、items、vendors 等)承载游戏构建数据的运行时视图;state/activity_sdk/:活动 SDK 的目录、加载器与校验逻辑,支撑"脚本化任务"这一核心功能。
README 中特别强调"所有游戏数据都在运行时从本机提取",正体现了这一层的设计约束:仓库内不含任何版权数据,状态层只做读写,不打包内容。
四层如何串成一次完整的调用 🔁
以"进入游戏目的地"为例,链路是典型的四层协作:
- 客户端钩子在游戏内部触发活动选择流程,出站帧被出口防护层拦截;
- 本地服务器的回环监听器收到 BAP 请求帧,路由到
server/bap/的活动权威逻辑; - 中间件完成帧解码、校验与响应编码,全程使用进程内密钥,无需真实握手;
- 服务器将新活动会话写回状态层,客户端收到响应后继续游戏,下次启动时该记录仍可从持久化存储恢复。
想动手跟踪这条链路,建议从 Sunrise/src/dllmain.cpp 的生命周期导出入手,再对照 client_runtime_lifecycle.cpp 与 server_runtime.h 的调用顺序。
上手指南:目录导航与构建 ⚙️
- 想读钩子:从
Sunrise/src/client/hooks/挑一个兴趣模块(如noclip/、fly/)看起,每个模块都有 lifecycle 文件说明安装与卸载; - 想读协议:精读 frame.h,配合
middleware/signon/理解认证流程; - 想读存档:从
Sunrise/src/state/investment/的 store 文件入手,注意"一个 store 一类数据"的划分; - 想编译:Windows 下用 Visual Studio 2026 打开 Sunrise.sln 构建 Release x64;Linux 下可用 linux-to-win-toolchain.cmake 交叉编译,CMakeLists.txt 定义了跨平台构建目标。
小结
Sunrise 架构的精髓在于边界清晰:钩子层不写业务、中间件层不写路由、服务器层不碰磁盘、状态层不懂协议。这种分层让一个"让在线游戏离线可玩"的复杂目标,变成了四个可独立理解、独立测试的模块。对想学习 Mod 开发、协议逆向或本地服务器设计的读者来说,Sunrise 源码(入口:Sunrise/src/)是一份相当完整的工程范本。
【免费下载链接】Sunrise
Destiny 2 Offline Preservation Mod
相关推荐
深入 Kaku 的 mux 层:Tab/Pane/Domain 状态管理与客户端-服务端协调架构指南
深入 Kaku 的 mux 层:Tab/Pane/Domain 状态管理与客户端 服务端协调架构指南 mux 是 Kaku(一个面向 AI 编码的 macOS
深入解析OPAL核心架构:掌握客户端-服务器无状态设计原理
深入解析OPAL核心架构:掌握客户端 服务器无状态设计原理 OPAL(Open Policy Administration Layer)是一个强大的策略和数据管
认证鉴权后端微服务API网关libSQL sqld 服务端架构设计解析:客户端/主服务器/副本服务器与 mvSQLite 后端的协同机制
libSQL sqld 服务端架构设计解析:客户端/主服务器/副本服务器与 mvSQLite 后端的协同机制 导读 本文以仓库内 docs/DESIGN.md
数据库关系型数据库嵌入式数据库后端数据同步
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考