-
Notifications
You must be signed in to change notification settings - Fork 3
Topology
4rcadia edited this page Jun 29, 2026
·
1 revision
Lucy 使用有向无环图来描述 Minecraft 服务器的运行时结构,其中包含:
- 服务器上运行了哪些运行时层(模组加载器、插件框架、桥接层、代理)?
- 它们之间的结构关系是什么(宿主、实现、代理)?
- 每个层向下游包暴露了什么能力和身份?
这些信息服务于安装兼容性判断、环境依赖注入、包搜索路径推导和用户界面展示。
每个 RuntimeNode 代表一个可以独立观察到的运行时层。
| 字段 | 类型 | 含义 |
|---|---|---|
ID |
RuntimeNodeID |
唯一标识,如 forge、paper、connector
|
Role |
RuntimeRole |
结构角色:mod_loader、plugin_core、bridge、proxy 等 |
Capabilities |
[]RuntimeCapability |
节点接受的包生态系统,如 fabric_mods、bukkit_plugins
|
Identities |
[]VersionedPackageRef |
节点暴露的版本化身份 |
对节点进行建模的原则并不是越多越好。一个节点必须满足以下条件之一才有存在价值:
引入一个会改变消费者决策的能力、风险等级或身份。
这里的"决策"涵盖解析、兼容性评估和风险提示。
节点的来源:
- 可执行文件。探测器在磁盘上发现了对应的服务器 JAR。例如 Forge、Paper、Fabric 等。
- 包。已安装包的名称映射到了已知节点。例如 Connector、Kilt、Geyser 等。
- CraftBukkit、Spigot 在 Paper 下不独立建节点——它们不引入独立的版本化身份,插件也不对它们做版本检查。
- 被适配的环境(如 Sinytra Connector 提供的 Fabric 生态)不独立建节点——能力直接挂在桥接节点上。也就是说,是
Neoferge -> Sinytra,而不是Neoferge -> Sinytra -> Fabric。
边描述节点间的结构关系。
| 动词 | 含义 | 示例 |
|---|---|---|
hosts |
一个节点宿主另一个节点(间接能力路径) | Forge → Connector |
extends |
结构上的延续或锚定(分支实现、指向 vanilla 等,不区分细类) | Purpur → Paper,Paper → Minecraft |
proxies |
多服务器代理关系(预留) | Velocity → backend |
曾经提出但是弃用的动词:adapts、bridges、routes。被适配的环境通过能力(Capability)表示,而非独立节点,避免过度建模。
能力(Capability)表示一个节点可以接受哪类包。
| 能力 | 含义 |
|---|---|
fabric_mods |
接受 Fabric 模组 |
forge_mods |
接受 Forge 模组 |
neoforge_mods |
接受 NeoForge 模组 |
bukkit_plugins |
接受 Bukkit 系插件 |
sponge_plugins |
接受 Sponge 插件 |
mcdr_plugins |
接受 MCDR 插件 |
velocity_plugins |
接受 Velocity 插件 |
bungeecord_plugins |
接受 BungeeCord 插件 |
关键设计: 桥接层可以携带其适配目标生态的能力。例如 Connector 节点同时具有 fabric_mods 能力,因为它将 Fabric 模组生态引入了 Forge 环境。这避免了为推断出的环境创建虚节点。
节点身份(Identities)是节点向下游包暴露的版本化标识。一个节点可以携带多个身份。
每个 RuntimeNode 携带自己的 Identities []VersionedPackageRef。这保留了"哪个运行时层提供了哪个身份"的关联,使得下游包可以检查特定层的版本约束。例如 Fabric 模组检查 Connector 报告的 fabricloader 版本。
| 服务器配置 | 节点 | 携带的身份 |
|---|---|---|
| Forge + Sinytra Connector | Connector |
connector@1.0.0、fabricloader@0.18.*
|
| Forge + Arclight | Arclight |
arclight@1.20.1、bukkit@1.20.1-R0.1
|
| Paper + Geyser | Geyser |
geyser@2.4.0、Bedrock 协议版本 |
| NeoForge + Kilt | Kilt |
kilt@0.4.5、forge@47.3.0(模拟) |
| Forge + Mohist | Mohist |
mohist、bukkit、craftbukkit、spigot、forge、neoforge
|
身份由探测器在检测阶段产出(扁平列表),在物化阶段通过 RuntimeIdentityNode 映射分配到对应节点。
拓扑有六类消费者:
| 消费者 | 使用方式 |
|---|---|
| 安装兼容性判断 |
EvaluateCompatibility:直接能力 vs 间接能力 |
| 提供者选择 | 根据能力路由到正确的上游源 |
| 环境依赖注入 |
HasCapability(FabricMods) 决定是否注入 fabricloader 等环境依赖 |
| 包搜索路径 | 能力 → mods/plugins 目录 |
| 平台推导 | 主节点 ID → PlatformId |
| 用户界面 | 拓扑渲染、状态展示 |
只有消费者 1 和 6 利用图的形状。消费者 2-5 使用扁平的能力查询。图的核心价值在于直接/间接能力区分、服务器核心身份和可视化。
JAR 探测 → ExecutableDetector → ExecutableEvidence
→ materializeRuntimeInfo (填充 ServerRuntime)
→ materializeRuntimeTopology (构建/选择拓扑,分配身份到节点)
→ EnrichTopologyFromPackages (从已安装包推导额外节点)
→ NormalizeTopology
→ Workspace.Topology (最终输出)
- 多服务器拓扑:代理(Velocity/BungeeCord)连接多个后端服务器。代理只知道后端地址,不知道平台/版本——Lucy 需要发现机制。
-
异构节点:
RuntimeNode可能演化为接口以支持不同类型节点携带不同元数据。目前保持结构体。