13 KiB
LTD-ManagerBot 模块文档
目录
快速开始
- 复制
src/main/resources/下的示例配置到config/ - 编辑
config/application.yaml— 设置数据库、API 地址、密钥 - 编辑
config/module.yaml— 取消注释并配置需要的模块 - 如需使用邀请码或白名单审计模块,将 SQL 模板放入
config/sql/ - 启动机器人
新模块必需的 application.yaml 配置
# 白名单系统 API (WhitelistAuditModule 必需)
whitelist-system:
url: "https://whitelist.your-server.top"
encrypted-token: "your-api-token-here"
基础设施模块
GroupMessagePollingModule (群消息轮询模块)
按固定间隔轮询 QQ 群消息历史,通过 SharedFlow<List<MsgHistorySpecificMsg>> 向其他模块分发消息。
- name: "talkGroup"
type: "GROUP_MESSAGE_POLLING_MODULE"
enabled: true
config:
target-group-id: 538751386 # 目标群号
poll-interval-millis: 5000 # 轮询间隔(毫秒),可选,默认5000
msg-history-check: 15 # 每次检查的历史消息数,可选,默认15
MailModule (邮件模块)
通过 SMTP 发送邮件。InvitationCodesModule 和 WhitelistAuditModule 会使用此模块。
- name: "talkGroup"
type: "MAIL_MODULE"
enabled: true
SMTP 设置在 application.yaml → mail: 段配置。
新模块
RCON 命令模块
类型: RCON_COMMAND_MODULE
允许指定用户在 QQ 群中执行 Minecraft RCON 命令。通过黑名单机制阻止危险操作,非授权用户无法执行。
执行流程
QQ群: "rcon list"
│
├── 用户不在 admin-ids 中 → 回复: "你没有权限执行 RCON 命令"
├── 命令匹配 command-blocklist → 回复: "命令已被阻止"
└── 通过 RCON 二进制执行 → 回复执行结果
配置示例
- name: "talkGroup"
type: "RCON_COMMAND_MODULE"
enabled: true
dependencies:
- name: "talkGroup"
type: "GROUP_MESSAGE_POLLING_MODULE"
config:
self-id: 3327379836
self-nick-name: "Bot"
command-prefix: "rcon" # QQ群触发前缀
admin-ids: [2561098830] # 允许执行RCON的QQ号
rcon-timeout-sec: 5 # RCON超时(秒)
command-blocklist: # 危险命令黑名单(前缀匹配)
- "stop"
- "restart"
- "op"
- "deop"
- "whitelist"
- "ban"
- "ban-ip"
- "kick"
- "debug"
- "execute"
配置项
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
self-id |
long | 是 | — | 机器人 QQ 号 |
self-nick-name |
string | 是 | — | 机器人昵称 |
command-prefix |
string | 是 | — | QQ 群触发前缀 |
admin-ids |
long[] | 是 | — | 允许执行 RCON 的 QQ 号列表 |
command-blocklist |
string[] | 是 | — | 危险命令黑名单(不区分大小写,自动去除 / 前缀) |
rcon-timeout-sec |
long | 否 | 5 |
RCON 超时时间(秒) |
RCON 二进制路径和配置文件路径从 application.yaml → tools.rcon 读取。
黑名单匹配规则
黑名单使用前缀匹配,自动去除前置 /:
"stop"阻止:stop,stop 10s,/stop,/minecraft:stop"ban"阻止:ban Steve,ban-ip,/ban等
Gitea Webhook 模块
类型: GITEA_WEBHOOK_MODULE
启动嵌入式 HTTP 服务器,接收 Gitea Webhook 事件,格式化后推送通知到 QQ 群。
支持的事件类型
| 事件 | QQ 消息格式 |
|---|---|
push |
推送者、分支、提交数、前5条提交摘要、对比链接 |
issues |
操作(已创建/已关闭/已重新打开)、标题、内容预览、链接 |
pull_request |
操作、分支流转(head → base)、状态、链接 |
create |
创建的分支/标签、创建者 |
delete |
删除的分支/标签、操作者 |
release |
标签名、版本名、内容预览、草稿/预发布标记 |
repository |
仓库操作(已创建/已删除/已转移) |
fork |
源仓库 → Fork 仓库 |
配置示例
- name: "talkGroup"
type: "GITEA_WEBHOOK_MODULE"
enabled: true
config:
webhook-port: 8080 # 监听端口
webhook-path: "/gitea-webhook" # Webhook 路径
webhook-secret: "your-webhook-secret" # HMAC-SHA256 密钥
target-group-id: 538751386 # 推送 QQ 群号
events: # 监听事件列表(空=全部)
- "push"
- "issues"
- "pull_request"
- "create"
- "delete"
- "release"
配置项
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
webhook-port |
int | 是 | — | HTTP 服务器监听端口 |
webhook-path |
string | 否 | /gitea-webhook |
Webhook 端点路径 |
webhook-secret |
string | 否 | "" |
HMAC-SHA256 签名验证密钥,为空则跳过验证 |
target-group-id |
long | 是 | — | 推送通知的目标 QQ 群号 |
events |
string[] | 否 | 全部 | 监听的事件类型列表 |
Gitea 端设置
在 Gitea 仓库 → 设置 → Webhooks → 添加 Webhook → Gitea:
- 目标 URL:
http://<服务器IP>:8080/gitea-webhook - 密钥: 与
webhook-secret一致 - 触发条件: 勾选需要的事件
安全性
- 签名验证: 通过 HMAC-SHA256 验证
X-Gitea-Signature请求头 - 生产环境建议务必设置
webhook-secret
白名单审计模块
类型: WHITELIST_AUDIT_MODULE
定期检查白名单群成员与白名单 API 的一致性。自动拒绝已离开白名单群的用户,设置宽限期供用户通过主群关键词重新激活。支持管理员手动触发审计,输出详细逐人报告。
存储: MySQL ltd_manager_bot.whitelist_audit 表(首次加载自动建表)。
自动 vs 手动审计
| 自动审计 | 手动审计 | |
|---|---|---|
| 触发 | 每 N 分钟自动轮询 | 管理员在白名单群发关键词 |
| 群消息 | 不发送(安静) | 发送完整统计摘要 + 逐人详情 |
| 邮件 | 所有操作始终发送 | 所有操作始终发送 |
| 日志前缀 | [自动] |
[手动审计] |
生命周期状态
在白名单群中 ───────────────────────────────► 正常(无操作)
│
└── 用户退出群 ──► 检测到离群 ──► 已被拒绝(宽限期开始)
│
├── 主群发关键词 ──► 已重新激活
├── 进入警告窗口 ──► 邮件通知(仅一次)
└── 宽限期过 ──► 永久删除
配置示例
- name: "talkGroup"
type: "WHITELIST_AUDIT_MODULE"
enabled: true
dependencies:
- name: "talkGroup" # 主群轮询 (重新激活关键词)
type: "GROUP_MESSAGE_POLLING_MODULE"
- name: "whitelistGroup" # 白名单群轮询 (审计命令)
type: "GROUP_MESSAGE_POLLING_MODULE"
- name: "talkGroup" # 邮件模块 (enable-email:true 时)
type: "MAIL_MODULE"
config:
self-id: 3327379836
filter-qq-list: [2561098830, 3327379836]
audit-allowed-ids: [2561098830]
whitelist-group-polling-dep-name: "whitelistGroup"
audit-command-prefixes: # 支持多个关键词
- "审计"
- "audit"
re-activation-keywords:
- "重新激活"
- "激活白名单"
grace-period-days: 7
expiry-warning-days: 2
poll-interval-minutes: 60
enable-email: false
# 邮件模板 (空=使用内置默认,支持占位符)
email-reject-template: ""
email-warning-template: ""
email-removed-template: ""
email-reactivated-template: ""
配置项
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
self-id |
long | 是 | — | 机器人 QQ 号 |
filter-qq-list |
long[] | 是 | — | 保护列表,永不自动拒绝 |
audit-allowed-ids |
long[] | 是 | — | 允许执行手动审计的 QQ |
whitelist-group-polling-dep-name |
string | 是 | — | 白名单群轮询模块的依赖名 |
audit-command-prefixes |
string[] | 否 | ["审计"] |
白名单群触发手动审计的关键词(支持多个) |
re-activation-keywords |
string[] | 是 | — | 主群中触发重新激活的关键词列表 |
grace-period-days |
int | 是 | — | 被拒绝后允许重新激活的天数 |
expiry-warning-days |
int | 是 | — | 宽限期到期前多少天发送警告 |
poll-interval-minutes |
long | 否 | 60 |
自动审计间隔(分钟) |
enable-email |
boolean | 否 | false |
是否启用邮件通知(需 MailModule 依赖) |
email-reject-template |
string | 否 | "" |
拒绝邮件正文。占位符:${playerName} ${graceDays} ${keywords} |
email-warning-template |
string | 否 | "" |
过期警告邮件正文。占位符:${playerName} ${remainDays} ${keywords} |
email-removed-template |
string | 否 | "" |
删除邮件正文。占位符:${playerName} |
email-reactivated-template |
string | 否 | "" |
重新激活邮件正文。占位符:${playerName} ${graceDays} |
手动审计输出示例
审计完成
────────────────
白名单总数: 42
在群正常: 35 人
新发现不在群(已拒绝): 2 人
• Steve(123456789)
• Alex(987654321)
宽限期中: Notch(111222333, 剩5天)
已过期删除: 1 人
• Hero(444555666)
过滤列表跳过: 3 人
邮件去重
每类邮件只发送一次:
| 邮件 | 去重方式 |
|---|---|
| 拒绝 | 仅首次检测到离群时发送(existing == null) |
| 重新拒绝 | 仅之前已重新激活的用户再次离群时发送 |
| 即将过期警告 | warningSentTime == 0L 守卫,仅发一次 |
| 已删除 | 发送后立即从 DB 删除记录,不再匹配 |
| 重新激活 | 仅在宽限期内关键词触发成功时发送 |
状态持久化
审计状态存储在 MySQL ltd_manager_bot.whitelist_audit 表中(自动建表,零配置)。Bot 重启不丢失已标记的待处理记录。原先基于 JSON 文件的状态持久化已移除。
SQL 模板位于 config/sql/whitelist/:
create_audit_table.sql— 建表 DDLquery_all_audit.sql— 查全表query_audit_by_qq.sql— 按 QQ 查询upsert_audit.sql— 新增或更新delete_audit.sql— 删除记录
依赖关系
| 依赖模块 | 类型 | 是否必需 | 用途 |
|---|---|---|---|
| 主群轮询 | GROUP_MESSAGE_POLLING_MODULE |
是 | 监听主群重新激活关键词 |
| 白名单群轮询 | GROUP_MESSAGE_POLLING_MODULE |
是 | 监听审计命令 + 获取群成员列表 |
| 邮件模块 | MAIL_MODULE |
enable-email: true 时 |
发送邮件通知 |
白名单 API 配置
API 地址和密钥在 application.yaml 的 whitelist-system: 段配置(启动后自动加密):
whitelist-system:
url: "https://whitelist.your-server.top"
encrypted-token: "your-api-token-here"
邮件通知时机
| 触发条件 | 邮件主题 |
|---|---|
| 首次检测离群 → 被拒绝 | 白名单已被拒绝 — 含宽限期和关键词提示 |
| 重新激活后再离群 → 再次拒绝 | 白名单已被拒绝 — 同上 |
| 进入警告窗口 | 白名单即将过期 — 剩余天数 |
| 宽限期过 → 永久删除 | 白名单已删除 |
| 关键词重新激活成功 | 白名单已重新激活 — 提醒加群 |
配置参考
SQL 模板
部分模块(InvitationCodesModule、GroupRequestHandlerModule)使用 config/sql/ 下的 SQL 模板文件。模板使用 ${placeholder} 语法:
-- config/sql/invitation/query_qualification.sql
SELECT q.player_id, q.effective, q.is_used, q.qq, q.status
FROM ltd_manager_bot.qualified_user_info q
WHERE q.qq IN (${placeholders})
代码中使用:
val sql = SqlTemplate.fromFile("invitation/query_qualification.sql")
val result = sql.bind("placeholders" to "?, ?, ?")
消息过滤管道
所有消息驱动的模块使用统一的 TriggerMessageFilter 管道:
IgnoreSelfFilter → NewMessageFilter → KeywordFilter → [CooldownFilter] → handler
管道确保:机器人自己的消息被忽略、只处理新消息、只有匹配关键词的消息才会到达业务处理器。