LTD-ManaagerBot/docs/en/modules.md

12 KiB

LTD-ManagerBot Module Documentation

Table of Contents


Quick Start

  1. Copy the example configs from src/main/resources/ to config/
  2. Edit config/application.yaml — set database, API URLs, tokens
  3. Edit config/module.yaml — uncomment and configure desired modules
  4. Place SQL templates in config/sql/ if using InvitationCodes or WhitelistAudit
  5. Launch the bot

Minimal application.yaml additions for new modules

# Whitelist System API (required by WhitelistAuditModule)
whitelist-system:
  url: "https://whitelist.your-server.top"
  encrypted-token: "your-api-token-here"

Infrastructure Modules

GroupMessagePollingModule

Polls a QQ group's message history at a fixed interval and emits a SharedFlow<List<MsgHistorySpecificMsg>>. Other modules subscribe to this flow to react to messages.

- name: "talkGroup"
  type: "GROUP_MESSAGE_POLLING_MODULE"
  enabled: true
  config:
    target-group-id: 538751386
    poll-interval-millis: 5000   # optional, default 5000
    msg-history-check: 15        # optional, default 15

MailModule

Queues and sends emails via SMTP. Used by InvitationCodesModule and WhitelistAuditModule.

- name: "talkGroup"
  type: "MAIL_MODULE"
  enabled: true

SMTP settings go in application.yamlmail: section.


New Modules

RCON Command Module

Type: RCON_COMMAND_MODULE

Allows specified QQ users to execute arbitrary Minecraft RCON commands via QQ group messages, with a configurable blocklist to prevent dangerous operations.

Workflow

QQ Group: "rcon list"
    │
    ├── User NOT in admin-ids → reply: "no permission"
    ├── Command matches blocklist → reply: "blocked"
    └── Execute via RCON binary → reply with output

Example Config

- 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"
    admin-ids: [2561098830]
    rcon-timeout-sec: 5
    command-blocklist:
      - "stop"
      - "restart"
      - "op"
      - "deop"
      - "whitelist"
      - "ban"
      - "ban-ip"
      - "kick"
      - "debug"
      - "execute"

Config Reference

Field Type Required Default Description
self-id long yes Bot's QQ ID
self-nick-name string yes Bot's display name
command-prefix string yes Trigger prefix in QQ group
admin-ids long[] yes QQ IDs allowed to execute RCON
command-blocklist string[] yes Blocked command prefixes (case-insensitive, /-prefix stripped)
rcon-timeout-sec long no 5 RCON timeout in seconds

The RCON binary path and config path are read from application.yamltools.rcon.

Blocklist Matching

The blocklist uses prefix matching after stripping leading /:

  • "stop" blocks: stop, stop 10s, /stop, /minecraft:stop
  • "ban" blocks: ban Steve, ban-ip, /ban, etc.

Gitea Webhook Module

Type: GITEA_WEBHOOK_MODULE

Starts an embedded HTTP server to receive Gitea webhook events and forwards formatted notifications to a QQ group.

Supported Events

Event QQ Message Format
push Author, branch, commit count, first 5 commit messages, compare URL
issues Action (opened/closed/reopened), title, body preview, link
pull_request Action, branches (head → base), state, link
create Branch/tag created, author
delete Branch/tag deleted, author
release Tag name, release name, body preview, draft/prerelease flags
repository Action (created/deleted/transferred)
fork Source repo → forked repo

Example Config

- name: "talkGroup"
  type: "GITEA_WEBHOOK_MODULE"
  enabled: true
  config:
    webhook-port: 8080
    webhook-path: "/gitea-webhook"
    webhook-secret: "your-webhook-secret"
    target-group-id: 538751386
    events:
      - "push"
      - "issues"
      - "pull_request"
      - "create"
      - "delete"
      - "release"

Config Reference

Field Type Required Default Description
webhook-port int yes HTTP server listen port
webhook-path string no /gitea-webhook Webhook endpoint path
webhook-secret string no "" HMAC-SHA256 secret for signature verification
target-group-id long yes QQ group to send notifications to
events string[] no all Event types to listen for

Gitea-side Setup

In your Gitea repository → SettingsWebhooksAdd WebhookGitea:

  • Target URL: http://<server-ip>:8080/gitea-webhook
  • Secret: Same as webhook-secret
  • Trigger On: Select desired events

Security

  • Signature verification: X-Gitea-Signature header validated via HMAC-SHA256
  • Empty webhook-secret disables verification (not recommended for production)

Whitelist Audit Module

Type: WHITELIST_AUDIT_MODULE

Periodically checks the whitelist group membership against the whitelist API. Automatically rejects users who left the group, with a configurable grace period for re-activation via keywords in the main group. Supports admin-triggered manual audits with detailed per-user reporting.

Storage: MySQL ltd_manager_bot.whitelist_audit table (auto-created on first load).

Auto vs Manual Audit

Auto Audit Manual Audit
Trigger Every N minutes (poll-interval) Admin sends keyword in whitelist group
Group messages Silent (none) Full summary with per-user detail
Email Always sent for every action Always sent for every action
Log prefix [自动] [手动审计]

Lifecycle States

In Whitelist Group ───────────────────────────────► OK (no action)
    │
    └── User left group ──► Detected ──► Rejected (grace period starts)
                                │
                                ├── Keyword in main group ──► Re-Activated
                                ├── Warning threshold ──► Email sent (once)
                                └── Grace period expired ──► Permanently Removed

Example Config

- 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"          # only if 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 templates (omit = use built-in defaults)
    email-reject-template: ""
    email-warning-template: ""
    email-removed-template: ""
    email-reactivated-template: ""

Config Reference

Field Type Required Default Description
self-id long yes Bot's QQ ID
filter-qq-list long[] yes QQ IDs never auto-rejected
audit-allowed-ids long[] yes QQ IDs allowed to trigger manual audit
whitelist-group-polling-dep-name string yes Dependency name for the whitelist group polling module
audit-command-prefixes string[] no ["审计"] Keywords to trigger manual audit (multiple)
re-activation-keywords string[] yes Keywords to re-activate from main group
grace-period-days int yes Days user has to re-activate after being rejected
expiry-warning-days int yes Days before expiry to send warning
poll-interval-minutes long no 60 Auto-audit interval in minutes
enable-email boolean no false Enable email notifications (requires MailModule)
email-reject-template string no "" Rejection email body. Placeholders: ${playerName} ${graceDays} ${keywords}
email-warning-template string no "" Expiry warning email body. Placeholders: ${playerName} ${remainDays} ${keywords}
email-removed-template string no "" Removal email body. Placeholders: ${playerName}
email-reactivated-template string no "" Re-activation email body. Placeholders: ${playerName} ${graceDays}

Manual Audit Output Example

审计完成
────────────────
白名单总数: 42
在群正常: 35 人
新发现不在群(已拒绝): 2 人
  • Steve(123456789)
  • Alex(987654321)
宽限期中: Notch(111222333, 剩5天)
已过期删除: 1 人
  • Hero(444555666)
过滤列表跳过: 3 人

Email Deduplication

Emails are sent exactly once per event:

Email Guard
Rejection Only on first detection (existing == null)
Re-rejection Only when previously-reactivated user leaves again
Expiry warning warningSentTime == 0L — sent once
Removal Record deleted from DB after send — never repeats
Re-activation Only on successful keyword-triggered approve

State Persistence

Audit state is stored in MySQL ltd_manager_bot.whitelist_audit table (auto-created, zero config). Survives bot restarts. Historical JSON file-based state is no longer used.

SQL templates are in config/sql/whitelist/:

  • create_audit_table.sql — DDL
  • query_all_audit.sql — fetch all records
  • query_audit_by_qq.sql — fetch by QQ
  • upsert_audit.sql — insert or update
  • delete_audit.sql — remove record

Dependencies

Dependency Type Required Purpose
Main group polling GROUP_MESSAGE_POLLING_MODULE yes Re-activation keyword monitoring
Whitelist group polling GROUP_MESSAGE_POLLING_MODULE yes Audit command monitoring + member list
Mail module MAIL_MODULE if enable-email: true Email notifications

Whitetelist API Config

API URL and token are in application.yaml whitelist-system: section for security (auto-encrypted):

whitelist-system:
  url: "https://whitelist.your-server.top"
  encrypted-token: "your-api-token-here"

Configuration Reference

SQL Templates

Some modules (InvitationCodesModule, GroupRequestHandlerModule) use SQL templates stored in config/sql/. Templates use ${placeholder} syntax:

-- 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})

Usage in code:

val sql = SqlTemplate.fromFile("invitation/query_qualification.sql")
val result = sql.bind("placeholders" to "?, ?, ?")

Message Filter Pipeline

All message-driven modules use a common TriggerMessageFilter pipeline:

IgnoreSelfFilter → NewMessageFilter → KeywordFilter → [CooldownFilter] → handler

This ensures messages from the bot itself are ignored, only new messages are processed, and only keyword-matching messages reach the handler.