concepts - mclucy/lucy GitHub Wiki

核心概念

本页将说明 Lucy 的三个核心抽象:

  • Package ID(包标识符)
  • Platform / Source(平台与来源)
  • Runtime Topology(运行时拓扑)

关键要点

Package ID(包标识符)

基本格式

在 Lucy 中,Package ID 是用于描述一个 package 的结构化字符串,标准形式为:

platform/project@version

注意,用户输入的原始 Package ID 并不一定具有唯一性。其唯一性会在内部被逐步解析并确保。目前这部分并没有统一入口,i.e.,正在设计。

示例:

fabric/[email protected]
   ↑        ↑        ↑
platform  project  version

neoforge/create@compatible
mcdr/mcdreforged@latest
lithium                    ← 省略 platform 与 version 的最简形式

字段规则与默认行为

platform / project / version 三段中,只有 project 必填。

  • 省略 platform:Lucy 在运行时环境中推断。
  • 省略 version:默认补为 @compatible

在实现中,Package ID 由 PackageId 结构体表示(见 types/type_id.go:124):

字段 类型 说明
Platform Platform 平台枚举值;默认 PlatformAny(未指定)
Name ProjectName 项目 slug,如 fabric-apilithium;大小写不敏感
Version RawVersion 版本字符串;支持精确版本与特殊标记(@latest@compatible
// ../lucy/types/type_id.go:124-128
type PackageId struct {
 Platform Platform
 Name     ProjectName
 Version  RawVersion
}

Identity Package(单位包)

挪用了数学概念单位元(Identity Element)。

平台本身也可作为 package 安装或升级,这类包称为 identity package

典型示例:

  • fabric/fabric 或简写 fabric:安装 Fabric 加载器
  • minecraft:Minecraft 本体
  • mcdreforgedmcdr:MCDReforged 插件框架

Lucy 会将别名标准化为规范包名(例如 fabric-loader -> fabric),并在版本可推断时自动补全为 @compatible(见 types/type_id.go:165)。

Platform(平台)与 Source(来源)

Platform(平台)

Platform 表示改变 Minecraft 原版行为的服务端框架或运行环境,可视为一组 package 的公共依赖。

平台的描述主体总是包而非服务器环境。这是与下文中的Topology的重要区分。

已知枚举值:

枚举常量 字符串值 说明
PlatformMinecraft minecraft 原版 Minecraft(别名 PlatformVanilla
PlatformFabric fabric Fabric 模组加载器
PlatformForge forge Forge 模组加载器
PlatformNeoforge neoforge NeoForge 模组加载器
PlatformMCDR mcdr MCDReforged 插件框架
PlatformNone none 无平台要求(被所有平台满足)
PlatformAny "" 未指定平台(单值占位,运行时收敛为具体平台)
PlatformUnknown unknown 解析失败哨兵值(不满足任何平台)

将在未来通过去除特殊值和改变满足关系来重构为在 $p \leq r \equiv \text{p.Satisfy}(r)$ 上构成偏序集来确保 Satisfy() 的可靠性。

语义区分:

  • PlatformAny:尚未确定平台,但最终应收敛为某一个确定平台。
  • PlatformNone:不要求任何特定平台,可被任意平台满足。
  • PlatformUnknown:解析失败,既不被满足,也不满足任何平台。

types/type_id.go:58

// ../lucy/types/type_id.go:16-28
type Platform string

const (
 PlatformAny       Platform = "" // PlatformAny is ambiguous but has single-valueness. It does NOT refer to multiple platforms, but rather a single platform that is unknown. Understand this as PlatformAny reduces to a definite platform at evaluation. Again, keep in mind that you should not allow it to be explicitly evaluated as multiple platforms.
 PlatformMinecraft Platform = "minecraft"
 PlatformVanilla            = PlatformMinecraft // Alias for Minecraft
 PlatformFabric    Platform = "fabric"
 PlatformForge     Platform = "forge"
 PlatformNeoforge  Platform = "neoforge"
 PlatformMCDR      Platform = "mcdr"
 PlatformNone      Platform = "none"    // PlatformNone is a special platform that is not satisfied by any platform, but it can satisfy all platforms. It is typically used to indicate the absence of a platform, for example, when a package is not compatible with any platform, or when a package does not require a platform.
 PlatformUnknown   Platform = "unknown" // PlatformUnknown is the only constant with no single-valueness, it can refer to multiple platforms other than the ones defined here.
)

// ../lucy/types/type_id.go:58-79
// Satisfy returns true if p satisfies the requirement of p2.
func (p Platform) Satisfy(p2 Platform) bool {
 // When p2 is PlatformNone, it is satisfied by all platforms.
 if p2 == PlatformNone {
  return true
 }
 // PlatformUnknown is not satisfied by any platform, and does not satisfy
 // any platform including itself.
 if p == PlatformUnknown || p2 == PlatformUnknown {
  return false
 }
 // When p2 is PlatformAny, it is satisfied by all platforms.
 if p2 == PlatformAny {
  return true
 }
 // When p is PlatformAny, it does not satisfy any platform except itself.
 if p == PlatformAny {
  return false
 }
 // Trivial cases
 return p == p2
}

// ../lucy/types/type_id.go:95-97
func (p Platform) IsModding() bool {
 return p == PlatformFabric || p == PlatformForge || p == PlatformNeoforge
}

Lucy 通过 IsModding() 区分 mod loader(fabricforgeneoforge)与其他平台类型。

Source(来源)

Source 是 package 元数据上游的枚举标识。每一个具体 Source 对应一个 Provider

  • 用途:CLI 输入、配置存储、结果溯源
  • 非用途:执行对象(执行对象是 upstream.Provider 接口)

已知枚举值:

枚举常量 字符串值 说明
SourceModrinth modrinth Modrinth mod 目录
SourceCurseForge curseforge CurseForge mod 目录
SourceGitHub github GitHub Release 资产
SourceMCDR mcdr MCDReforged 插件目录
SourceAuto auto / "" 路由策略标记,由路由层自动选择 provider
SourceUnknown unknown 解析失败哨兵值

SourcePlatform 是正交维度:同一个 Fabric mod 可同时存在于 Modrinth 和 CurseForge。搜索命令可用 --source modrinth 限定来源(见 types/source.go:1)。

// ../lucy/types/source.go:16-25
const (
 SourceAuto Source = iota // policy marker: let routing choose providers
 SourceCurseForge
 SourceModrinth
 SourceGitHub
 SourceMCDR
 SourceUnknown // sentinel for parse/validation failure
)

版本标识符与兼容性(Compatibility)

RawVersion 与特殊版本标记

版本字段 RawVersion 除精确版本号外,还支持:

标记 内部常量 说明
@latest VersionLatest 拉取该 project 最新发布版本,不考虑服务器环境兼容性
@compatible VersionCompatible 拉取与当前服务器 Minecraft 版本兼容的最新版本(省略版本时默认值)
(省略) VersionAny 内部占位;等价于 @compatible,由 upstream 层推断后解析

@compatible@latest 都是“可推断”版本(CanInfer() == true),在实际调用上游 API 前,应先经 upstream.InferVersion() 解析为具体版本号(见 types/type_dependency.go:30)。

[!WARNING] 以下内容基于非完整代码推断,可能与实际预期行为存在偏差。

下面关于 @compatible 解析机制的描述基于代码结构推断,未被行内文档记录。请以 upstream/ 目录中的实际实现为准。

@compatible 的解析依赖 probe 模块给出的当前服务器 Minecraft 游戏版本(GameVersion)。路由层基于该版本过滤上游目录并选出兼容的最新包版本。这也是推荐默认策略,可降低版本不匹配导致的运行时崩溃风险。

兼容性裁定(CompatVerdict)

Lucy 使用 CompatVerdict 枚举表达当前环境下的兼容性评估:

说明
compatible 完全兼容,可正常安装
degraded 部分兼容,可安装但存在风险(如通过 bridge 层适配)
incompatible 不兼容,无法安装
unresolved 无法确定(topology 信息不足)

CompatResult 除裁定值外,还携带:

  • 机器可读原因:Reason
  • 详细说明:Detail
  • 风险等级:RiskLevel(0-4,对应 RiskNoneRiskCritical

types/type_server_topology.go:44

// ../lucy/types/type_server_topology.go:42-49
type CompatVerdict string

const (
 CompatCompatible   CompatVerdict = "compatible"
 CompatDegraded     CompatVerdict = "degraded"
 CompatIncompatible CompatVerdict = "incompatible"
 CompatUnresolved   CompatVerdict = "unresolved"
)

// ../lucy/types/type_server_topology.go:51-56
type CompatResult struct {
 Verdict   CompatVerdict    `json:"verdict"`
 Reason    string           `json:"reason"`
 Detail    string           `json:"detail"`
 RiskLevel RuntimeRiskLevel `json:"risk_level"`
}

Runtime Topology(运行时拓扑)

Runtime Topology 是 probe 模块对当前服务器运行时结构的完整建模。Lucy 基于该模型判断 package 是否可安装、风险如何。

数据结构总览

RuntimeTopology 由三部分组成:

RuntimeTopology
├── PrimaryNode  : RuntimeNodeID       ← 主节点 ID(服务器核心运行时)
├── Nodes        : []RuntimeNode       ← 所有已知运行时节点
└── Edges        : []RuntimeEdge       ← 节点间关系边

RuntimeNode 表示运行时中的一个软件单元,字段如下(见 types/type_server_topology.go:73):

字段 说明
ID 节点唯一标识(RuntimeNodeID
Role 节点角色(见下节 RuntimeRole
IdentityPlatform 节点对应的 Lucy Platform
Capabilities 节点可加载的 package 生态系统列表
RiskLevel 节点已知风险等级(0-4)

节点角色(RuntimeRole)

角色值 说明
mod_loader 模组加载器(Fabric、Forge、NeoForge)
plugin_core 插件核心(MCDR、Paper、Spigot、Bukkit)
hybrid 混合服务端,同时支持 mod 与 Bukkit 插件(如 Arclight、Youer)
proxy 代理服务端(Velocity、BungeeCord、Waterfall)
bridge 跨生态桥接层(Connector、Kilt)
protocol_bridge 协议转换桥接层(Geyser)
vanilla 原版 Minecraft

types/type_server_topology.go:7probe/probe_topology_registry_data.go:29

运行时能力(RuntimeCapability)

每个节点声明其可加载的 package 生态系统:

Capability 值 说明
fabric_mods 可加载 Fabric 模组
forge_mods 可加载 Forge 模组
neoforge_mods 可加载 NeoForge 模组
bukkit_plugins 可加载 Bukkit/Spigot/Paper 插件
mcdr_plugins 可加载 MCDReforged 插件
proxying 代理转发能力
protocol_bridge 协议桥接能力(如基岩版 <-> Java 版)

types/type_server_topology.go:20

节点关系边(RuntimeEdge)

边用于表达运行时节点关系(尤其是混合服务端与 bridge 场景):

边类型(RuntimeEdgeKind 含义
hosts 一个节点托管另一个节点的 package 生态
bridges 一个节点桥接另一个节点的 package 生态(高风险)
routes 流量路由关系(代理场景)
adapts 适配关系

types/type_server_topology.go:93

// ../lucy/types/type_server_topology.go:73-79
type RuntimeNode struct {
 ID               RuntimeNodeID       `json:"id"`
 Role             RuntimeRole         `json:"role"`
 IdentityPlatform Platform            `json:"identity_platform"`
 Capabilities     []RuntimeCapability `json:"capabilities"`
 RiskLevel        RuntimeRiskLevel    `json:"risk_level"`
}

// ../lucy/types/type_server_topology.go:102-107
type RuntimeEdge struct {
 From RuntimeNodeID    `json:"from"`
 To   RuntimeNodeID    `json:"to"`
 Kind RuntimeEdgeKind  `json:"kind"`
 Risk RuntimeRiskLevel `json:"risk"`
}

// ../lucy/types/type_server_topology.go:109-113
type RuntimeTopology struct {
 PrimaryNode RuntimeNodeID `json:"primary_node"`
 Nodes       []RuntimeNode `json:"nodes"`
 Edges       []RuntimeEdge `json:"edges"`
}

// ../lucy/types/type_server_topology.go:124-126
func (t *RuntimeTopology) Resolved() bool {
 return t != nil && t.PrimaryNode != RuntimeNodeUnknown && len(t.Nodes) > 0
}

// ../lucy/types/type_server_topology.go:128-140
func (t *RuntimeTopology) FindNode(id RuntimeNodeID) (RuntimeNode, bool) {
 if t == nil {
  return RuntimeNode{}, false
 }

 for _, node := range t.Nodes {
  if node.ID == id {
   return node, true
  }
 }

 return RuntimeNode{}, false
}

注册表与默认 Topology

RuntimeRegistry 是静态注册表,用于保存已知平台的 topology 配置(RegistryEntry),支持按节点 ID 或 Platform 查询。

DefaultRegistry 内置的运行时节点包含:

minecraftfabricforgeneoforgemcdrpaperspigotbukkitfoliaarclightyouervelocitybungeecordwaterfallgeyserconnectorkilt

BuildTopologyFromEntry() 会从单个 RegistryEntry 出发,遍历其 PolicyEdges,构建包含主节点及关联节点/边的完整 RuntimeTopology(见 probe/probe_topology_registry.go:86)。

[!WARNING] 以下内容基于非完整代码推断,可能与实际预期行为存在偏差。

下面关于 topology 与兼容性裁定协作机制的说明基于代码结构推断,未被行内文档记录。请以 probe/install/ 目录中的实际实现为准。

在安装流程开始时,probe 模块会扫描本地服务器目录,识别可执行文件与已安装 package 元数据,生成当前服务器的 RuntimeTopology。随后该 topology 传递到路由层,用于:

  1. 选择合适的上游 provider
  2. 过滤与当前平台不兼容的 package 版本
  3. 生成 CompatResult 兼容性裁定

相关页面

参考文件

本页主要依据如下源码(基线 commit:86d3480cffa821b9b9c0747263a637b2973a7366):

  • README.md:150 - 核心概念定义(Platform、Project、Package、Package ID 格式)
  • types/type_id.go:16 - Platform 枚举完整定义及 Satisfy() 语义说明
  • types/type_id.go:99 - ProjectName 类型及 slug 规范
  • types/type_id.go:124 - PackageId 结构体及字符串化方法
  • types/type_id.go:165 - Identity package 映射表(别名 -> 规范名)
  • types/source.go:1 - Source 枚举及 SourceAuto 路由策略标记语义
  • types/type_dependency.go:7 - RawVersionVersionLatest/VersionCompatible 常量
  • types/type_dependency.go:30 - CanInfer() 方法(可推断版本集合)
  • types/type_server_topology.go:7 - RuntimeRole 枚举
  • types/type_server_topology.go:20 - RuntimeCapability 枚举
  • types/type_server_topology.go:44 - CompatVerdictCompatResultCompatPolicy
  • types/type_server_topology.go:73 - RuntimeNode 结构体
  • types/type_server_topology.go:93 - RuntimeEdgeKind 枚举
  • types/type_server_topology.go:109 - RuntimeTopology 结构体
  • probe/probe_topology_registry.go:24 - RuntimeRegistry 注册表实现
  • probe/probe_topology_registry.go:86 - BuildTopologyFromEntry() 拓扑构建逻辑
  • probe/probe_topology_registry_data.go:29 - defaultRegistryEntries 默认注册表数据