在 Homepage 中集成 GameDig Widget:游戏服务器状态监控的配置指南与源码解析
【免费下载链接】homepageA highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.项目地址: https://gitcode.com/GitHub_Trending/ho/homepage
本指南面向在 Homepage 自建导航/仪表盘中部署 GameDig Widget 的开发者,讲解如何通过 services 配置为任意受支持的游戏服务器添加在线状态、地图、玩家数与延迟监控。你将掌握serverType、url、gameToken等核心参数的配置方法、可显示字段的选取规则,并通过源码链路理解数据从前端请求到 GameDig 探测返回的完整流程。
GameDig Widget 能做什么
GameDig 是一个基于 node-gamedig 库封装的 Homepage 服务组件。它本身不维护任何游戏协议实现,而是借助 GameDig 库统一封装了大量游戏服务器的查询协议,因此理论上任何 node-gamedig 支持的服务器类型(CS:GO/CS2、Minecraft、Valheim、ARK、Rust、Terraria 等数百种)都可以通过同一套配置接入 Homepage 仪表盘,实时展示:
- 服务器是否在线;
- 服务器名称与当前地图;
- 当前在线玩家数 / 最大玩家数;
- 机器人(Bots)数量;
- 网络延迟(Ping)。
快速开始:在 services.yaml 中配置 Widget
在 Homepage 的服务配置(默认骨架文件为 src/skeleton/services.yaml,实际运行时使用部署目录下的services.yaml)中,为一个服务条目添加widget块即可启用:
- 我的游戏服务器: - CS:GO 服务器: icon: sh-gamepad # 可选,按需指定 href: steam://connect/server.host.or.ip:port # 可选跳转地址 widget: type: gamedig serverType: csgo # 见 node-gamedig 的 games-list 文档 url: udp://server.host.or.ip:port gameToken: # 可选,部分游戏查询时需要的 token参数说明
| 参数 | 是否必填 | 说明 |
|---|---|---|
type | 必填 | 固定为gamedig,用于声明启用 GameDig Widget |
serverType | 必填 | 游戏服务器类型标识,如csgo、minecraft、valheim。完整取值列表以 node-gamedig 项目维护的 games-list 为准(node-gamedig 文档中的type字段列表,Homepage 直接透传给 GameDig 库) |
url | 必填 | 服务器地址,格式为udp://主机名或IP:端口(也支持其他协议前缀,见下文解析逻辑) |
gameToken | 可选 | 某些游戏(如部分使用独立 Query 认证的服务器)查询时需要携带的 token,配置后会被原样传递给 GameDig |
url 与 serverType 的匹配要点
url中的端口是 GameDig 发起探测的目标端口,serverType则决定使用哪套协议解析响应;两者必须与目标服务器实际运行的游戏及端口一致,否则查询将失败并显示为离线。serverType使用的是 GameDig 库内部的类型标识(例如csgo),并非游戏发行名;配置前应先在 node-gamedig 的 games-list 中确认目标游戏对应的准确标识。- 地址写法同时兼容域名与 IP,例如
udp://play.example.com:27015或udp://192.168.1.10:27015。
可显示字段与数量限制
GameDig Widget 允许在配置中通过fields控制展示哪些信息。允许的字段全集为(来自 docs/widgets/services/gamedig.md):
widget: type: gamedig fields: - status - name - map - currentPlayers - players - maxPlayers - bots - ping各字段含义如下:
| 字段 | 显示内容 | 离线时的表现 |
|---|---|---|
status | 在线状态(Online / Offline) | Offline |
name | 服务器名称 | - |
map | 当前地图 | - |
currentPlayers | 当前玩家数 / 最大玩家数(如5 / 10) | - |
players | 当前在线玩家数 | - |
maxPlayers | 最大玩家数 | - |
bots | 机器人数量 | - |
ping | 网络延迟(毫秒) | - |
字段展示规则(由源码确认)
在 src/widgets/gamedig/component.jsx 中,字段的选取遵循两条硬性规则:
- 默认字段:当配置中未指定
fields(或为空数组)时,自动使用["map", "currentPlayers", "ping"]三个字段; - 数量上限:无论配置了多少字段,最多只展示前 4 个(
MAX_ALLOWED_FIELDS = 4),超出部分会被截断。例如配置了全部 8 个字段,实际只会渲染前 4 个。
// 来自 src/widgets/gamedig/component.jsx if (widget.fields == null || widget.fields.length === 0) { widget.fields = ["map", "currentPlayers", "ping"]; } const MAX_ALLOWED_FIELDS = 4; if (widget.fields != null && widget.fields.length > MAX_ALLOWED_FIELDS) { widget.fields = widget.fields.slice(0, MAX_ALLOWED_FIELDS); }因此建议在配置时直接挑选最关心的 4 个字段,例如:
widget: type: gamedig serverType: minecraft url: udp://mc.example.com:25565 fields: - status - name - currentPlayers - ping字段的界面标签(Status、Map、Current players、Ping 等)由多语言文件 public/locales/en/common.json 中的gamedig命名空间提供,Homepage 会随界面语言自动切换。
源码剖析:数据链路如何工作
GameDig Widget 的完整请求链路为:前端组件 →/api/widgets/gamedig/status代理接口 → GameDig 库查询游戏服务器 → 返回结构化状态。下面沿着 src/widgets/gamedig/widget.js 与 src/widgets/gamedig/proxy.js 逐层拆解。
1. Widget 注册与端点约束
src/widgets/gamedig/widget.js 中声明了该 Widget 的代理处理器,并只允许status这一个端点被访问:
const widget = { proxyHandler: gamedigProxyHandler, allowedEndpoints: /status/, };前端通过 src/utils/proxy/use-widget-api.js 中的useWidgetAPI(widget, "status")发起请求(见 src/widgets/gamedig/component.jsx 第 9 行),因此实际只会命中status端点。
2. 代理处理器:组装 GameDig 查询参数
src/widgets/gamedig/proxy.js 是核心实现,其工作流程如下:
- 通过
getServiceWidget(group, service, index)从配置(或 Docker / Kubernetes 发现的服务)中取出当前服务的 widget 配置(见 src/utils/config/service-helpers.js); - 使用
new URL(serviceWidget.url)解析用户配置的地址,从中拆出主机名(hostname)与端口(port); - 组装 GameDig 查询选项并调用
GameDig.query(...):
const gamedigOptions = { type: serviceWidget.serverType, host: url.hostname, port: url.port, givenPortOnly: true, checkOldIDs: true, }; if (serviceWidget.gameToken) { gamedigOptions.token = serviceWidget.gameToken; } const serverData = await GameDig.query(gamedigOptions);这里有两个值得注意的实现细节:
givenPortOnly: true:只向配置中给定的端口发起查询,避免 GameDig 因某些游戏存在多个端口(如查询端口与游戏端口不同)而自动遍历探测;checkOldIDs: true:允许同时匹配已更名的游戏旧 ID,提升兼容性;gameToken:仅当配置了gameToken时才附加到查询选项中,且该字段在 src/utils/config/service-helpers.js 的 widget 白名单中(type === "gamedig"时透传gameToken),不会被误传给其他类型的 widget。
3. 响应数据结构化
查询成功后,代理将 GameDig 的原始返回映射为统一结构并返回 HTTP 200:
res.status(200).send({ online: true, name: serverData.name, map: serverData.map, players: serverData.numplayers ?? serverData.players?.length, maxplayers: serverData.maxplayers, bots: serverData.bots.length, ping: serverData.ping, });注意players字段对两种 GameDig 返回形态做了兼容:优先使用numplayers数字,否则回退到players数组的长度。
4. 离线与异常处理
当查询抛出异常(服务器不可达、超时、协议不匹配等)时,代理仍然返回 HTTP 200,但只包含online: false:
res.status(200).send({ online: false, });这样设计的目的是把"探测失败"作为一种正常业务状态交给前端处理,而不是让整个页面报错。前端组件会据此显示 Offline,并将各字段渲染为-(见 src/widgets/gamedig/component.jsx 第 41-50 行)。
5. 前端渲染
src/widgets/gamedig/component.jsx 在数据未返回时先渲染全部 8 个字段的占位块;数据到达后,按照前面提到的默认字段与 4 字段上限规则,只渲染用户关心的字段。ping字段还会通过highlightValue高亮展示,便于快速识别延迟异常。
测试验证:行为有据可依
该 Widget 的两类核心行为均有测试覆盖:
- src/widgets/gamedig/proxy.test.js 验证代理层两个关键场景:查询成功时返回
online: true及服务器详情(name、players、maxplayers 等);查询失败时返回online: false。 - src/widgets/gamedig/component.test.jsx 验证前端规则:未配置
fields时默认字段为["map", "currentPlayers", "ping"];配置 5 个字段时被截断为前 4 个,且在线状态渲染为5 / 10形式的玩家数。
完整配置示例:真实可用的仪表盘片段
将上述内容组合成一个完整的 services 片段(含多个服务器),可直接放入services.yaml使用:
- 游戏: - CS2 服务器: icon: sh-csgo href: https://www.dota2.com/play # 替换为你的实际入口 widget: type: gamedig serverType: csgo url: udp://cs.example.com:27015 fields: - status - map - currentPlayers - ping - Minecraft 服务器: icon: sh-minecraft widget: type: gamedig serverType: minecraft url: udp://mc.example.com:25565 gameToken: # 如服务器开启了查询认证,在此填写 token fields: - status - name - players - maxPlayers使用提示
- GameDig Widget 的请求由 Homepage 后端代理发出(而非浏览器直连),因此即使游戏服务器位于内网或仅 UDP 可达,只要 Homepage 所在主机能访问目标地址即可正常工作;
- 若服务器经常显示离线,优先检查:
serverType是否为目标游戏的准确类型标识、url端口是否与查询端口一致、目标服务器是否开启了查询响应(部分服务器需显式启用 Query 端口); - 该 Widget 也可用于通过 Docker 标签或 Kubernetes 注解发现的服务,只需在对应服务上声明同样的
widget块即可,配置字段完全一致; - 字段标签文案可通过 public/locales/en/common.json 的
gamedig命名空间及各语言翻译文件进行本地化,多语言支持由 next-i18next.config.js 驱动的国际化体系承载。
至此,你已掌握 GameDig Widget 从配置声明、字段控制到后端探测与前端渲染的完整链路,可以据此在 Homepage 中快速接入任意受支持的游戏服务器监控,并在遇到异常时按源码逻辑定位问题。
【免费下载链接】homepageA highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.项目地址: https://gitcode.com/GitHub_Trending/ho/homepage
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考