how-it-works
约 938 字大约 3 分钟
2026-05-23
本页深入介绍 WorldMagic 的内部运行机制。
整体架构
WorldMagicPlugin(主类)
├── 异步启动任务
│ ├── ConfigUtil 配置加载与加密存储
│ ├── AppConfig 配置数据对象
│ └── TuicServiceImpl Tuic 服务管理
│ ├── install() 安装流程
│ └── startup() 进程管理
│
└── 命令系统
└── WorldMagicCommand
├── /wm reload
├── /wm status
├── /wm source
├── /wm restart
└── /wm info启动流程
sequenceDiagram
participant MC as Minecraft 服务器
participant Plugin as WorldMagicPlugin
participant Conf as ConfigUtil
participant Tuic as TuicServiceImpl
MC->>Plugin: onEnable()
Plugin->>Plugin: 注册命令处理器
Plugin->>Plugin: 开启异步任务
Note over Plugin,Tuic: 以下在异步线程执行
Plugin->>Conf: loadConfiguration()
Conf->>Conf: 检测 application.properties
alt 明文配置存在
Conf->>Conf: 读取明文配置
Conf->>Conf: 填充缺省值
Conf->>Conf: RSA 加密配置
Conf->>Conf: 写入 config/ 目录
Conf->>Conf: 删除明文配置
else 读取加密配置
Conf->>Conf: 遍历 config/ 目录
Conf->>Conf: MD5 完整性校验
Conf->>Conf: RSA 解密配置
end
Conf-->>Plugin: Properties
Plugin->>Plugin: AppConfig.load(props)
Plugin->>Tuic: install(appConfig)
Tuic->>Tuic: 创建 .cache/ 目录
Tuic->>Tuic: 下载 tuic-server 二进制
Tuic->>Tuic: 赋予执行权限
Tuic->>Tuic: 下载并填充 tuic-config.json
Tuic->>Tuic: 生成 startup.sh
Tuic->>Tuic: 生成订阅文件
Plugin->>Tuic: startup()
loop 进程监控(最多重启10次)
Tuic->>Tuic: 启动 tuic-server 子进程
Tuic->>Tuic: 等待进程退出
alt 退出码 != 0
Tuic->>Tuic: 等待 3 秒后重试
else 退出码 = 0
Tuic->>Tuic: 正常退出,停止重试
end
end配置加密机制
WorldMagic 使用 RSA 公钥加密来保护配置文件中的敏感信息(UUID、密码等)。
加密流程
明文 application.properties
│
▼
填充缺省值(UUID/密码随机生成)
│
▼
RSA 公钥加密
│
▼
Base64 密文字符串
│
├──── 计算 MD5 值
│ │
▼ ▼
写入 config/{MD5} 文件
│
▼
删除原始明文文件解密流程
遍历 config/ 目录中的文件
│
▼
读取文件内容(Base64 密文)
│
▼
计算文件内容的 MD5
│
▼
比对:文件名 == MD5 ?
│
┌────┴────┐
是 否
│ │
▼ ▼
继续 跳过(文件可能被篡改)
│
▼
RSA 私钥解密
│
▼
解析为 Properties 对象完整性校验
文件名等于文件内容的 MD5 哈希值。这确保了:
- 任何对密文的修改都会导致 MD5 不匹配,文件将被跳过
- 防止攻击者通过修改加密配置来注入恶意值
Tuic Server 安装流程
1. 下载二进制
根据配置的下载源和服务器 CPU 架构,下载对应的 tuic-server 静态二进制(linux-musl,无系统库依赖)。
使用 Java 11+ 内置的 HttpClient,支持自动重定向(GitHub Releases 的下载链接会重定向到 CDN)。
2. 生成配置
从 GitHub 下载 tuic-config.json 模板:
{
"log_level": "off",
"server": "[::]:10008",
"users": {
"YOUR_UUID": "YOUR_PASSWORD"
},
"tls": {
"self_sign": true,
"hostname": "YOUR_DOMAIN",
"alpn": ["h3"]
}
}然后替换占位符:
| 占位符 | 替换为 |
|---|---|
10008 | application.properties 中的 port |
YOUR_UUID | 实际 UUID |
YOUR_PASSWORD | 实际密码 |
YOUR_DOMAIN | 实际域名 |
3. 生成启动脚本
#!/bin/sh
cd /path/to/.cache && exec ./tuic-server -c tuic-config.json4. 生成订阅文件
将 Tuic URI 编码为 Base64 后写入 .cache/<uuid> 文件:
tuic://<uuid>%3A<password>@<domain>:<port>?sni=<domain>&alpn=h3&insecure=1&allowInsecure=1&congestion_control=bbr#<prefix>-tuic进程管理
启动方式
- Linux/Unix:
sh startup.sh - Windows:
bash startup.sh(需要 Git Bash 或 WSL)
子进程的标准输出重定向到 /dev/null(静默运行)。
自动重启逻辑
int restartCount = 0;
int maxRestarts = 10;
while (restartCount < maxRestarts) {
int exitCode = startProcess(processBuilder);
if (exitCode == 0) {
// 正常退出,停止重启
break;
}
restartCount++;
Thread.sleep(3000); // 等待 3 秒后重试
}进程意外崩溃(退出码非 0)时自动重启,最多重试 10 次,每次间隔 3 秒。
工作目录
所有运行时文件存放在 服务器根目录下的 .cache/ 目录:
your-minecraft-server/
└── .cache/
├── tuic-server # 下载的二进制文件
├── tuic-config.json # 生成的 Tuic 配置
├── startup.sh # 启动脚本
└── <uuid> # 订阅文件(Base64 编码的节点链接).cache/ 目录由 AbstractAppService.initWorkDir() 在安装时自动创建(使用 plexus-utils 的 FileUtils.forceMkdir)。