probe detector - mclucy/lucy GitHub Wiki

探测器(Probe Detector)

本文档说明 probe/internal/detector 子系统的职责、执行路径与输出数据结构,重点覆盖三类探测器:

  • 可执行文件探测(ExecutableDetector
  • 包探测(PackageDetector
  • 环境探测(EnvironmentDetector

该子系统是 probe 模块的底层识别层:负责从 JAR / ZIP / .pyz / .mcdr 文件中提取平台、版本、依赖与运行时证据,并将结果反馈给 probe 上层的 topology 构建与兼容性评估流程。

关键要点

核心接口与注册表

detector 包定义了三组接口,并通过全局注册表统一管理:

  • ExecutableDetector:识别服务器可执行体,输出 *types.ExecutableInfo
  • PackageDetector:识别 mod / plugin 包,输出 []types.Package
  • EnvironmentDetector:识别工作目录外部环境(如 MCDR),写入 types.EnvironmentInfo

注册入口位于 detector_registry.go

  • registerExecutableDetector
  • registerModDetector
  • registerOtherPackageDetector
  • registerEnvironmentDetector

聚合层通过 getExecutableDetectors() / getModDetectors() / getOtherPackageDetectors() / getEnvironmentDetectors() 读取注册结果并执行探测。

聚合执行行为(Aggregator)

detector_aggregator.go 提供统一入口:

  • Executable(filePath string):打开 JAR,遍历所有 executable detector,收集候选
  • Packages(filePath string):按扩展名分派包探测
  • McdrPlugin(filePath string):通过名称键 "mcdr plugin" 调用 other-package detector
  • Environment(dir string):逐个执行 environment detector,聚合环境信息

Executable() 的结果裁定规则:

  • 0 个候选:返回 types.NoExecutable
  • 1 个候选:返回该候选,并尝试写入 BridgeHints
  • 多个候选:记录告警并返回 types.UnknownExecutable

其中 BridgeHints 来自 DetectBridgeMarkers(),用于后续 topology enrich 阶段。

可执行文件探测(Server Executable)

当前已实现 5 类服务器可执行体检测:

  1. Vanilladetector_vanilla.go

    • 关键证据:version.json
    • 防误判逻辑:若 version.json 可解析为 Forge installer 结构(_comment + mainClass),返回 types.NoExecutable
    • 输出:RuntimeIdentitiesminecraft,Topology 主节点为 minecraft
  2. Fabric Single-File Serverdetector_fabric.go

    • 关键证据:install.properties
    • 读取字段:fabric-loader-versiongame-version
    • 输出:fabric + minecraft 双 identity;Topology 主节点 fabric
  3. Fabric Launcherdetector_fabric.go

    • 关键证据:fabric-server-launch.propertieslaunch.mainClass=net.fabricmc.loader.impl.launch.knot.KnotServer
    • 再从 META-INF/MANIFEST.MFClass-Path 推导 loader/game 版本
  4. Forge Serverdetector_forge.go

    • 关键证据:META-INF/MANIFEST.MF
    • 读取字段:
      • Implementation-Title: net.minecraftforge
      • Implementation-Version(Forge 版本)
      • Specification-Title: Minecraft + Specification-Version(游戏版本)
  5. NeoForge Serverdetector_neoforge.go

    • 关键证据:Class-Path 中存在 libraries/net/neoforged/neoforge/<version>/...
    • gameVersion 同样尝试由 manifest Specification-Version 提取

Warning

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

请以 probe/internal/detector/*.go 的最新实现为准。

包探测(Mods / Plugins)

Packages() 目前按扩展名分发:

  • .jar / .zip:执行 JAR 包探测器链
  • .pyz / .mcdr:交给 McdrPlugin()

各平台包探测器要点如下:

  • Fabric mod:读取 fabric.mod.json,提取 id/version、作者、license、描述;依赖字段 depends/recommends/suggests/breaks/conflicts 映射到 types.Dependency
  • Forge mod:读取 META-INF/mods.tomlversion == ${file.jarVersion} 时回退读取 manifest;依赖区间使用 Maven 方言解析
  • NeoForge mod:读取 META-INF/neoforge.mods.toml;解析逻辑与 Forge 相近,但平台为 neoforge
  • MCDR plugin:读取 mcdreforged.plugin.json;依赖区间按 npm 语义解析

版本区间解析 helpers:

  • parseFabricVersionRanges -> dependency.ParseRanges(..., InferRangeDialect(PlatformFabric), Semver)
  • parseMavenVersionRange -> dependency.ParseRange(..., InferRangeDialect(PlatformForge), Semver)
  • parseNpmVersionRange -> dependency.ParseRange(..., InferRangeDialect(PlatformMCDR), Semver)

环境探测(Environment)

McdrDetector 通过工作目录中的 config.yml 判断是否为 MCDR 环境:

  • 若存在配置文件:解析为 exttype.FileMcdrConfig
  • 调用 mcdreforged --version 获取版本,写入 env.Mcdr

probe 上层,buildEnvironment() 直接调用 detector.Environment(".");若命中 MCDR,workPath() 切换到 env.Mcdr.Config.WorkingDirectory

Bridge Marker 与 Topology Enrichment 协作

DetectBridgeMarkers() 会扫描 JAR entry 名称并识别以下节点证据:

  • connector(risk 3)
  • kilt(risk 3)
  • velocity(risk 0)
  • bungeecord(risk 0)
  • geyser(risk 1)

这些 marker 在单候选 executable 时写入 ExecutableInfo.BridgeHints,随后在 probe/EnrichTopologyFromPackages() 中被合并到 runtime topology。

已知限制与实现注意点

  • 当多个 executable detector 同时命中时,当前策略直接返回 types.UnknownExecutable,尚无更细粒度冲突消解机制。
  • forge 旧版(pre-1.13)mod 探测仍处于 TODO 状态,相关实现仅保留注释草稿。
  • buildExecutableInfo() 的第 4 层递归扫描(pwd 全目录)标注为 TODO,尚未实现。

Warning

此功能尚未完整/正确实现 probe/internal/detector/detector_forge.go 中旧版 Forge mod 探测尚未接入执行路径,详见同文件 TODO 注释区。

相关页面

参考文件

本页依据以下源码(基线 commit:86d3480cffa821b9b9c0747263a637b2973a7366):

  • probe/internal/detector/detector.go:10 - 三类 detector 接口定义
  • probe/internal/detector/detector_registry.go:4 - 注册表结构与 register/get 函数
  • probe/internal/detector/detector_aggregator.go:17 - Executable() 聚合入口与候选裁定
  • probe/internal/detector/detector_aggregator.go:75 - Packages() 按扩展名分派
  • probe/internal/detector/detector_aggregator.go:109 - McdrPlugin() other-package 探测入口
  • probe/internal/detector/detector_aggregator.go:137 - Environment() 环境聚合入口
  • probe/internal/detector/detector_vanilla.go:22 - Vanilla executable 探测
  • probe/internal/detector/detector_fabric.go:28 - Fabric executable(single-file)探测
  • probe/internal/detector/detector_fabric.go:113 - Fabric executable(launcher)探测
  • probe/internal/detector/detector_fabric.go:242 - Fabric mod 探测与依赖映射
  • probe/internal/detector/detector_forge.go:26 - Forge executable 探测
  • probe/internal/detector/detector_forge.go:118 - Forge mod 探测(mods.toml)
  • probe/internal/detector/detector_neoforge.go:26 - NeoForge executable 探测
  • probe/internal/detector/detector_neoforge.go:142 - NeoForge mod 探测
  • probe/internal/detector/detector_mcdr.go:32 - MCDR 环境探测(config.yml + 命令行版本)
  • probe/internal/detector/detector_mcdr.go:94 - MCDR 插件元数据探测
  • probe/internal/detector/detector_bridge.go:17 - Bridge marker 扫描逻辑
  • probe/internal/detector/detector_fabric_helpers.go:11 - Fabric 区间解析 helper
  • probe/internal/detector/detector_forge_helpers.go:56 - Forge(Maven) 区间解析 helper
  • probe/internal/detector/detector_mcdr_helpers.go:16 - MCDR(npm) 区间解析 helper
  • probe/probe_exec.go:26 - detector 在 executable 探测路径中的调用
  • probe/probe.go:220 - detector 在 environment / installed packages 中的调用
  • probe/probe_topology_enrich.go:70 - BridgeHints 注入 topology
⚠️ **GitHub.com Fallback** ⚠️