Skip to content
4rcadia edited this page Jun 29, 2026 · 1 revision

拓扑模型

概览

Lucy 使用有向无环图来描述 Minecraft 服务器的运行时结构,其中包含:

  1. 服务器上运行了哪些运行时层(模组加载器、插件框架、桥接层、代理)?
  2. 它们之间的结构关系是什么(宿主、实现、代理)?
  3. 每个层向下游包暴露了什么能力和身份?

这些信息服务于安装兼容性判断、环境依赖注入、包搜索路径推导和用户界面展示。

节点

每个 RuntimeNode 代表一个可以独立观察到的运行时层。

字段

字段 类型 含义
ID RuntimeNodeID 唯一标识,如 forgepaperconnector
Role RuntimeRole 结构角色:mod_loaderplugin_corebridgeproxy
Capabilities []RuntimeCapability 节点接受的包生态系统,如 fabric_modsbukkit_plugins
Identities []VersionedPackageRef 节点暴露的版本化身份

建模标准

对节点进行建模的原则并不是越多越好。一个节点必须满足以下条件之一才有存在价值:

引入一个会改变消费者决策的能力、风险等级或身份。

这里的"决策"涵盖解析、兼容性评估和风险提示。

节点的来源:

  1. 可执行文件。探测器在磁盘上发现了对应的服务器 JAR。例如 Forge、Paper、Fabric 等。
  2. 包。已安装包的名称映射到了已知节点。例如 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

曾经提出但是弃用的动词:adaptsbridgesroutes。被适配的环境通过能力(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.0fabricloader@0.18.*
Forge + Arclight Arclight arclight@1.20.1bukkit@1.20.1-R0.1
Paper + Geyser Geyser geyser@2.4.0、Bedrock 协议版本
NeoForge + Kilt Kilt kilt@0.4.5forge@47.3.0(模拟)
Forge + Mohist Mohist mohistbukkitcraftbukkitspigotforgeneoforge

身份由探测器在检测阶段产出(扁平列表),在物化阶段通过 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 可能演化为接口以支持不同类型节点携带不同元数据。目前保持结构体。

Clone this wiki locally