docker-minecraft-server 自动执行 RCON 命令全解:五大钩子时机与源码级实现机制
【免费下载链接】docker-minecraft-serverDocker image that provides a Minecraft Server for Java Edition that automatically installs/upgrades versions, modloaders, modpacks and more at startup项目地址: https://gitcode.com/GitHub_Trending/do/docker-minecraft-server
docker-minecraft-server(itzg/minecraft-server镜像)支持在服务器生命周期中的关键节点自动执行 RCON 命令,涵盖五个钩子:服务器启动、客户端连接、客户端断开、首个客户端连接、末位客户端断开。读完本篇,你将掌握如何用 Compose 环境变量配置这些自动命令(含多行 YAML 书写技巧)、理解底层守护脚本的状态机触发逻辑与执行顺序,并能把"新手玩家规则""预生成暂停/恢复"等自动化场景落地到你的 Minecraft 服务器中。
一、功能概述:能自动化哪些操作
自动 RCON 命令功能允许你在以下五个时机让服务器自动执行一条或多条控制台命令:
| 环境变量 | 触发时机 | 典型用途 |
|---|---|---|
RCON_CMDS_STARTUP | 服务器启动并进入监听状态后 | 预生成区块、禁用火焰扩散、初始化队伍 |
RCON_CMDS_ON_CONNECT | 任意客户端连接(在线人数上升) | 给新玩家发物品、移入队伍 |
RCON_CMDS_ON_DISCONNECT | 任意客户端断开(在线人数下降) | 恢复游戏规则、清理实体 |
RCON_CMDS_FIRST_CONNECT | 首个客户端连接(0 → 有人) | 停止预生成等维护任务 |
RCON_CMDS_LAST_DISCONNECT | 末位客户端断开(有人 → 0) | 清理实体、重启维护任务 |
这些变量全部为可选(默认空)。只要其中任意一个非空,镜像启动流程就会拉起 RCON 命令守护进程;全部留空则该功能完全不启用。完整的变量定义可参见 docs/variables.md 中的 RCON 段落,其中还定义了配套变量:ENABLE_RCON(默认true,禁用会同时削弱交互式彩色控制台等依赖 RCON 的特性)、RCON_PASSWORD(默认随机生成,官方文档明确标注必须修改)、RCON_PORT(默认25575)、RCON_PASSWORD_FILE(从文件/Secrets 读取密码,推荐用于敏感数据管理,见 server-properties.md)。
二、Compose 配置写法:多行命令务必使用|-块样式
由于每个钩子可以包含多条命令,在 Compose 文件的环境变量中声明多行内容时,最省事、最不容易出错的写法是使用 YAML 的|-块样式指示符(clip 块标量:保留内部换行,同时去掉首尾空行;若用不带-的|,则首尾会各多出空行):
服务器启动时执行:
RCON_CMDS_STARTUP: |- gamerule doFireTick false pregen start 200客户端连接时执行:
RCON_CMDS_ON_CONNECT: |- team join New @a[team=]注意:连接事件只告诉你"有客户端连上来了",并不携带具体是谁连上——需要通过 RCON 命令(如选择器、队伍筛选)自行判断目标玩家。
客户端断开时执行:
RCON_CMDS_ON_DISCONNECT: |- gamerule doFireTick true首个客户端连接时执行:
RCON_CMDS_FIRST_CONNECT: |- pregen stop末位客户端断开时执行:
RCON_CMDS_LAST_DISCONNECT: |- kill @e[type=minecraft:boat] pregen start 200三、完整实战示例:新手玩家规则
下面这套组合利用New/Old两个队伍跟踪玩家状态,是官方文档给出的完整示例:把无队伍玩家移入New队,执行欢迎命令(发放白桦船),再移入Old队;同时首人上线时停止预生成、末人下线时清理船只并恢复预生成。命令前的/前缀可写可不写(下例保留了):
RCON_CMDS_STARTUP: |- /pregen start 200 /gamerule doFireTick false /team add New /team add Old RCON_CMDS_ON_CONNECT: |- /team join New @a[team=] /give @a[team=New] birch_boat /team join Old @a[team=New] RCON_CMDS_FIRST_CONNECT: |- /pregen stop RCON_CMDS_LAST_DISCONNECT: |- /kill @e[type=minecraft:boat] /pregen start 200仓库中还提供了一个可直接运行的完整 Compose 实例 examples/docker-compose-rconcmd.yml:基于TYPE: FABRIC服务器,通过CURSEFORGE_FILES安装fabric-api与chunky-pregenerator两个模组,然后把上面"队伍 + 预生成"的自动化映射到 chunky 命令上:
environment: EULA: "TRUE" TYPE: FABRIC MEMORY: "2G" CURSEFORGE_FILES: | fabric-api chunky-pregenerator RCON_CMDS_STARTUP: |- /gamerule doFireTick false /team add New /team add Old /chunky radius 1000 /chunky start RCON_CMDS_ON_CONNECT: |- /team join New @a[team=] /give @a[team=New] birch_boat /team join Old @a[team=New] RCON_CMDS_FIRST_CONNECT: |- /chunky pause RCON_CMDS_LAST_DISCONNECT: |- /kill @e[type=minecraft:boat] /chunky continue四、源码级实现:从启动链到守护进程状态机
4.1 功能如何被启用
功能入口在 scripts/start-configuration:启动流程会检查五个RCON_CMDS_*变量,只要有一个非空就打印Starting RCON commands并执行 scripts/start-rconcmds。该脚本做的事很明确:
- 为五个
RCON_CMDS_*变量和RCON_CMDS_PERIOD设置默认值(空 / 10)并全部导出; - 对
RCON_CMDS_PERIOD做防御性校验——isNumericElseSetToDefault(非数字则回退 10)与checkIfNotZeroElseSetToDefault(为 0 则回退 10,两个函数定义于 scripts/start-utils,并输出[init]警告); - 以后台进程方式拉起守护脚本
auto/rcon-cmds-daemon.sh &。
也就是说,轮询周期RCON_CMDS_PERIOD默认 10 秒,且必须为正整数,这决定了连接/断开事件的检测粒度。
4.2 守护进程的两段式状态机
真正的调度逻辑在 scripts/auto/rcon-cmds-daemon.sh,它分两个阶段:
阶段一(INIT):等待服务器真正就绪。先轮询java_process_exists(每 0.1 秒检查 java 进程是否存在),再调用mc_server_listening确认服务器进入监听状态后才执行RCON_CMDS_STARTUP。mc_server_listening复用自 scripts/auto/autopause-fcns.sh,底层用mc-monitor status探测SERVER_HOST:SERVER_PORT。执行完成后有一个值得注意的分支:若四个连接/断开类钩子全部为空,守护进程打印No addition rcon commands are given, stopping rcon cmd service后直接exit 0——只配了RCON_CMDS_STARTUP时不需要常驻进程。
阶段二(II):轮询在线人数变化。每RCON_CMDS_PERIOD秒调用java_clients_connections(同样是mc-monitor status --show-player-count)读取当前在线人数,并与上一轮记录的CLIENTCONNECTIONS比较,触发条件与执行顺序(源码内注释明确写了优先级考量)如下:
- FIRST_CONNECT 最先执行:
0 → 有人时触发。源码注释写道 "on first client connection is usually to STOP maintence, aka DO THIS FIRST"——首个玩家上线通常意味着要停掉维护任务,所以它被安排在最前面,避免维护任务与ON_CONNECT的欢迎命令争抢服务器资源; - ON_CONNECT:当前人数 > 上次人数时触发。注意这是"人数上升"判断而非"恰好 +1",一轮周期内多人同时上线只会触发一次;
- ON_DISCONNECT:当前人数 < 上次人数时触发,同样是"人数下降"的粗粒度判断;
- LAST_DISCONNECT 最后执行:
有人 → 0时触发。注释说明其典型用途是"重启维护,放最后做",确保所有断开类命令执行完才开始后台维护。
4.3 容错设计:ping 失败按"有人在线"处理
java_clients_connections(scripts/auto/autopause-fcns.sh)里有一个关键容错:当mc-monitor探测失败时,把在线人数按1处理,注释解释为"避免一个有玩家连接但卡顿的服务器被误判为空"。对自动 RCON 命令的意义在于:网络抖动或服务器繁忙导致的探测失败不会误触发LAST_DISCONNECT里的清理/维护命令,宁可漏报不可错杀。
4.4 命令如何真正发出
每条命令通过run_command执行:先logRcon "running - <cmd>"记日志(日志前缀为[Rcon loop]),再调用容器内的rcon-cli发送,随后把服务器返回输出再记一条日志(见 rcon-cmds-daemon.sh)。rcon-cli的认证信息由启动流程提前写入:scripts/start-configuration 会把RCON_PASSWORD写入~/.rcon-cli.env与~/.rcon-cli.yaml,因此守护进程能以正确的凭据直连 RCON 端口。多行命令的解析方式为按行切分后逐行rcon-cli执行,行内转义通过echo -e展开。
五、使用边界与排错要点
结合上述源码实现,实际部署时需要注意:
- 事件是周期轮询驱动的,不是实时事件:
RCON_CMDS_PERIOD决定检测延迟(默认 10 秒),且只检测人数"净变化"。同一周期内一个玩家进、一个玩家出,净变化为 0,两个钩子都不会触发。 - 启动钩子只执行一次,且在服务器真正接受连接之后;如果启动命令依赖的模组/插件此时未就绪,命令会执行失败但流程不重试——从
[Rcon loop]日志里可以看到每条命令的实际返回。 ENABLE_RCON=false会使整套机制失效,因为它会移除 RCON 支持,而守护进程完全依赖rcon-cli发令。- 修改 RCON 端口请用
RCON_PORT(默认25575),官方文档在 docs/configuration/server-properties.md 中特别强调不要通过server.properties改rcon.port,否则会破坏镜像自身的集成。 - 敏感凭据建议走
RCON_PASSWORD_FILE+ Docker Secrets(/run/secrets/rcon_pass)而不是明文RCON_PASSWORD,这一模式在 ssh.md 示例中有完整写法。 - 只配 STARTUP 时守护进程会自我退出,属正常行为;若日志出现
Error: invalid state:则说明状态机异常,可结合DEBUG=true复现排查。
六、延伸阅读
- 完整环境变量清单:docs/variables.md(含
RCON_CMDS_*五项定义) - 手动/交互式发令方式:docs/sending-commands/commands.md、websocket.md、ssh.md
- 可复制的 Compose 实例:examples/docker-compose-rconcmd.yml
- 相关自动化:autopause/autostop 与 RCON 命令共用同一套
mc-monitor人数探测函数(scripts/auto/autopause-fcns.sh),可配合 docs/misc/autopause-autostop/ 下的文档了解暂停/停止逻辑。
【免费下载链接】docker-minecraft-serverDocker image that provides a Minecraft Server for Java Edition that automatically installs/upgrades versions, modloaders, modpacks and more at startup项目地址: https://gitcode.com/GitHub_Trending/do/docker-minecraft-server
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考