31 KiB
ShrinkSDK 项目设计总结
生成日期:2026-08-16 依据:仓库源码(
Assets/Modules/、GeneratedServers/)、各模块package.json/README.md/CHANGELOG.md、.planning/threads/shrinksdkunity.md、NETWORK_PITFALLS.md,以及.planning/codebase/既有代码库地图(其中部分内容已滞后于当前代码,本文以源码现状为准)。
1. 项目定位
ShrinkSDK 是一个以 Unity 包(UPM)为边界的 SDK 单仓库,不是单个游戏项目。它为 Unity 游戏提供一整套可独立分发、可拼装组合的基础设施:
- 事件总线(ShrinkEventBus)
- 存档与设置(ShrinkDataSaver)
- 命令系统(ShrinkCommand)
- 网络框架与独立服务器生成(ShrinkNetwork + GeneratedServers)
- 模组框架(ShrinkModFramework,Forge 风格)
- 新手引导(ShrinkTutorial)
- 统一应用宿主与起盘 Starter(ShrinkApp.Core + ShrinkApp.Starter.Basic,最新一轮工作)
设计哲学贯穿全仓库:静态门面 + Attribute 声明式范式 + 编译期注册表 + asmdef 最小抽象 + 可选桥接包。不做重框架化(无 DI 容器、无第三方状态机),追求低侵入接入 Unity 项目。
2. 技术栈
| 项 | 值 |
|---|---|
| Unity 版本 | 2022.3(ProjectSettings/ProjectVersion.txt) |
| 语言 | C#(运行时与独立 .NET 宿主共用合同) |
| 异步 | UniTask 2.x(com.cysharp.unitask) |
| 序列化 | Newtonsoft.Json(com.unity.nuget.newtonsoft-json 3.2.2);网络层另支持 MessagePack-CSharp 3.1.4 |
| 编译织入 | Unity ILPostProcessing + Mono.Cecil |
| UI | uGUI + TextMeshPro |
| 渲染 | URP 14 |
| 网络 | 自研传输层:Loopback / TCP(含可选 TLS)/ KCP(Kcp-CSharp.dll) |
| 独立服务器 | .NET 8 控制台宿主(GeneratedServers/ShrinkNetwork.ServerHost) |
| 测试 | Unity Test Runner(NUnit,EditMode 为主) |
3. 仓库布局
ShrinkSDK/
├── Assets/Modules/ # 全部 SDK 模块(每个是独立 UPM 包 + asmdef)
│ ├── ShrinkEventBus/ # 事件总线(Runtime/Editor/CodeGen/Tests)
│ ├── ShrinkDataSaver/ # 存档与设置(Runtime/Editor/Tests)
│ ├── ShrinkCommand/ # 命令系统
│ ├── ShrinkNetwork/ # 网络框架(Core/Metadata/Routing/Serialization/Transport/Editor 脚手架)
│ ├── ShrinkModFramework/ # 模组框架(Bootstrap/Core/Metadata/Registry/Loading/Network/Integration)
│ ├── ShrinkTutorial/ # 新手引导(Core/Storage/Trigger/UI)
│ ├── ShrinkApp.Core/ # 统一应用宿主层
│ ├── ShrinkApp.Starter.Basic/ # 最小起盘 Starter
│ ├── ShrinkShared.CodeGen/ # 共享 IL 织入管线
│ └── *.Integration.EventBus / *.Integration.App # 模块间桥接包
├── Assets/Scenes/ # 示例/演示场景
├── GeneratedServers/ # 生成的独立 .NET 服务器工程(可重建,不手写业务)
├── GeneratedModSdk/ # 导出的 Mod SDK 开发包(Libs/Templates/manifest)
├── Servers/ # (当前为空)
├── Packages/manifest.json # UPM 依赖
├── ShrinkSDK.sln # 解决方案(含全部模块 csproj)
├── NETWORK_PITFALLS.md # 联网与事件桥接踩坑记录(19 条经验)
└── .planning/ # gsd 线程与代码库地图(部分滞后)
4. 模块清单与依赖关系
| 包名 | 版本 | 职责 | 关键依赖 |
|---|---|---|---|
com.cneicy.shrink-eventbus |
1.3.0 | 高性能类型安全事件总线,优先级调度与自动注册 | UniTask |
com.cneicy.shrink-datasaver |
2.2.0 | 模块化存档与设置:多槽位、链式迁移、AES 加密、双备份 | Newtonsoft, UniTask |
com.cneicy.shrink-datasaver-integration-eventbus |
2.1.0 | DataSaver 原生事件 → EventBus 桥接(9 个事件类型) | DataSaver, EventBus |
com.cneicy.shrink-datasaver-integration-app |
0.1.0 | DataSaver 初始化交给 ShrinkApp 宿主接管 | DataSaver, App.Core |
com.cneicy.shrink-command |
0.2.0 | 路径式命令系统(Minecraft/Brigadier 风格)、权限、来源判定 | UniTask |
com.cneicy.shrink-command-integration-eventbus |
0.1.1 | 事件请求执行命令 + 命令生命周期事件发布 | Command, EventBus |
com.cneicy.shrink-command-integration-network |
0.1.0 | command/execute RPC 远程执行命令 |
Command, Network |
com.cneicy.shrink-command-integration-app |
0.1.0 | 默认命令服务纳入宿主容器 | Command, App.Core |
com.cneicy.shrink-network |
0.2.0 | 会话、消息注册、RPC、权限、TCP/KCP/Loopback 传输 | UniTask, Newtonsoft |
com.cneicy.shrink-network-integration-eventbus |
0.1.1 | EventBase 事件直接走网络同步并在远端重分发 | Network, EventBus |
com.cneicy.shrink-network-integration-app |
0.1.0 | 默认网络服务纳入宿主容器 | Network, App.Core |
com.cneicy.shrink-mod-framework |
0.1.0 | 模组发现、依赖解析、生命周期、注册表、外部 DLL 热载、Harmony | Newtonsoft |
com.cneicy.shrink-tutorial |
0.1.0 | 数据驱动互动引导:遮罩挖洞、动态锚点、条件完成 | uGUI, TMP |
com.cneicy.shrink-app-core |
0.1.0 | 统一宿主:模块安装器、服务容器、统一启动流程 | EventBus, UniTask |
com.cneicy.shrink-app-starter-basic |
0.1.0 | 最小起盘:入口场景生成 + 五模块最小闭环调试台 | App.Core, Command, DataSaver, Network 及各自 Integration.App |
ShrinkShared.CodeGen(asmdef) |
— | 共享 IL 后处理器:四套编译期注册表 + EventBus 织入 | Cecil |
依赖层次(自底向上):
ShrinkShared.CodeGen(编译期,作用于 Command/Network/App 引用方程序集)
│
ShrinkEventBus ←── ShrinkDataSaver ←── DataSaver.Integration.EventBus
↑ (独立桥接,不依赖 App)
ShrinkNetwork ←── ShrinkCommand(经 Integration.Network 桥)
↑
ShrinkModFramework(Integration/ 胶水可选自动接入以上三者)
↑
ShrinkApp.Core(组合根)←── *.Integration.App(各模块安装器)
↑
ShrinkApp.Starter.Basic(起盘模板)
5. 总体架构
5.1 分层视图
┌──────────────────────────────────────────────────────────┐
│ Starter 层:ShrinkApp.Starter.Basic(场景/配置/UI 生成) │
├──────────────────────────────────────────────────────────┤
│ 组合根:ShrinkApp.Core(Host/Services/Installer 排序) │
├───────────────┬───────────────┬──────────────────────────┤
│ 功能模块: │ EventBus │ DataSaver │ Tutorial │
│ │ Command │ Network │ │
├───────────────┴───────────────┴──────────────────────────┤
│ 桥接层:*.Integration.EventBus / *.Integration.Network │
│ *.Integration.App(可选包,反射自动发现) │
├──────────────────────────────────────────────────────────┤
│ 扩展面:ShrinkModFramework(模组热载 + Harmony + 上述全) │
├──────────────────────────────────────────────────────────┤
│ 编译期:ShrinkShared.CodeGen(Cecil IL 织入/注册表注入) │
├──────────────────────────────────────────────────────────┤
│ 独立宿主:GeneratedServers/ShrinkNetwork.ServerHost(.NET)│
└──────────────────────────────────────────────────────────┘
5.2 四个横切设计模式(全仓库统一)
模式一:Attribute 声明式范式。 每个子系统用自己的特性声明能力,处理器/消息/命令/安装器都是 [Xxx] + 类型 的组合:[EventBusSubscriber]+[EventSubscribe]、[ShrinkNetworkMessage(opcode, route)]、[ShrinkNetworkSubscriber]+[ShrinkNetworkSubscribe]、[ShrinkCommand("say <message...>")]、[ShrinkMod(modId,...)]、[ShrinkAppModuleInstaller]。
模式二:编译期注册表取代全域反射。 ShrinkShared.CodeGen/Editor/ShrinkRegistryILPostProcessor.cs 是唯一的共享 IL 后处理器,对引用了 ShrinkCommand.Runtime / ShrinkNetwork.Runtime / ShrinkApp.Core.Runtime 的程序集做四件事:
InjectEventBusAutoRegister:给带[EventBusSubscriber]的 MonoBehaviour 织入Awake → EventBus.AutoRegister(this)与OnDestroy → UnregisterInstance(处理了继承基类 Awake/OnDestroy 的 base 调用)。InjectShrinkCommandRegistry:静态命令类型写入程序集级[ShrinkCommandStaticRegistry(typeof(...))]。InjectShrinkNetworkRegistry:[ShrinkNetworkMessage]消息类型与静态订阅者类型分别写入[ShrinkNetworkMessageRegistry]/[ShrinkNetworkStaticSubscriberRegistry]。InjectShrinkAppRegistry:[ShrinkAppModuleInstaller]安装器类型写入[ShrinkAppInstallerRegistry]。
运行时 AutoRegisterAll() 只读程序集特性,不做 AppDomain.GetAssemblies()+GetTypes() 全域扫描——这是模组外部 DLL 与独立服务器共用的关键机制(外来 DLL 不经过 Unity 编译管线,仍可走实例注册路径 RegisterHandlers(object) / RegisterCommands(object) 兜底)。注意织入器刻意不处理核心程序集自身(否则 Cecil 写回会触发 Unity "references itself" 拒载,源码注释中已记录该教训)。
模式三:静态门面 + 可实例化内核。 EventBus(静态门面)委托给 Builder 构建的 IShrinkEventBus 实例(默认 LogAndContinue + 按 phase 派发,可 CreateBus 多实例);ShrinkNetworkRuntime.Default / ShrinkCommandService 同理。使用方零成本拿到默认单例,高级场景可自建实例。
模式四:可选桥接包 + 运行时反射自动发现。 模块间集成全部做成独立小包(不污染主包依赖),并用反射探测"对方是否存在":ShrinkNetworkService.BindTransport(...) 自动接入 EventBus 桥(BindTransport(null) 解绑);ShrinkModFramework/Runtime/Integration/ShrinkModOptionalRuntimeIntegration.cs 在模组注册时自动尝试把模组实例接到 EventBus/Command/Network。未安装桥接包时静默跳过。
5.3 ShrinkApp 统一宿主(组合根)
最新引入的 ShrinkApp.Core 把"谁先启动、服务放哪"收口为一条统一链路:
Shrink.Bootstrap:[RuntimeInitializeOnLoadMethod(BeforeSceneLoad)]创建ShrinkAppHostGameObject(可 DontDestroyOnLoad),组装ShrinkAppContext = Host + Settings + Services。- 安装器发现:
ShrinkAppGeneratedRegistry扫描程序集级[ShrinkAppInstallerRegistry](由共享织入器生成),实例化所有IShrinkAppModuleInstaller。 - 拓扑排序:按
Order+DependsOn(显式成环/缺依赖/重复 ModuleId 直接抛错),ShrinkAppSettings.disabledModuleIds可整模块禁用。 - 两阶段启动:先统一
RegisterServices(context)(向ShrinkAppServices类型字典容器注册服务),再按序InitializeAsync。 - 事件广播:成功发
ShrinkAppStartedEvent(含模块清单,等待 UnityStart后才发布),失败发ShrinkAppStartFailedEvent。
各功能模块通过 *.Integration.App 包提供安装器(如 ShrinkNetworkAppInstaller,ModuleId shrink.network,Order -1400),把各自的默认服务注册进容器。ShrinkDataSaver 2.2.0 专门新增 ShrinkDataSaverRuntime 把初始化入口从 MonoBehaviour Bootstrap 下沉,为的就是让宿主接管初始化顺序(旧 ShrinkDataSaverBootstrap 保留为兼容入口)。
5.4 生命周期入口一览
| 入口 | 时机 | 作用 |
|---|---|---|
ShrinkApp.Bootstrap |
BeforeSceneLoad | 创建宿主并按拓扑序启动全部安装器 |
ShrinkModRuntimeBootstrap |
AfterAssembliesLoaded | 读设置、装载模组(场景内/外部 DLL)、接 Harmony |
DataSaverEventBusBridge |
AfterAssembliesLoaded | DataSaver 原生事件桥到 EventBus |
ShrinkTutorialRuntimeBootstrap |
运行时初始化 | 引导系统自举 |
ShrinkDataSaverBootstrap(MonoBehaviour,兼容) |
场景 | 委托 ShrinkDataSaverRuntime;自动保存轮询、暂停/退出落盘 |
| EventBus IL 织入 | 编译期 | MonoBehaviour 自动注册/反注册 |
6. 各模块设计要点
6.1 ShrinkEventBus 1.3.0
- 双层结构:静态门面
EventBus+IShrinkEventBus实例(ShrinkEventBusBuilder配置异常策略、类型校验、marker 接口、phase 派发)。 - 订阅模型:
Action<T>同步与Func<T, UniTask>异步两种 handler;优先级支持枚举EventPriority与数字(数字 0 = NORMAL);receiveCanceled控制取消后是否继续收;IShrinkEventSubscription句柄式订阅 + 实例对象整体注册两套 API。 - 派发机制:监听列表按 phase 分桶 + 快照缓存(
ListenerList),支持父事件监听子事件,跨父子按数字优先级稳定归并;事件对象持有派发时快照而非内置列表。1.3.0 对热路径做了系统性并发加固(总线内单锁、EventId懒生成、ConcurrentDictionary元数据缓存、EventPool容量上限 128 防双重归还)。 - 声明能力:
[Cancelable]/[HasResult]标注事件语义;EventResult承载结果。 - 自动注册:编译期织入(见 5.2)+ 静态注册表;1.3.0 修复"无实例订阅方法的类型被织入后在 Awake 抛异常"的问题,现改警告跳过。
- 兜底管线:共享织入器覆盖不到、只引用
ShrinkEventBus.Runtime的程序集由模块内CodeGen/Editor/EventBusILPostProcessor.cs本地兜底。 - 工具:
EventBusViewerWindow编辑器查看器(走公开快照接口,不反射私有字段)、EventBusBenchmark、Tests 目录覆盖派发/优先级/注册/订阅四类行为。
6.2 ShrinkDataSaver 2.2.0
- 核心对象:
ShrinkSave(存档门面:槽位保存/加载/删除、截图存档、跨模块查询缓存)、ShrinkSettings(设置门面:读写、监听、防抖持久化)、ShrinkDataSaverRuntime(真实初始化与 autosave 驱动,2.2.0 新增)。 - 模块化存档:业务实现
ISaveModule/ISaveModule<T>注册进保存流;关键模块失败终止保存,非关键失败跳过并记日志。 - 存储抽象:
IStorageProvider→LocalStorageProvider(唯一实现)。2.1.0 起升级为异步文件流 + 主文件原子替换(.tmp中转)+.bak1/.bak2双副本轮换备份,主文件损坏自动回退修复;DeleteSlotAsync连带清理主/备/临时文件。 - 安全:AES-CBC + PBKDF2-SHA256(
SaveEncryptor)。 - 迁移:
MigrationChain链式版本迁移(JObject 弱类型操作),支持缺步检测与回滚。 - 易用性:
GetRecentSlotIndex()/GetRecommendedContinueSlotAsync()把"继续游戏"能力下沉包内。 - 事件桥:
DataSaverEventBusBridge单向把原生事件映射为 9 个EventBase事件。 - 测试:仓库最扎实的测试面(保存/加载/迁移/加密/序列化/设置六类,
MockStorageProvider隔离文件系统)。
6.3 ShrinkCommand 0.2.0
- 定位:独立于网络层的 Brigadier 风格命令系统,Unity 与纯 .NET 宿主(独立服务器)共用同一套。
- 命令模型:路径式定义(字面量段 + 贪婪参数段),
[ShrinkCommand("say <message...>")];方法参数支持ShrinkCommandContext/IShrinkCommandSource/ 路径参数按序绑定;返回值支持 void/string/Result 的同步与 Task/UniTask 变体。 - 内建:
help/?帮助树。 - 注册:静态命令走编译期注册表
ShrinkCommandGeneratedRegistry;实例命令RegisterCommands(object)反射方法签名(模组/运行时对象用)。 - 集成:
Integration.EventBus用ShrinkCommandExecuteRequestEvent请求执行并发布 executing/executed/failed 生命周期事件;Integration.Network提供command/executeRPC,远端会话可执行命令(独立服务器与控制台共用同一套命令注册)。
6.4 ShrinkNetwork 0.2.0
- 消息模型:三类载荷——
IShrinkNetworkMessage(单向)、IShrinkNetworkRequest(RPC 请求)、ShrinkRpcResponseBase(错误码+载荷)。所有消息显式[ShrinkNetworkMessage(opcode, route)],opcode/route 一一对应,冲突在生成阶段直接报错(不静默兜底)。 - 包结构(
ShrinkNetworkPacket):ProtocolVersion/SchemaVersion(版本闸门)/Opcode/RequestToken(强类型 RPC 关联,替代裸 int)/SessionToken+ 过期时间 /Route/Kind/Payload。 - 服务内核(
ShrinkNetworkService):持有IShrinkNetworkSerializer + ShrinkNetworkMessageRegistry + ShrinkNetworkRouter三件套;BindTransport绑定传输并自动接入可选桥接;协议版本窗口校验(越界可主动断链);IncomingPacketValidator钩子做逐包鉴权;GetDiagnosticsSnapshot()暴露会话/收发/RPC/协议违规/权限拒绝/处理器异常/未知 opcode/分发 miss/序列化失败等全套计数。 - 并发模型:会话表与挂起 RPC 并发安全,断线自动失败挂起 RPC;派发可注入
IShrinkNetworkDispatchScheduler——独立服务器用Inline,Unity 侧用ShrinkNetworkDispatchQueue(有界队列 + 拒绝/丢弃溢出策略 + 主线程PumpAsync预算泵出),避免网络线程直入 Unity API。 - RPC:
RpcAsync/CallAsync+ShrinkRpcCallOptions(超时、路由重载、令牌覆盖、DebugLabel)。 - 权限:
[ShrinkNetworkSubscribe(Authority=..., Permission=...)]处理器级双重约束(来源 + 权限串)。 - 序列化:
ShrinkJsonNetworkSerializer(调试)/ShrinkMessagePackNetworkSerializer(正式,高频实时推荐 MessagePack+KCP)。 - 传输:
IShrinkNetworkTransport抽象 + Loopback(宿主本地闭环)/ TCP 客户端·服务端(可选ShrinkTcpTlsOptionsTLS,读包路径统一走Stream兼容 SslStream,最大包长保护)/ KCP 客户端·服务端(ShrinkKcpPeer、随机 conversationId、远端地址校验)。IShrinkNetworkSessionControlTransport支持服务端主动踢会话。 - 状态同步范式:
[ShrinkNetworkStateSync("lan", role)]显式声明角色(JoinRequest/JoinResponse/Command/StateDelta/LeaveNotice/Heartbeat),供独立服务器生成器产出可运行同步模块;旧 route 回退识别仍保留。 - EventBus 桥(Integration.EventBus):
[ShrinkNetworkEvent]标注"可上网"的事件类型;扩展方法PublishEventAsync / BroadcastEventAsync / RequestEventAsync / UseEventBusBridge,事件在远端重新分发回 EventBus;区分广播型/远端裁决型/增量型三类语义。
6.5 ShrinkModFramework 0.1.0
- 模组声明:
[ShrinkMod(modId, displayName, version, AutoApplyHarmonyPatches=...)]+[ShrinkModDependency(modId, minVersion)];实现IShrinkMod或继承ShrinkModBase。 - 生命周期四阶段(按依赖拓扑序):
OnConstruct → OnRegisterContent → OnInitialize → OnReady。 - 注册表:
context.GetRegistry<T>("items")按类型+名称双重隔离,键唯一,每条记录归属模组(ShrinkModRegistry/RegistryManager)。 - 装载(
ShrinkModLoader):程序集内模组发现 + 依赖排序;外部 DLL 增量热加载(persistentDataPath/Mods,目录监听 + 延迟触发,同目录依赖解析;不支持卸载、不支持 IL2CPP 动态加载)。 - Harmony:检测到
0Harmony时按模组自动Harmony("shrink.mod.<id>").PatchAll(modAssembly);无 Harmony 静默跳过(可选桥接,不打进框架)。 - 网络抽象:
IShrinkModNetworkTransport + ShrinkModNetworkManager,只定义频道/处理器/收发语义,可接 NGO/Mirror/FishNet/自有 Socket。 - 自动集成:
ShrinkModOptionalRuntimeIntegration在模组注册时反射探测并接入 EventBus/Command/Network(含刷新 Network-EventBus 桥)。 - 自动启动:
[RuntimeInitializeOnLoadMethod(AfterAssembliesLoaded)]读ShrinkModFrameworkSettings装载;ShrinkModBootstrap(场景物体)仅作手动覆盖。 - 编辑器脚手架(
Editor/Scaffolding/):外部 DLL 模组模板生成器、仓库内模组模板生成器(推荐路径,复用仓库 sln/asmdef 编译链)、Mod SDK 导出器(ShrinkSDK/Mod/*菜单,产出GeneratedModSdk/:Libs + ExternalMod 模板 + manifest)。
6.6 ShrinkTutorial 0.1.0
- 数据驱动:
ShrinkTutorialData / Step / Database(ScriptableObject)+ShrinkTutorialSettings;ShrinkTutorialManager单例调度(排队、前置检查、逐步执行、完成/跳过持久化)。 - 目标定位:静态
Hierarchy Path或运行时AnchorId(ShrinkTutorialAnchor组件 +AnchorRegistry);步骤支持waitForTarget + waitTimeout等待动态目标出现。 - 完成条件:
ClickTarget(EventSystem 射线真实命中才过步,防"遮罩挡住但教程已前进")/AnyClick/CustomEvent(业务调CompleteStep(eventName))/Auto;DragToTarget暂按自定义事件处理。 - UI:独立 Overlay Canvas + 遮罩挖洞(目标区可继续点击)+ 提示框/箭头/跳过按钮(
ShrinkTutorialMask / Dialog)。 - 持久化:
IShrinkTutorialStorage→ 默认PlayerPrefs实现。 - 本地化:仅接口
IShrinkTutorialLocalizationProvider,不内置表系统。 - 入口:
ShrinkSDK/引导/教程编辑器、ShrinkSDK/引导/重置教程进度;示例场景ShrinkTutorialSample.unity可由ShrinkSDK/引导/创建示例场景一键重建(当前示例文案为英文,规避 TMP 默认字体缺中文字形)。
6.7 ShrinkApp.Starter.Basic 0.1.0
- 一键起盘:菜单
ShrinkApp/Starter/生成 Basic Entry 场景生成ShrinkAppEntry.unity+ShrinkAppSettings/ShrinkDataSaverSettings/ShrinkAppBasicStarterSettings三份配置。 - 最小闭环调试台:存档槽操作、命令输入与输出、Loopback 绑定/断开、模块/服务/存档/命令/网络五块只读状态面板,演示
App + DataSaver + Command + Network全链路。 - Starter 配置:自动绑 loopback、默认命令、输出行数上限等。
7. 独立服务器生成链
目标:Unity 项目里的消息合同与处理器范式,能直接生成一个可编译、可运行、可继续补业务的 .NET 独立服务器工程(控制台 + 专用服,类似 Minecraft server 的形态)。
生成器:ShrinkNetwork/Editor/Scaffolding/ShrinkDedicatedServerScaffoldGenerator.cs,菜单 ShrinkSDK/Network/生成完整独立服务器工程 / 刷新独立服务器 Generated 合同,输出到 GeneratedServers/ShrinkNetwork.ServerHost/。
生成策略(依赖特性范式而非演示代码命名):
- 模板部分(
.cs.txt源):Program.cs、Framework/(ShrinkDedicatedServerApp、ServerHostOptions/Properties、ServerAuthStore、UnityNetworkCodeScanner、IShrinkServerModule模块体系)、AuthServerModule、TCP/KCP 服务端传输、server.properties。 - 扫描生成部分(
Generated/*.g.cs):网络合同 DTO、按[ShrinkNetworkStateSync]角色推断同步模块、按[ShrinkNetworkEvent]三分类(广播/裁决/增量)自动生成 handler 模板并注册、[ShrinkNetworkSubscribe]权限声明映射、扫描清单(UNITY_NETWORK_SCAN.md/unity-network-scan.json)。
宿主运行形态:
- 模块自发现:反射本程序集全部
IShrinkServerModule实例化(含生成的UnityGeneratedServerModule与手写的AuthServerModule)。 - 双监听:TCP 与 KCP 同端口(默认 17777;历史演示 17001/17002)。
- 配置体系:
ServerHostProperties.LoadOrCreate(),优先级 代码默认值 < server.properties < 环境变量;支持SHRINK_SERVER_CONFIG_PATH自定义路径、SHRINK_SERVER_AUTH_TOKEN等环境变量;首启缺文件自动落默认配置。 - 鉴权与安全基线:默认拒绝匿名登录(
AllowAnonymousWhenAuthTokenMissing显式开启才放行);共享口令登录后签发内存态会话令牌(TTL + 续期窗口 + 逐包校验 + 坏令牌踢线,server/auth/login/server/auth/refresh);协议/Schema 版本窗口越界可断链;TCP 可选 TLS(服务端证书 + 客户端校验);TCP/KCP 均有最大包长与远端地址校验。 - 可观测:
GetDiagnosticsSnapshot()全套指标按DiagnosticsLogIntervalSeconds周期打印,Ctrl+C 前输出最终快照。
验证工具(烟测闭环):GeneratedServers/ShrinkCommand.RuntimeSmoke、ShrinkCommand.EventBusSmoke、ShrinkNetwork.RuntimeSmoke 三个控制台工程,覆盖"登录拿令牌 → 业务 RPC → 令牌续期 → 篡改令牌被踢"与远程 status 命令链路。
8. 场景资产
| 场景 | 用途 |
|---|---|
SampleScene.unity |
基础示例 |
ShrinkAppEntry.unity |
Starter 一键生成的入口调试台 |
ShrinkEmbeddedHostNetworkDemo.unity |
宿主内嵌网络演示(控制器自动 RegisterService,无需手工注册) |
ShrinkLanMovementDemo.unity |
LAN 平台跳跃移动同步演示(状态增量范式样板) |
ShrinkTutorialSample.unity |
引导系统示例(三类完成路径),可一键重建 |
9. 安全与健壮性设计(商业级硬化两轮成果)
- 传输防线:TCP/KCP 最大包长保护(防伪造长度触发大分配)、KCP 远端地址校验 + 随机 conversationId、TCP 并发写串行化(防包流交叉,见 NETWORK_PITFALLS #4)。
- 协议闸门:包级 Protocol/Schema 版本 + 服务端窗口校验,违规可主动断链。
- 身份与会话:默认拒绝匿名;共享口令 → 内存态会话令牌(TTL/续期/逐包校验/踢线)。
- 加密信道:TCP 可选 TLS(证书 + SNI + 吊销检查;当前不含双向认证)。
- 并发安全:服务/会话并发集合、断线自动失败挂起 RPC、EventBus 派发竞态修复、Unity 侧有界派发队列 + 溢出策略。
- 可观测:全套指标快照 + 宿主周期摘要(尚无 metrics 导出/trace/告警)。
- 生成期报错:opcode/route 冲突、installer 循环依赖、重复 ModuleId 均在编译/生成阶段失败,不静默兜底。
10. 测试与验证现状
- 包内测试:
ShrinkDataSaver/Tests(六类,最扎实);ShrinkEventBus/Tests(派发/优先级/注册/订阅四类,1.3.0 后补齐)。 - 烟测工程:三个 RuntimeSmoke/EventBusSmoke 控制台工程,覆盖鉴权-续期-踢线与远程命令全链路。
- 构建验证:
dotnet build ShrinkSDK.sln、Assembly-CSharp(-Editor)、ServerHost.csproj 均 0 warning / 0 error(线程 2026-04-07 记录用户实测 Command/Network/独立服务器链路通过)。 - 缺口:Network/Command/ModFramework/Tutorial 无包内测试目录;无 CI 配置;Unity 编辑器内"重新生成完整独立服务器工程"的运行时回归未做(线程 Next Steps 首条)。
11. 已知设计限制与风险
来自 .planning/codebase/CONCERNS.md(编码问题部分已修复,如 DataSaver 中文乱码已按 UTF-8 重写)与线程 Notes/Next Steps 的仍有效项:
- 网络栈生产缺口:无 TLS 双向认证、无正式身份体系(当前是共享口令+内存令牌,无令牌轮换/外部 IdP)、协议版本是"窗口校验+断开"而非协商式、无 metrics 导出/trace/dashboard/告警、未做压测与模糊包故障演练。
- EventBus 桥回传受限:
ShrinkNetwork.Integration.EventBus的HasResult事件只回传EventResult/IsCanceled/ErrorCode/ErrorMessage,不自动回传事件对象其它字段的最终改动。 - 外部 DLL 模组边界:不支持运行时卸载程序集;IL2CPP Player 下外部 DLL 动态加载不可用。
- 生成器边界:独立服务器生成以"可编译、可注册、可继续补业务"为目标,不推断完整业务逻辑;
GeneratedServers/产物可重建,人工业务不得写进生成文件(覆写保护行为待确认,线程 Next Steps 有记录)。 - 教程系统:DragToTarget 未内建命中判定;圆形高亮视觉按外接矩形挖洞;示例文案为英文(等可用中文 TMP 字体资产后回改)。
- 仓库工程面:无 CI/发布流水线;
.planning/codebase/地图滞后于当前模块规模(本文档即为补齐);部分公开 API 仍有 nullable 语义不一致残留(route = null类签名收口未完成)。 - 历史已过期项:
D:\UnityBuilds\ShrinkSDK曾不是 Git 仓库(现为 Git 仓库,当前处于初始提交暂存阶段);ServerHost nullable warnings 已清零(旧记录过期)。
12. 关键文件索引(推荐阅读顺序)
- 统一宿主:
Assets/Modules/ShrinkApp.Core/Runtime/ShrinkApp.cs→ShrinkAppHost.cs→ShrinkAppTypes.cs - 编译期机制:
Assets/Modules/ShrinkShared.CodeGen/Editor/ShrinkRegistryILPostProcessor.cs - 事件系统:
Assets/Modules/ShrinkEventBus/Runtime/EventBus.cs→IShrinkEventBus.cs→ShrinkEventBusInstance.cs - 存档系统:
Assets/Modules/ShrinkDataSaver/Runtime/ShrinkSave.cs→ShrinkDataSaverRuntime.cs→LocalStorageProvider.cs - 命令系统:
Assets/Modules/ShrinkCommand/Runtime/Core/ShrinkCommandService.cs→Metadata/ShrinkCommandAttributes.cs - 网络框架:
Assets/Modules/ShrinkNetwork/Runtime/Core/ShrinkNetworkService.cs→Metadata/ShrinkNetworkPacket.cs→Transport/Abstractions/IShrinkNetworkTransport.cs - 模组框架:
Assets/Modules/ShrinkModFramework/Runtime/Bootstrap/ShrinkModRuntimeBootstrap.cs→Loading/ShrinkModLoader.cs→Core/IShrinkMod.cs - 引导系统:
Assets/Modules/ShrinkTutorial/Runtime/Core/ShrinkTutorialManager.cs - 独立服务器:
GeneratedServers/ShrinkNetwork.ServerHost/Program.cs→Framework/ShrinkDedicatedServerApp.cs - 经验教训:
NETWORK_PITFALLS.md(19 条联网/桥接/编译链踩坑,含 Kcp DLL 兼容、TCP 并发写、生成器范式化等)