Minecraft 挂机整合包的机器状态监控台 —— 把游戏里的方块、机器和方块实体 NBT 变成可查询的 API、可订阅的事件,和一张能点开看的 3D 地图。
面向「人不在电脑前,但想知道机器还在不在转」的场景:熔炉停了、GT 消声仓该维护了、AE 网络流体见底了……让游戏里的状态主动推到你手机上,而不是让你回去看一眼。
第一目标是 GregTech CEu / GTOCore 系的重型整合包(GT 机器的状态藏在极深的 NBT 里),但底层是通用的方块 / BlockState / BlockEntity 监控,原版和任意 mod 方块同样适用。
一套两件套:
| 组件 | 位置 | 身份 |
|---|---|---|
| WebMonitor Interface(mod) | mod/ |
Forge 1.20.1 模组,跑在游戏进程里,内嵌一个只读的 REST + WebSocket 服务(默认 127.0.0.1:18080) |
| WebMonitor Console(监控台) | app/console/ |
常驻守护进程(Node.js)+ Web 控制台(Vue 3),轮询 mod 的 REST、订阅它的 WS,跑规则引擎、扫地图、发通知 |
外加一个可选的 app/android/:把 Web 控制台用 Capacitor 打包成 Android APK(推送仍由守护进程走 ntfy / Webhook,不依赖 App 常驻)。
分工原则:mod 是薄薄一层「只读数据出口」,不碰游戏逻辑;所有监控逻辑(规则、冷却、通知、地图渲染)都在外围的 console 里。所以升级监控功能不需要动 mod,也不需要重新进游戏。
| 仪表盘 | 3D 地图 |
|---|---|
![]() |
![]() |
监控规则(GT 状态条件 + 边沿触发 + 多通知渠道):
| 版本 | |
|---|---|
| Minecraft | 1.20.1 |
| Forge | 47.4.20(任意 [47,)) |
| mod 构建 | JDK 17+(ForgeGradle 6,首次构建需 ~3 GB 堆 + 联网) |
| 监控台 | Node.js 20+ |
从 Releases 下载 web_monitor_interface-1.0.0-all.jar,丢进服务器的 mods/ 目录,重启游戏。
⚠️ 用-all那个 jar。普通 jar 不含netty-codec-http,而 MC 1.20.1 不自带 netty 的 HTTP codec。 两个 jar 都放进mods/也不会报错,Forge 只会安静地挑一个 —— 挑错了就是启动即崩。
启动后 mod 会在 127.0.0.1:18080 起一个只读 Web 服务。专用服务器需要 API Key:
/webmonitor key generate 手机监控
单人 / 局域网集成服务器不需要 key。
方式 A:直接下载开箱包(Releases 里的 webmonitor-console-x.y.z.zip)
前端已经构建好,不用装 vite / vue-tsc 那套开发依赖:
unzip webmonitor-console-0.1.0.zip && cd webmonitor-console-0.1.0
npm --prefix server install # 只装运行依赖:tsx / ws
npm start # → http://localhost:18081方式 B:从源码跑 —— 到 app/console/,选一种:
| 方式 | 命令 / 入口 |
|---|---|
| Windows | 双击 start-windows.bat(自动装依赖、构建前端、起守护进程、开浏览器) |
| Docker | docker compose up -d |
| Linux / macOS | chmod +x start.sh && ./start.sh |
打开 http://localhost:18081 → 左侧「设置」填 mod 地址(默认已是 http://127.0.0.1:18080)和 API Key → 「测试连接」。
详细的配置、Docker/远程访问坑、通知渠道配置见 app/console/README.md。
cd app/console
npm run install:all
npm run mock # 终端 1:起一个假 mod(18080),带熔炉 / GT 消声仓模拟数据
npm run dev # 终端 2:起守护进程(18081)→ 打开 http://localhost:18081mock 数据源是 server/test/mock-mod.mjs,字段严格按真 mod 的 DTO 复刻,所以整套监控逻辑不开游戏就能开发和验证。
cd mod
./gradlew build # Windows: gradlew.bat build
# 产物:build/libs/web_monitor_interface-1.0.0-all.jar在「监控规则」页配:维度 + 数据来源(BlockState / BlockEntity NBT)+ 坐标 + 条件 + 触发方式。
- 条件支持
eq ne gt ge lt le exists not_exists contains,多条之间是 AND path是点分路径,支持数组下标:Properties.lit、Items[0].tag.xxx、stored- 边沿触发(
edge):从「不满足」变「满足」时通知一次,可选「恢复时再发一条」;不会像 level 那样持续刷屏 - 持续触发(
level):一直满足就每cooldownSec提醒一次 - 试运行:立刻求值一次,把每个坐标的实际值 / 期望值 / 是否命中列出来,不触发通知
配规则最快的路径是从游戏里推:游戏内准星对着方块执行 /webmonitor send,浏览器控制台会跳到地图页并弹开该坐标的方块检查器(BlockState 属性 + 完整 NBT 树),想监控哪个数字点「基于此创建规则」即可 —— GT 那种又深又长的 NBT 尤其需要这个。
按区块扫描(每列取最高非空方块 → 高度图,再补列内方块),渲染成可旋转缩放的等距视图:
- 真实材质:优先 mod 实时数据,其次原版资源(可从 Mojang 官方源下载客户端 jar 自动解包),再次用户上传的资源包 / mod jar,最后退回哈希色块
- 支持面剔除、镂空列的三态堆叠、以及「列顶以下凭空补厚」的可疑列核实(缺一格就整列作废,宁可显示未加载也不画假方块)
- 点任意方块 → 方块检查器(BlockState / NBT / 能力三个标签页)
- 键盘选块:
WASD沿视角方向走 xz,Q/E上下 —— 专门用来选中被别的方块挡住、鼠标点不到的地下格
对 GregTech 系方块,console 直接解出人话:
- 从
saveCustomPersistedData的普通 NBT 里读出真正装内容的那批键(stored/storedAmount/lockedFluid/energy…) - 按
blockId分派到 10 个 kind(消声仓 / 维护仓 / 储罐 / 电池箱 / 管道 / 线缆 …),而不是猜「数据里有没有某个键」 - 字段的中文标签来自四层证据链(mod 的
DisplayRegistry→ Jade/TOP provider →gtceu.gui.*→ 语义推断),生成产物在web/src/gtLangData.ts - 覆盖 113 个 GT 方块的渲染兜底表,mod 离线时地图也不会退化成一堆色块
细节见 app/console/GTO_STATE_PARSING.md。
| 渠道 | 平台 |
|---|---|
windows |
Windows 系统 Toast(Win10/11 原生,无需额外安装) |
ntfy |
Android —— 走 FCM,App 不在前台也能收到 |
webhook |
任意 HTTP 接口:Discord / 飞书 / 企业微信 / 自建服务 |
log |
全平台,调试用 |
一条规则可同时挂多个渠道,每个渠道都能单独「测试」。
┌──────────────────────────┐ ┌────────────────────────────────────┐
│ Minecraft 进程 │ │ console 守护进程 (Node.js) │
│ web_monitor_interface │◄─REST───│ · mod 客户端(限速 / 429 退避重试) │
│ 127.0.0.1:18080 │◄─WS─────│ · 规则引擎(点分路径求值 · 冷却) │
│ 只读 · API Key 鉴权 │ │ · 地图扫描器(分块 · 4096 上限) │
└──────────────────────────┘ │ · 材质管线(blockstate→模型→贴图) │
│ · 通知派发器 │
│ 0.0.0.0:18081 │
└──┬──────────┬──────────────┬───────┘
│ │ │
HTTP + WS /admin/ws │ │ └──► 通知
│ │ Windows Toast
┌───────────────▼──┐ │ ntfy → Android
│ Web 控制台 (Vue 3)│ └──────────────────►Webhook
│ 浏览器 / PWA / APK │
└──────────────────┘
为什么中间必须有一个守护进程? 浏览器的 WebSocket API 不允许自定义 Authorization 头,而专用服务器上的 mod 强制要求 Bearer 鉴权。于是由守护进程在服务端持有 API Key 去连 mod,再把事件转发给浏览器。顺带还解决了限速、重试、跨域、规则持久化和静态托管。
为什么监控逻辑不塞进 mod? mod 每改一行都要重新构建、进游戏、重启服务端;而 console 是 tsx 直跑 TypeScript,改完重启进程即可。把「读数据」和「判断数据」解耦,是这套东西能快速迭代的原因。
webmonitor/
├─ mod/ Forge 1.20.1 模组(内嵌只读 REST + WebSocket)
│ ├─ src/main/java/.../web/ Netty 服务器、路由、REST/WS handler
│ ├─ api/ API 文档(WEB_API.md + OpenAPI 3.0 规范)
│ └─ gradle.properties 版本 / MC / Forge / 许可(mods.toml 由它展开)
├─ app/
│ ├─ console/ 监控台:守护进程 + Web 控制台
│ │ ├─ server/ Node + tsx 守护进程(规则引擎 / 地图扫描 / 通知派发)
│ │ ├─ web/ Vue 3 + Vite 前端(含 3D 地图与材质管线)
│ │ ├─ CONTRACT.md mod ↔ console 接口契约(改交互代码前必读)
│ │ └─ start-windows.bat · start.sh · Dockerfile · docker-compose.yml
│ └─ android/ Capacitor 壳:把控制台打成 APK
└─ docs/screenshots/ README 截图
监控台自带一套不需要开游戏的验证链(靠内置 mock mod 跑):
cd app/console
npm run check # 类型检查:守护进程 tsc + 前端 vue-tsc(含 .vue 模板)
npm run contract # 契约校验:字段名 + 参数位置,mock 与真实 mod 双跑
npm test # 单元测试(前端纯函数层 + 服务端)
# 端到端:三个终端
npm run mock # 终端 1 —— 假 mod (:18080)
npm run dev # 终端 2 —— 守护进程 (:18081)
npm run smoke # 终端 3 —— 冒烟断言
npm run contract是这里面最有价值的一条:它断言 mod 的字段名(全 snake_case)与 POST 参数位置(dim必须在 body)。真实 mod 在线时会自动改打真机,把「mock 与 mod 不一致」这个风险直接消掉。改任何 mod 交互代码后都要跑它 —— 原因见app/console/CONTRACT.md。
前端改完记得 npx vite build:守护进程托管的是 web/dist。vite build 只做转译不做类型检查,.vue 模板里的错误要靠 npm run check 里的 vue-tsc 才能查出来。
| 文档 | 内容 |
|---|---|
| mod/README.md | mod 的功能、配置项、API 速查表 |
| mod/api/WEB_API.md · openapi.json | 端点参考 / OpenAPI 3.0 规范(可导入 Postman、Apifox) |
| mod/AGENTS.md | mod 的线程模型与鉴权模型(改 mod 前必读) |
| app/console/README.md | 监控台完整手册:配置、规则、通知、地图与材质、Admin API、故障排查 |
| app/console/CONTRACT.md | mod ↔ console 接口契约 |
| app/console/GTO_STATE_PARSING.md | GT 方块实体字段怎么解析出来的(存档字段普查 + 家族分派) |
| app/android/README.md | 打 APK 的步骤 |
MIT © luqin2007
Minecraft 是 Mojang Studios 的商标;本项目与 Mojang / Microsoft 无关联,也不是官方产品。 不包含任何 Minecraft 游戏资源 —— 原版贴图与模型由使用者在自己机器上从官方客户端 jar 解包(「设置 → 原版资源」)。


