Skip to content

Mod 信息 API

Mod Information API 提供了对多种 mod 类型(NeoForge、Forge、Fabric)的 Minecraft 元数据的全面访问,支持自动 mod 同步、启动器集成以及服务器-客户端 mod 管理。这些 API 支持三种不同的 mod 类别:公共 mod、仅客户端 mod 和服务端 mod,并内置了缓存以优化性能,同时为各种消费者应用程序提供灵活的内容协商。

API 架构

Mod Information API 构建在三层架构之上,分离了路由、业务逻辑和数据访问的职责。public/mods.php 中的路由层定义了 RESTful 端点,这些端点将 mod 发现和解析委托给 McModUtils 命名空间。Mods 类管理文件夹扫描和缓存,而单个 Mod 实例负责从 JAR 存档中提取元数据。

系统采用 mod 类型映射 策略,其中路由前缀(modsclient-modsserver-mods)对应配置数组中的配置键(commonclientserver),从而能够针对每个 mod 类别动态配置路径和下载 URL。

来源:public/mods.php, config.default.php

Mod 类型类别

API 支持三种不同的 mod 类型类别,每种类别服务于不同的同步场景:

Mod 类型路由前缀配置键用例服务端过滤
公共 Mod/modscommon服务器和客户端都需要的 Mod忽略服务端前缀
仅客户端 Mod/client-modsclient仅在客户端需要的 Mod忽略服务端前缀
仅服务端 Mod/server-modsserver应仅在服务器上运行的 Mod仅包含服务端前缀

服务端前缀过滤 机制使用可配置的前缀(serveronly_server_)来区分不应分发给客户端的 mod。这对于性能优化以及防止因服务端依赖项导致客户端崩溃至关重要。

来源:public/mods.php, config.default.php

API 端点

获取 Mod 列表端点

主要端点检索特定类别中所有 mod 的综合元数据。它支持用于缓存控制和输出格式自定义的查询参数。

端点模式GET /:modType,其中 :modTypemodsclient-modsserver-mods 之一

查询参数

参数类型默认值描述
forceBooleanfalse绕过缓存并强制重新解析
simple-md5Booleanfalse返回简化的 filename: md5 对象
typeStringauto强制使用 jsonhtml 输出格式

完整 JSON 响应结构

JSON

json { "modsHash": "d9e9ae1ba3b4771ed389518777747fd38b641c25ef7a9a5ff2628e83d57f474d", "updateAt": "2025-07-27T14:52:10+08:00", "mods": [ { "name": "Apothic Attributes", "authors": ["Shadows_of_Fire"], "version": "2.9.0", "filename": "ApothicAttributes-1.21.1-2.9.0.jar", "fileName": "ApothicAttributes-1.21.1-2.9.0.jar", "sha1": "eed5808509eb279fd342cafebadd5b95accb4ef8", "hashes": { "value": "eed5808509eb279fd342cafebadd5b95accb4ef8", "algo": 1 }, "download": "https://mc-api.yuaner.tw/files/mods/ApothicAttributes-1.21.1-2.9.0.jar", "downloadUrl": "https://mc-api.yuaner.tw/files/mods/ApothicAttributes-1.21.1-2.9.0.jar" } ] }

modsHash 字段是所有 mod 文件元数据(相对路径、修改时间、文件大小)的 SHA256 哈希值,使客户端能够在不下载完整列表的情况下检测更改。simple-md5 模式提供了一种轻量级格式,非常适合快速完整性检查。

来源:public/mods.php, src/McModUtils/Mod.php

单个 Mod 信息端点

通过文件名检索特定 mod 文件的详细元数据。此端点用于在下载前验证 mod 的存在性和元数据。

端点模式GET /:modType/:filename

参数

参数类型描述
filename路径参数JAR 文件名(例如 ftb-quests-forge-2001.2.0.jar
download查询参数设置为 1 以触发直接文件下载

示例请求GET /mods/ftb-quests-forge-2001.2.0.jar

此端点返回与列表端点相同的 mod 对象结构,但仅针对单个文件。可选的 download=1 参数为那些更倾向于基于 API 的下载而不是静态文件服务的应用程序提供了直接下载机制。

来源:public/mods.php, src/McModUtils/Mod.php

下载单个 Mod 文件(PHP 后端)

通过 PHP 后端直接下载特定的 mod 文件。当 Nginx 直接文件服务不可用时,此端点用作后备方案。

端点模式GET /:modType/:filename/download

响应头

Content-Type: application/java-archive Content-Disposition: attachment; filename="ftb-quests-forge-2001.2.0.jar" Content-Length: [file size] X-Served-By: PHP

这种基于 PHP 的下载方法仅适用于后备场景。对于生产部署,请配置 Nginx 通过 /files/:modFolder/:file 路由直接提供 mod 文件,以获得显著更好的性能。PHP 后端会增加处理开销,这在处理大型 mod 文件或高请求量时会变得明显。

来源:public/mods.php, public/mods.php

直接文件下载端点

优化的下载端点,应在 Nginx 中配置以进行直接文件服务,而无需 PHP 处理。

端点模式GET /files/:modFolder/:filename

参数

参数类型选项描述
modFolder路径参数mods, clientmodsMod 文件夹映射
filename路径参数任何 JAR 文件要下载的文件

config.default.php 中的配置将每个 mod 类型映射到下载 URL 路径。例如,common mods 路径(/opt/minecraft/mc-server/mods)通过 /files/mods/ 提供,而 client mods 使用 /files/clientmods/

来源:public/mods.php, config.default.php

下载所有 Mod 为 ZIP

生成并下载包含来自特定类别的所有 mod 的 ZIP 存档,并根据文件夹更改进行智能缓存失效。

端点模式GET /:modType/zip

查询参数

参数类型默认值描述
forceBooleanfalse无论缓存如何,强制重新生成 ZIP

响应头

Content-Type: application/zip Content-Disposition: attachment; filename="BarianMcMods整合包common-20250727-0906.zip" Content-Length: [zip size] Cache-Control: no-cache, must-revalidate

ZIP 生成机制 将当前文件夹哈希(基于文件路径、时间戳和大小)与存储在 ZIP 文件注释元数据中的哈希进行比较。如果它们不同,则创建一个嵌入当前哈希的新 ZIP。这使得无需文件系统扫描即可进行高效的缓存验证。

来源:public/mods.php, src/McModUtils/Mods.php

Mod 解析系统

系统使用 基于优先级的解析器 从 JAR 存档中自动提取 mod 元数据,该解析器在回退到文件名解析之前会尝试多种 mod 格式标准。

NeoForge/Forge 解析器

NeoForge 和 Forge mod 都使用位于 META-INF/neoforge.mods.tomlMETA-INF/mods.toml 的类似 TOML 元数据文件。解析器使用正则表达式模式提取字段:

PHP

// displayName 提取 if (preg_match('/displayName\s*=\s*"([^"]+)"/', $tomlRaw, $m)) { $result['name'] = $m[1]; } // version 提取 if (preg_match('/version\s*=\s*"([^"]+)"/', $tomlRaw, $m)) { $result['version'] = $m[1]; } // authors 提取 if (preg_match('/authors\s*=\s*"([^"]+)"/', $tomlRaw, $m)) { $result['authors'] = [trim($m[1])]; }

Fabric 解析器

Fabric mod 使用位于 fabric.mod.json 的 JSON 元数据文件,其结构简单:

PHP

$jsonData = json_decode($raw, true); $result['name'] = $jsonData['name'] ?? ($jsonData['id'] ?? null); $result['version'] = $jsonData['version'] ?? null; $result['authors'] = is_array($jsonData['authors']) ? $jsonData['authors'] : [$jsonData['authors'] ?? []];

文件名回退解析器

当 mod 元数据文件不可用时,系统使用模式匹配从文件名中提取信息:

PHP

// 模式:modname-version-modloader 或 modname-version if (preg_match('/^(.+?)-((?:neoforge|forge|fabric)[\w.\\+\\-]*)$/i', $basename, $m)) { $modName = $m[1]; $version = $m[2]; } elseif (preg_match('/^(.+?)-(\d[\w.\\+\\-]*)$/', $basename, $m)) { $modName = $m[1]; $version = $m[2]; }

这种回退机制确保即使没有适当元数据的 mod 也能被识别和同步,尽管可靠性低于基于存档的解析。

来源:src/McModUtils/Mod.php, src/McModUtils/Mod.php, src/McModUtils/Mod.php

缓存机制

缓存系统通过存储解析的 mod 数据并避免重复的文件系统操作和存档解析,提供了显著的性能优化。

两级缓存策略

缓存元数据结构

缓存文件以 JSON 格式存储,具有以下结构:

JSON

json { "folder_hashed": "d9e9ae1ba3b4771ed389518777747fd38b641c25ef7a9a5ff2628e83d57f474d", "update_at": "2025-07-27T14:52:10+08:00", "mods": "O:21:\"serialized_mod_objects\"" }

文件夹哈希 通过以一致的顺序连接文件元数据来计算:

PHP

$hashComponents[] = $relativePath . '|' . $mtime . '|' . $size; sort($hashComponents); $hash = hash('sha256', implode("\n", $hashComponents));

这种方法确保对 mods 文件夹的任何更改(添加、删除、修改)都会使缓存失效,而无需手动清除缓存。

缓存文件命名

缓存文件使用 元哈希 命名,该哈希包含 mods 路径和过滤配置:

PHP

$hPath = md5(serialize($this->path)); $hIgnorePrefixs = md5(serialize($this->ignorePrefixs)); $hOnlyPrefixs = md5(serialize($this->onlyPrefixs)); $metaHashed = md5($hPath . '|' . $hIgnorePrefixs . '|' . $hOnlyPrefixs); // 缓存文件:mods-[metaHashed].json

这种设计确保过滤规则的更改(例如,切换服务端前缀过滤)会自动生成单独的缓存文件,从而防止返回不正确的 mod 列表。

缓存存储在 public/static/ 中,文件名如 mods-[hash].json。对于生产部署,请确保此目录可由 PHP 进程写入,并考虑配置 Nginx 直接提供这些静态文件以获得额外的性能提升。

来源:src/McModUtils/Mods.php, src/McModUtils/Mods.php, src/McModUtils/Mods.php

响应格式化和内容协商

ResponseFormatter 类根据客户端首选项提供智能的内容协商,支持 JSON 和 HTML 输出格式。

内容协商逻辑

格式化器通过以下优先级顺序确定输出格式:

  1. 查询参数覆盖?type=json?json=1 强制 JSON 输出
  2. Accept 头 :检查 HTTP Accept 头中的 application/json
  3. 默认 :对于基于浏览器的请求,回退到 HTML 输出

JSON 输出格式

JSON 响应使用 JSON_UNESCAPED_UNICODE 以正确支持国际字符,并包含适当的头:

Content-Type: application/json; charset=utf-8

HTML 输出格式

对于浏览器请求,系统生成递归 HTML 列表,以适当的转义显示嵌套数据结构。数组呈现为 <ul> 元素,对象显示其类名,URL 变为可点击的链接。

这种 HTML 回退使开发人员能够在浏览器中直接调试 API 响应,而无需额外工具。

来源:src/App/ResponseFormatter.php, public/mods.php

配置

Mod API 通过 config.default.php 中的 mods 部分进行配置。每种 mod 类型需要三个配置条目:

配置键类型描述示例
pathStringmods 文件夹的绝对路径/opt/minecraft/mc-server/mods
dl_urlpathString直接下载的 URL 路径/files/mods/
ignore_serverside_prefixBoolean过滤掉仅服务端 modtrue
only_serverside_prefixBoolean仅包含仅服务端 modfalse

全局 serverside_prefixs 数组定义了哪些文件名前缀表示服务端 mod:

PHP

'serverside_prefixs' => ['serveronly_', 'server_']

以这些前缀开头的文件会自动从客户端 mod 列表中排除,除非通过 server-mods 端点特别请求。

来源:config.default.php, src/McModUtils/Mods.php

使用示例

基本 Mod 列表检索

BASH

bash curl https://mc-api.yuaner.tw/mods?type=json # 强制刷新缓存 curl https://mc-api.yuaner.tw/mods?force=1 # 获取简化的 MD5 格式以进行完整性检查 curl https://mc-api.yuaner.tw/mods?simple-md5=1

客户端 Mod 同步

BASH

bash # 仅获取客户端 mod(排除服务端) curl https://mc-api.yuaner.tw/client-mods # 下载完整的客户端 mod 包 curl -O https://mc-api.yuaner.tw/client-mods/zip

单个 Mod 操作

BASH

bash # 获取 mod 元数据 curl https://mc-api.yuaner.tw/mods/ftb-quests-forge-2001.2.0.jar # 下载特定 mod curl -O https://mc-api.yuaner.tw/files/mods/ftb-quests-forge-2001.2.0.jar # 通过 PHP 后端下载的替代方法 curl -O https://mc-api.yuaner.tw/mods/ftb-quests-forge-2001.2.0.jar/download

与启动器集成

API 响应结构与多种启动器格式兼容:

  • Prism Launcher :使用 nameauthorsversionfilename 字段
  • CurseForge API :使用 fileNamedownloadUrlhashes 结构
  • ModUpdater :使用 sha1download 字段

这种兼容性使得可以与流行的 Minecraft 启动器无缝集成,而无需数据转换。

来源:public/mods.php, src/McModUtils/Mod.php

后续步骤

要全面了解 mod 解析系统,请参阅 Mod 解析系统 (NeoForge, Forge, Fabric) 。要详细了解缓存机制,请参阅 缓存机制和缓存失效 。对于服务器状态监控 API,请继续阅读 服务器状态 API