☰
深入Sunrise架构:客户端钩子、协议中间件、本地服务器与持久化状态的四层设计
2026/10/13 9:45:23 网站建设 项目流程

【免费下载链接】Sunrise

Destiny 2 Offline Preservation Mod

项目地址:https://gitcode.com/gh_mirrors/sunrise16/Sunrise
点击查看免费下载

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 中特别强调"所有游戏数据都在运行时从本机提取",正体现了这一层的设计约束:仓库内不含任何版权数据,状态层只做读写,不打包内容。

四层如何串成一次完整的调用 🔁

以"进入游戏目的地"为例,链路是典型的四层协作:

  1. 客户端钩子在游戏内部触发活动选择流程,出站帧被出口防护层拦截;
  2. 本地服务器的回环监听器收到 BAP 请求帧,路由到server/bap/的活动权威逻辑;
  3. 中间件完成帧解码、校验与响应编码,全程使用进程内密钥,无需真实握手;
  4. 服务器将新活动会话写回状态层,客户端收到响应后继续游戏,下次启动时该记录仍可从持久化存储恢复。

想动手跟踪这条链路,建议从 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

项目地址:https://gitcode.com/gh_mirrors/sunrise16/Sunrise
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询