# CaCl2Backup 中文 | [English](README_EN.md) 一个功能完善的Minecraft服务器备份模组,专为Fabric设计。 ## 功能特性 - **三种备份触发器** - 支持定时间隔、每日定时、服务器关闭时三种独立触发器,可自由组合 - **可靠流式压缩** - 临时文件写入、完整 CRC 校验、完成后原子发布 - **自动清理** - 备份完成后自动清理过期备份,支持按数量和时间双重限制 - **完整恢复** - 支持从备份完整恢复世界存档 - **标签系统** - 为备份添加标签,便于识别和管理(特殊字符自动替换为下划线) - **序号操作** - 使用序号快速选择备份,无需输入完整文件名 - **实时状态** - 查看备份状态、配置信息和备份列表 - **热重载配置** - 无需重启服务器即可重载配置 - **自动重启还原** - 恢复备份后可选自动重启服务器完成还原 ## 系统要求 - Minecraft 26.0+(26.x 全系列) - Fabric Loader 0.15.0+ - Fabric API - Java 25+ ## 安装 1. 确保已安装Fabric Loader和Fabric API 2. 将模组JAR文件放入服务器的`mods`文件夹 3. 启动服务器,模组会自动生成配置文件 ## 命令参考 所有命令仅OP可执行,以`/backup`为前缀。 ### 基础命令 | 命令 | 描述 | 示例 | |------|------|------| | `/backup create [标签]` | 创建手动备份(可选标签) | `/backup create before_update` | | `/backup list` | 列出所有可用备份(显示序号) | `/backup list` | | `/backup status` | 显示当前配置和状态 | `/backup status` | | `/backup reload` | 重载配置文件 | `/backup reload` | | `/backup cleanup` | 手动执行清理旧备份 | `/backup cleanup` | ### 恢复与删除 | 命令 | 描述 | 示例 | |------|------|------| | `/backup restore <序号/文件名>` | 从指定备份恢复世界 | `/backup restore 1` | | `/backup delete <序号/文件名>` | 删除指定备份 | `/backup delete 2` | **提示:** 可以使用 `/backup list` 查看备份序号,然后直接用序号操作。 ### 配置命令 | 命令 | 描述 | 示例 | |------|------|------| | `/backup config` | 显示所有配置项 | `/backup config` | | `/backup config interval [<分钟>]` | 查看/设置备份间隔 | `/backup config interval 60` | | `/backup config maxbackups [<数量>]` | 查看/设置最大备份数量 | `/backup config maxbackups 20` | | `/backup config maxage [<天数>]` | 查看/设置备份最大保留天数 | `/backup config maxage 14` | | `/backup config autocleanup []` | 查看/设置自动清理 | `/backup config autocleanup on` | | `/backup config threads [<数量>]` | 兼容旧配置;可靠 ZIP 写入固定使用1个线程 | `/backup config threads` | | `/backup config level [<1-9>]` | 查看/设置压缩级别 | `/backup config level 6` | | `/backup config autorestart []` | 查看/设置还原后自动重启 | `/backup config autorestart on` | | `/backup config restartdelay [<秒>]` | 查看/设置自动重启延迟 | `/backup config restartdelay 60` | | `/backup config restartmessage [<消息>]` | 查看/设置重启提示消息({seconds}占位符) | `/backup config restartmessage "即将重启..."` | | `/backup config broadcastrestart []` | 查看/设置重启提示广播 | `/backup config broadcastrestart on` | | `/backup config trigger` | 查看所有触发器状态 | `/backup config trigger` | | `/backup config trigger interval []` | 查看/设置定时触发器 | `/backup config trigger interval on` | | `/backup config trigger server_stop []` | 查看/设置停服触发器 | `/backup config trigger server_stop on` | | `/backup config trigger schedule []` | 查看/设置每日定时触发器 | `/backup config trigger schedule on` | | `/backup config trigger schedule add ` | 添加定时时间点 | `/backup config trigger schedule add 03:00` | | `/backup config trigger schedule remove ` | 移除定时时间点 | `/backup config trigger schedule remove 03:00` | | `/backup config trigger schedule clear` | 清空所有时间点 | `/backup config trigger schedule clear` | ## 配置文件 配置文件位于:`config/cacl2backup.json` ```json { "backupIntervalMinutes": 30, "maxBackups": 10, "compressionThreads": 1, "compressionLevel": 6, "autoBackupEnabled": true, "autoCleanupEnabled": true, "maxBackupAgeDays": 7, "backupFolderName": "backups", "broadcastBackupMessages": true, "saveOnBackup": true, "autoRestartAfterRestore": false, "restartDelaySeconds": 60, "restoreRestartMessage": "服务器将在 {seconds} 秒后重启以完成还原...", "broadcastRestoreMessage": true, "triggers": { "interval": { "enabled": true, "interval_minutes": 30 }, "server_stop": { "enabled": false }, "schedule": { "enabled": false, "times": ["03:00", "15:00"] } } } ``` ### 配置项说明 | 配置项 | 类型 | 默认值 | 描述 | |--------|------|--------|------| | `backupIntervalMinutes` | int | 30 | 自动备份间隔(分钟),最小值1 | | `maxBackups` | int | 10 | 最大备份数量,超过此数量会自动删除最旧的备份 | | `compressionThreads` | int | 1 | 旧版兼容字段;可靠 ZIP 流固定使用1个写入线程 | | `compressionLevel` | int | 6 | 压缩级别(1-9),1最快压缩率最低,9最慢压缩率最高 | | `autoBackupEnabled` | boolean | true | 是否启用自动备份 | | `autoCleanupEnabled` | boolean | true | 是否启用自动清理旧备份 | | `maxBackupAgeDays` | int | 7 | 备份最大保留天数 | | `backupFolderName` | String | "backups" | 备份文件夹名称 | | `broadcastBackupMessages` | boolean | true | 是否向所有玩家广播备份消息 | | `saveOnBackup` | boolean | true | 备份前是否保存世界 | | `autoRestartAfterRestore` | boolean | false | 还原后是否自动重启服务器 | | `restartDelaySeconds` | int | 60 | 自动重启延迟秒数,最小值10 | | `restoreRestartMessage` | String | "服务器将在 {seconds} 秒后重启以完成还原..." | 重启提示消息,{seconds}会被替换为延迟秒数 | | `broadcastRestoreMessage` | boolean | true | 是否广播重启提示消息 | | `triggers.interval.enabled` | boolean | true | 启用定时备份触发器 | | `triggers.interval.interval_minutes` | int | 30 | 定时备份间隔(分钟) | | `triggers.server_stop.enabled` | boolean | false | 启用服务器关闭时备份触发器 | | `triggers.schedule.enabled` | boolean | false | 启用每日定时备份触发器 | | `triggers.schedule.times` | list | [] | 每日备份时间点(HH:mm格式,如["03:00","15:00"]) | ## 使用指南 ### 创建备份 **手动备份(推荐用于重要操作前):** ``` /backup create before_major_update ``` **查看备份列表:** ``` /backup list ``` 输出示例: ``` [CaCl2Backup] Available backups (5): 1. 2024-02-20 10:30:00 [before_update] - 125.3 MB 2. 2024-02-19 22:00:00 [auto] - 124.8 MB 3. 2024-02-19 10:00:00 - 123.5 MB ... ``` ### 恢复世界 **警告:恢复操作会覆盖当前世界存档!** 1. 查看备份列表获取序号: ``` /backup list ``` 2. 使用序号恢复: ``` /backup restore 1 ``` 3. 根据配置决定后续行为: - **autoRestartAfterRestore=false(默认)**:手动停止服务器完成恢复 - **autoRestartAfterRestore=true**:模组自动在指定延迟后重启服务器 4. 服务器启动时自动完成世界还原 **配置自动重启行为:** ``` /backup config autorestart on # 开启自动重启 /backup config restartdelay 60 # 设置延迟60秒 /backup config restartmessage "服务器将在 {seconds} 秒后重启..." # 自定义消息 /backup config broadcastrestart on # 开启广播 ``` ### 删除备份 使用序号删除: ``` /backup delete 2 ``` ## 备份触发方式 三种独立的触发器可自由组合使用: | 触发器 | 默认 | 说明 | |--------|------|------| | **Interval**(定时) | 开启 | 每隔 N 分钟自动备份 | | **Schedule**(每日定时) | 关闭 | 每天指定时刻备份(如凌晨 3:00 和下午 15:00) | | **Server Stop**(停服) | 关闭 | 服务器正常关闭时自动备份 | | 手动命令 | — | 随时执行 `/backup create [标签]` | 示例配置: ```json // 仅启用停服备份 + 每日凌晨3点备份,关闭定时间隔 "triggers": { "interval": { "enabled": false }, "server_stop": { "enabled": true }, "schedule": { "enabled": true, "times": ["03:00"] } } ``` ## 备份文件命名规则 ``` backup_YYYY-MM-DD_HH-mm-ss.zip # 无标签备份 backup_YYYY-MM-DD_HH-mm-ss_标签.zip # 带标签备份 ``` 示例: - `backup_2024-02-20_10-30-00.zip` - `backup_2024-02-20_10-30-00_before_update.zip` **标签命名规则:** - 只允许:字母 `a-zA-Z`、数字 `0-9`、下划线 `_`、连字符 `-` - 其他字符(空格、中文、特殊符号等)会自动替换为下划线 `_` ## 性能说明 ### 可靠压缩 ZIP 是顺序输出格式。模组现在固定使用单个流式写入器,避免旧版“多线程” 实际串行且会吞掉文件错误的问题。备份前会在服务器主线程上保存世界并暂停 世界文件的自动写入(游戏仍可继续运行),ZIP 直接读取冻结的世界目录,写 入临时文件并完整读取校验 CRC,验证成功后才原子移动为正式备份。备份全程 不在主线程上复制世界目录,因此超大世界也不会阻塞服务器 tick、不会触发 watchdog 强制关服。 ### 压缩级别对比 | 级别 | 压缩率 | 速度 | 适用场景 | |------|--------|------|----------| | 1-3 | ~40% | 最快 | 频繁备份、SSD存储 | | 4-6 | ~50% | 平衡 | 日常使用(推荐) | | 7-9 | ~55% | 较慢 | 存储空间紧张 | ## 最佳实践 1. **定期检查备份** - 定期运行 `/backup list` 确认备份正常创建 - 定期测试恢复流程确保备份可用 2. **合理设置保留策略** - `maxBackups` 和 `maxBackupAgeDays` 同时生效 - 建议保留至少3-5个有效备份 3. **重要操作前手动备份** - 更新模组前 - 重大建筑项目前 - 服务器版本升级前 4. **异地备份** - 定期将备份文件夹复制到其他位置 - 考虑使用云存储同步备份 ## 故障排除 ### 备份失败 **问题:** `Backup failed: World directory not found` **解决:** 模组会从 MinecraftServer 自动读取实际世界路径,包括自定义 `level-name`。请确认 `server.properties` 指向的世界存在且包含 `level.dat`。 ### 恢复后世界异常 **问题:** 恢复后世界数据不完整 **解决:** 1. 确保恢复完成后重启服务器 2. 检查备份文件是否完整(文件大小是否正常) 3. 尝试使用其他备份文件 ### 权限问题 **问题:** 无法执行命令 **解决:** 确保玩家已被设置为OP(使用 `/op 玩家名`)。 ## 开发信息 - **作者:** CaCl2 - **版本:** 1.2.0 - **许可证:** MIT - **Minecraft版本:** 26.0+(26.x 全系列) - **Fabric API版本:** 0.146.1+ ## 更新日志 ### 1.2.0 - **可靠备份** — 备份前冻结世界写入(不再整目录复制,超大世界不再触发 watchdog)、单线程流式 ZIP、CRC 完整校验、半成品原子发布和同秒文件名防覆盖 - **安全恢复** — 自定义世界路径、恢复前验证 `level.dat`、旧世界回滚目录、交换失败自动回滚、启动失败下次自动恢复 - **热重载** — 原位更新触发器引用并应用备份目录、压缩级别、保存和广播设置 - **线程安全** — Minecraft 消息和停服操作统一切回服务器线程,备份与恢复使用原子并发锁 - **配置安全** — 损坏 JSON 自动保留为 `.broken-*`,严格校验布尔值、每日时间、目录和嵌套配置 - **维护性** — 修复目录流泄漏、启用真实备份广播、清理崩溃遗留快照与半成品,并扩展回归测试 ### 1.1.2 - **修复** — 识别并修复旧版本已持久化的 `maxBackups=0`、`maxBackupAgeDays=0`、`autoCleanupEnabled=false` 损坏配置组合 - **改进** — 服务器启动及配置重载时立即清理积压备份,不再只在新备份完成后清理 - **改进** — 清理扫描和删除失败会写入日志,并报告扫描、选择和实际删除数量 - **测试** — 增加 40 个备份按上限保留 10 个及按保留天数清理的回归测试 ### 1.1.1 - **修复** — 自动清理旧备份功能失效的 bug(Gson 反序列化时未校验 `maxBackups`、`maxBackupAgeDays`、`autoCleanupEnabled` 三个字段的默认值,导致旧配置文件迁移后自动清理被静默禁用) - **修复** — 备份清理逻辑中 `else if` 导致按数量和按天数删除互相影响,修正为独立判断并精确保留 `maxBackups` 个备份 ### 1.1.0 - **备份触发器重构** — 新增三种独立触发器:Interval(定时)、Schedule(每日定时)、Server Stop(停服) - 触发器可任意组合,通过 `triggers` 配置节控制 - 旧配置文件自动迁移,原有 interval 设置不丢失 - 新增触发器命令:`/backup config trigger interval/schedule/server_stop` - 支持每日多时间点备份(如 `["03:00","15:00"]`) - 服务器关闭时支持同步备份(使用 `createBackupSync`) - Minecraft 版本支持扩展至 26.x 全系列(`>=26.0 <27.0`) - 移除旧命令 `/backup config autobackup`,统一使用 `trigger interval` - **安全修复** — Zip Slip 路径遍历防护、备份名路径过滤、TOCTOU 并发竞态修复 - Schedule 触发器 DST 夏令时正确性修复、并发列表安全、命令规范化 ### 1.0.2 - 重构恢复流程:移除 `/backup restarter` 命令,自动重启功能集成到 `/backup restore` - 新增配置项:`autoRestartAfterRestore`、`restartDelaySeconds`、`restoreRestartMessage`、`broadcastRestoreMessage` - 新增配置命令:`/backup config autorestart`、`/backup config restartdelay`、`/backup config restartmessage`、`/backup config broadcastrestart` ### 1.0.1 - 更新至 Minecraft 26.1.2 - 新增 GitHub Release 自动发布工作流 - Java 版本要求提升至 25+ ### 1.0.0 - 初始版本发布 - 多线程压缩支持 - 自动定时备份 - 自动清理旧备份 - 完整恢复功能 - 标签系统 - 序号快速选择 - 热重载配置