dsh-mc-server-ops
Minecraft server ops via RCON with static command blocking, pluggable local/Pterodactyl adapters, configurable community voting, and multi-layer process detection for Paper, Forge, Fabric, and vanilla servers. The QQ group surface requires the @tencent-connect/dsh-qqbot plugin first; the local adapt
Install
dsh plugin --profile web add dsh-mc-server-ops
Sandbox test
This plugin has not been tested yet. Submit a test →
README
dsh-mc-server-ops
把一台 Minecraft 服务器托管到 DeepSeek Harness 里的插件:QQ 群里的群友可以直接查状态、看日志、绑定游戏名,服主可以启停服务器、改配置、修 KubeJS 配方。
插件本身只是「服务器操作 + 人设」这一层,聊天通道由 QQ 机器人插件提供。
安装前请先装好并配置 @tencent-connect/dsh-qqbot(见下方「前置插件」),否则装上了也没有入口。
前置插件(必须)
插件 · 作用 · 获取
@tencent-connect/dsh-qqbot · QQ 群/私聊通道:把群消息送进 Harness,把回复发回群里 · npm / DSH 插件市场
没有它,本插件仍然会加载 mc_server 工具(本地 GUI 会话里可以用),但群里没人能触发它。
它做什么
- 状态:进程、在线玩家、CPU、内存、TPS、磁盘、运行时长,并给出「正常 / 卡顿 / 无响应假死 / 启动中」判定
- 启停:start / stop / restart;假死自动强杀重启;确认关闭或假死时玩家也能重启
- 日志:最近日志(过滤 RCON 噪音)、最近一次崩溃的上下文
- 白名单:QQ ↔ 游戏名绑定,自动写入
whitelist.json(保留大小写,避免离线 UUID 不匹配) - 配方:
kubejs脚本备份 / 重载 - 授权:动受保护区域(world、ops\data、白名单)要 2 位群友投票;凑满 2 票之前任何人反对就作废
- 人设:默认「小铜」,名字和语气都能在设置里改
安装
# 1) 先装 QQ 机器人插件并配好 AppID / AppSecret dsh plugin add @tencent-connect/dsh-qqbot # 2) 再装本插件 dsh plugin add dsh-mc-server-ops
本地开发可以直接指向目录:
dsh plugin add /path/to/dsh-mc-server-ops
安装后重启 DSH,在「设置 → 插件 → mc-server-ops」里填服务器目录。
配置(设置界面可改)
字段 · 默认 · 说明
server.dir · 空 · 服务器目录(含 server.properties、mods、java)。留空则读环境变量 MC_SERVER_DIR,再不行用 D:\server
server.rconPort · 25575 · RCON 端口,需在 server.properties 里 enable-rcon=true
server.rconPassword · 空 · 留空则从 server.properties 读取
persona.enabled · true · 是否注入人设
persona.name · 小铜 · 助手在群里的名字
persona.text · 空 · 人设正文;留空用内置默认(小铜)。改人设就改这里,不用动代码
persona.scope · qq · qq 只注入 QQ 群/私聊;all 所有会话;none 关闭
ops.allowPlayerWrite · true · 允许玩家改服务器目录下非敏感文件
ops.grantHours · 12 · 服主确认后可编辑文件/执行命令的有效时长
adapter · local · 写操作走哪条路:local 本机脚本;panel Pterodactyl 面板 HTTP API
panel.url · 空 · 面板地址,adapter=panel 时必填
panel.serverId · 空 · 面板里该服务器 URL 最后一段(8 位短 ID)
panel.clientApiKey · 空 · 客户端 API Key(ptlc_ 开头)
vote.approveNeed · 2 · 通过需要几位群友同意
vote.rejectNeed · 1 · 几位反对就作废(1 = 一票否决)
vote.timeoutMinutes · 15 · 多久没凑够门槛自动作废
vote.vetoEnabled · true · 是否允许一票否决;关掉后反对票只记录、不作废
vote.protectedPaths · world, ops/data, whitelist · 改动这些位置需要群友投票放行
bridge.enabled · false · 是否启用群服互通(游戏聊天 → QQ 群)
bridge.mode · auto · auto 有玩家在线才转发 / on 常开 / off 常关
bridge.groups · [] · 转发到哪些群(群 openid)
bridge.events · join/leave 关、death 开 · 除聊天外还转发哪些事件
bridge.coalesceMs · 3000 · 固定合并窗口(coalesce.mode=fixed 时用)
bridge.coalesce.mode · auto · 合并窗口:auto 按最近发言节奏 + 在线人数自动调整 / fixed 固定
bridge.coalesce.minMs / maxMs · 1000 / 6000 · 自动模式的最短 / 最长等待
bridge.coalesce.sampleSize · 3 · 用最近几条发言算节奏(2–6)
bridge.coalesce.quietMs · 20000 · 超过这么久没说话算冷场,直接按最短等待
bridge.coalesce.fullPlayers · 6 · 在线人数达到这个值算「人多」
bridge.coalesce.fastMs · 2000 · 相邻两条发言间隔小于这个值算「话密」
bridge.maxPerDay · 900 · 每群每天发送上限(官方上限 1000)
bridge.appId / appSecret · 空 · 留空自动从本机 qqbot 插件配置读取
目录结构
dsh-mc-server-ops/
├── index.js # 插件宿主代码:mc_server 工具、权限守卫、人设注入
├── cordis.patch.yml # 安装时自动插入的加载行
└── ops/
├── command-guard.mjs # 静态命令拦截:出网前掐掉“一条命令搞崩整个服”的类型
├── qq-bridge.mjs # 群服互通:读日志 → 直连 QQ 开放平台(不经过 AI)
├── coalesce.mjs # 合并窗口计算:最近发言节奏 + 在线人数 → 等多久再发(纯函数)
├── rcon.mjs # 跨平台核心:RCON、进程探测、日志、状态汇总
├── rcon-probe.mjs # 极简 RCON 探测(查在线玩家)
├── adapters/ # 写操作适配器:local(本机脚本)/ panel(Pterodactyl)
├── mcadmin.ps1 # 运维入口(status/start/stop/投票/白名单…)
├── watchdog.ps1 # 看门狗:崩溃自动拉起
└── server-console.ps1 # 带日志着色的服务器控制台
首次运行时插件会把 ops/*.ps1 复制到 <服务器目录>\ops\(rcon.mjs 留在包里直接调用,不复制),运行期数据(bindings.json、votes.json、state.json、owners.json)也生成在那里,不会写进本仓库。
服主和群友:怎么区分、怎么绑定
默认所有人都是群友:只能查状态、看日志、问问题。
服主名单存在 <服务器目录>\ops\data\owners.json,只有名单里的 QQ 能执行高危动作(stop / restart / cmd / 白名单 / 导出等)。
绑定服主(只在设置面板里做)
1. 打开「设置 → MC 服务器 → 服主绑定」
2. 在输入框里填对方的 QQ openid,点「添加为服主」
3. 名单会立刻刷新,每行右边有「移除」
QQ openid 怎么拿: 群消息开头都是 [昵称 (ID)],括号里那串就是(例如 [蘑菇来吃鱼 (34EB...CB)])。群友自己不知道的话,在群里 @ 机器人 问一句「我的 ID 是多少」,它会原样念出来——这串 ID 本来在群里就可见,不算秘密。
服务器本机的等价命令:
powershell -File <服务器目录>\ops\mcadmin.ps1 -Action owner-add -Arg <openid> -Actor LOCAL-CONSOLE
名单为空时这条命令不需要权限(引导用),一旦有了服主就只有服主能加人;群聊、私聊里都不能自行提权。
其他
owner-list查看名单、owner-del移除(后两个仅服主)- 群友无法通过任何方式给自己提权;改 world / ops\data / 白名单这种受保护区域必须走投票
功能开关(设置界面里逐项开关)
权限分成两层:基础权限(授权窗口、玩家能不能改文件)和功能开关(下面这 9 项)。关掉的那一项,玩家调用时插件会直接拒绝并说明原因,不会走到脚本;服主不受影响。
开关 · 默认 · 关掉之后
voteEscalation 投票放权 · 开 · 只有服主能改 world / ops\data / 白名单
kubejsEdit 改 KubeJS 配方 · 开 · 玩家改 kubejs/ 被拒
configEdit 改配置 · 开 · 玩家改 config / defaultconfigs / server.properties 被拒
playerStart 玩家开服 · 开 · 服务器关着也只有服主能开
playerRestart 玩家重启 · 开 · 崩溃/假死时也只有服主能重启
playerStop 玩家停服 · 关 · 玩家永远不能停服
gamemodeSwitch 切模式 · 开 · 玩家不能把自己切生存/旁观
say 游戏内广播 · 开 · 玩家不能 say
fileSend 发文件到群 · 开 · 玩家不能把文件发到群里
投票门槛也能改:vote.approveNeed(默认 2 位同意)、vote.rejectNeed(默认 1 位反对即作废)、vote.timeoutMinutes(默认 15 分钟)、vote.vetoEnabled(关掉后反对票只记录、不作废)、vote.protectedPaths(哪些位置算受保护区域,默认 world / ops/data / whitelist)。保存后会写进 ops\data\vote-config.json,脚本每次调用时读它。
命令拦截(静态,绕不过去)
ops/command-guard.mjs 是 RCON 出网前的最后一道闸,只拦“一条命令就能把服搞崩”的类型:
拦截项 · 谁能发
kill @a / kill @e / kill @r / kill * · 谁都发不了
kick @a / kick @e · 谁都发不了
whitelist off / whitelist clear · 谁都发不了
execute ... run kill @a · 谁都发不了(换个写法也绕不过)
stop · 只有服主
op / deop / execute / ban 这类正常管理指令不拦——它们本来就是 cmd 的用途,只在插件层限制“只有服主能发”。say / tell / msg / title 等聊天类前缀直接放行,避免把聊天内容误判成指令。
同一套规则在两处生效:插件层(index.js)判身份,PowerShell 层(mcadmin.ps1 的 Assert-CommandSafe)兜底——直接调脚本也拦得住。
连接方式:本机 / Pt
…(truncated)
Rendered from the README published on npm. Formatted only, not edited.
Versions
Published on npm::5,最后更新 2026-11-06