|
| 1 | +# 📝 配置文件自动更新说明 |
| 2 | + |
| 3 | +## ❓ 配置文件会自动更新吗? |
| 4 | + |
| 5 | +**答案**: ⚠️ **部分自动,需要注意** |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## 🔄 当前配置更新机制 |
| 10 | + |
| 11 | +### 1. 首次启动 (插件安装) |
| 12 | + |
| 13 | +✅ **完全自动**: |
| 14 | +```java |
| 15 | +// ConfigManager.java |
| 16 | +private void loadConfig() { |
| 17 | + plugin.saveDefaultConfig(); // 从 JAR 复制 config.yml 到插件目录 |
| 18 | + plugin.reloadConfig(); |
| 19 | + this.config = plugin.getConfig(); |
| 20 | +} |
| 21 | +``` |
| 22 | + |
| 23 | +**效果**: |
| 24 | +- 如果 `plugins/ConvenientAccess/config.yml` 不存在 |
| 25 | +- 自动从 JAR 包内的 `resources/config.yml` 复制 |
| 26 | +- ✅ 包含所有最新配置项 |
| 27 | + |
| 28 | +--- |
| 29 | + |
| 30 | +### 2. 插件更新 (升级版本) |
| 31 | + |
| 32 | +⚠️ **不会自动更新**: |
| 33 | +- Bukkit/Spigot 默认行为: `saveDefaultConfig()` 只在文件不存在时才复制 |
| 34 | +- 如果 `config.yml` 已存在,**不会覆盖** |
| 35 | +- ❌ 新增的配置项**不会自动添加** |
| 36 | + |
| 37 | +**问题场景**: |
| 38 | +```yaml |
| 39 | +# v0.4.0 的 config.yml (旧版本) |
| 40 | +api: |
| 41 | + auth: |
| 42 | + enabled: true |
| 43 | + admin-password: "xxx" |
| 44 | + api-token: "xxx" |
| 45 | + # ❌ 缺少新增的 login-attempt-limit 配置 |
| 46 | + |
| 47 | +# v0.5.0 的 config.yml (新版本) - 不会自动合并 |
| 48 | +api: |
| 49 | + auth: |
| 50 | + enabled: true |
| 51 | + admin-password: "xxx" |
| 52 | + api-token: "xxx" |
| 53 | + login-attempt-limit: # ✅ 新增配置 |
| 54 | + enabled: true |
| 55 | + max-attempts: 5 |
| 56 | + lock-duration-minutes: 15 |
| 57 | +``` |
| 58 | +
|
| 59 | +--- |
| 60 | +
|
| 61 | +## 🛠️ 解决方案 |
| 62 | +
|
| 63 | +### 方案1: 手动添加新配置项 (推荐) |
| 64 | +
|
| 65 | +**用户需要手动编辑 `config.yml` 添加**: |
| 66 | + |
| 67 | +```yaml |
| 68 | +api: |
| 69 | + auth: |
| 70 | + # ... 现有配置 ... |
| 71 | + |
| 72 | + # 👇 手动添加这部分 |
| 73 | + login-attempt-limit: |
| 74 | + enabled: true |
| 75 | + max-attempts: 5 |
| 76 | + lock-duration-minutes: 15 |
| 77 | +``` |
| 78 | + |
| 79 | +**优点**: |
| 80 | +- ✅ 保留现有配置 |
| 81 | +- ✅ 不会丢失自定义设置 |
| 82 | + |
| 83 | +**缺点**: |
| 84 | +- ❌ 需要用户手动操作 |
| 85 | +- ❌ 容易遗漏 |
| 86 | + |
| 87 | +--- |
| 88 | + |
| 89 | +### 方案2: 代码提供默认值 (已实现) ✅ |
| 90 | + |
| 91 | +**当前实现**: |
| 92 | +```java |
| 93 | +// 读取配置时提供默认值 |
| 94 | +boolean attemptLimitEnabled = config.getBoolean("api.auth.login-attempt-limit.enabled", true); |
| 95 | +int maxAttempts = config.getInt("api.auth.login-attempt-limit.max-attempts", 5); |
| 96 | +int lockDuration = config.getInt("api.auth.login-attempt-limit.lock-duration-minutes", 15); |
| 97 | +``` |
| 98 | + |
| 99 | +**效果**: |
| 100 | +- ✅ 即使配置文件中没有该项,代码也能正常工作 |
| 101 | +- ✅ 使用硬编码的默认值 |
| 102 | +- ⚠️ 用户无法通过查看配置文件知道有这个功能 |
| 103 | + |
| 104 | +--- |
| 105 | + |
| 106 | +### 方案3: 自动合并配置 (建议实施) 🎯 |
| 107 | + |
| 108 | +**实现思路**: |
| 109 | +```java |
| 110 | +public class ConfigManager { |
| 111 | + private void loadConfig() { |
| 112 | + plugin.saveDefaultConfig(); |
| 113 | + plugin.reloadConfig(); |
| 114 | + this.config = plugin.getConfig(); |
| 115 | + |
| 116 | + // 🆕 自动添加缺失的配置项 |
| 117 | + autoUpdateConfig(); |
| 118 | + } |
| 119 | + |
| 120 | + private void autoUpdateConfig() { |
| 121 | + boolean updated = false; |
| 122 | + |
| 123 | + // 检查并添加 login-attempt-limit 配置 |
| 124 | + if (!config.contains("api.auth.login-attempt-limit.enabled")) { |
| 125 | + config.set("api.auth.login-attempt-limit.enabled", true); |
| 126 | + updated = true; |
| 127 | + } |
| 128 | + if (!config.contains("api.auth.login-attempt-limit.max-attempts")) { |
| 129 | + config.set("api.auth.login-attempt-limit.max-attempts", 5); |
| 130 | + updated = true; |
| 131 | + } |
| 132 | + if (!config.contains("api.auth.login-attempt-limit.lock-duration-minutes")) { |
| 133 | + config.set("api.auth.login-attempt-limit.lock-duration-minutes", 15); |
| 134 | + updated = true; |
| 135 | + } |
| 136 | + |
| 137 | + if (updated) { |
| 138 | + plugin.saveConfig(); |
| 139 | + logger.info("配置文件已自动更新,添加了新的配置项"); |
| 140 | + } |
| 141 | + } |
| 142 | +} |
| 143 | +``` |
| 144 | + |
| 145 | +**优点**: |
| 146 | +- ✅ 完全自动,无需用户干预 |
| 147 | +- ✅ 保留现有配置 |
| 148 | +- ✅ 自动添加新配置项 |
| 149 | + |
| 150 | +**缺点**: |
| 151 | +- ⚠️ 需要为每个新配置项编写检查代码 |
| 152 | +- ⚠️ 版本升级时需要维护 |
| 153 | + |
| 154 | +--- |
| 155 | + |
| 156 | +### 方案4: 配置迁移系统 (最佳但复杂) |
| 157 | + |
| 158 | +**版本化配置管理**: |
| 159 | +```java |
| 160 | +public class ConfigMigrator { |
| 161 | + private static final String CONFIG_VERSION_KEY = "config-version"; |
| 162 | + private static final int CURRENT_VERSION = 2; |
| 163 | + |
| 164 | + public void migrate(FileConfiguration config) { |
| 165 | + int version = config.getInt(CONFIG_VERSION_KEY, 1); |
| 166 | + |
| 167 | + if (version < 2) { |
| 168 | + // 从版本1迁移到版本2 |
| 169 | + migrateV1toV2(config); |
| 170 | + } |
| 171 | + |
| 172 | + // 更新版本号 |
| 173 | + config.set(CONFIG_VERSION_KEY, CURRENT_VERSION); |
| 174 | + } |
| 175 | + |
| 176 | + private void migrateV1toV2(FileConfiguration config) { |
| 177 | + // 添加 login-attempt-limit 配置 |
| 178 | + if (!config.contains("api.auth.login-attempt-limit")) { |
| 179 | + config.set("api.auth.login-attempt-limit.enabled", true); |
| 180 | + config.set("api.auth.login-attempt-limit.max-attempts", 5); |
| 181 | + config.set("api.auth.login-attempt-limit.lock-duration-minutes", 15); |
| 182 | + logger.info("配置已从 v1 迁移到 v2: 添加登录失败限制功能"); |
| 183 | + } |
| 184 | + } |
| 185 | +} |
| 186 | +``` |
| 187 | + |
| 188 | +--- |
| 189 | + |
| 190 | +## 📋 当前状态 |
| 191 | + |
| 192 | +### 已有新配置项 (v0.5.0) |
| 193 | + |
| 194 | +```yaml |
| 195 | +api: |
| 196 | + auth: |
| 197 | + login-attempt-limit: |
| 198 | + enabled: true |
| 199 | + max-attempts: 5 |
| 200 | + lock-duration-minutes: 15 |
| 201 | +``` |
| 202 | + |
| 203 | +### 当前行为 |
| 204 | + |
| 205 | +1. **首次安装**: ✅ 自动包含新配置 |
| 206 | +2. **从旧版本升级**: ❌ 需要手动添加 |
| 207 | + |
| 208 | +### 代码行为 |
| 209 | + |
| 210 | +```java |
| 211 | +// 即使配置文件中没有,代码也会使用默认值 |
| 212 | +boolean attemptLimitEnabled = config.getBoolean( |
| 213 | + "api.auth.login-attempt-limit.enabled", |
| 214 | + true // 👈 默认启用 |
| 215 | +); |
| 216 | +``` |
| 217 | + |
| 218 | +--- |
| 219 | + |
| 220 | +## 🎯 推荐的升级步骤 |
| 221 | + |
| 222 | +### 对于用户 |
| 223 | + |
| 224 | +1. **备份现有配置**: |
| 225 | + ```bash |
| 226 | + cp plugins/ConvenientAccess/config.yml plugins/ConvenientAccess/config.yml.backup |
| 227 | + ``` |
| 228 | + |
| 229 | +2. **查看新配置示例**: |
| 230 | + - 解压 JAR 包查看 `resources/config.yml` |
| 231 | + - 或查看 GitHub/文档 |
| 232 | + |
| 233 | +3. **手动添加新配置项**: |
| 234 | + ```yaml |
| 235 | + # 在 api.auth 部分添加 |
| 236 | + login-attempt-limit: |
| 237 | + enabled: true |
| 238 | + max-attempts: 5 |
| 239 | + lock-duration-minutes: 15 |
| 240 | + ``` |
| 241 | + |
| 242 | +4. **重载插件**: |
| 243 | + ```bash |
| 244 | + /convenientaccess reload |
| 245 | + ``` |
| 246 | + |
| 247 | +### 对于开发者 (TODO) |
| 248 | + |
| 249 | +建议实施**方案3: 自动合并配置**: |
| 250 | + |
| 251 | +1. 在 `ConfigManager.java` 添加 `autoUpdateConfig()` 方法 |
| 252 | +2. 在 `loadConfig()` 中调用 |
| 253 | +3. 检查并添加缺失的配置项 |
| 254 | +4. 保存配置文件 |
| 255 | + |
| 256 | +--- |
| 257 | + |
| 258 | +## ⚠️ 注意事项 |
| 259 | + |
| 260 | +### 1. 配置文件格式 |
| 261 | +- YAML 格式严格要求**缩进** |
| 262 | +- 使用**空格**缩进,不要用 Tab |
| 263 | +- 每级缩进 **2个空格** |
| 264 | + |
| 265 | +### 2. 重载配置 |
| 266 | +```bash |
| 267 | +# 重载配置命令 |
| 268 | +/convenientaccess reload |
| 269 | +
|
| 270 | +# 或重启插件 |
| 271 | +/reload confirm # 不推荐,可能导致内存泄漏 |
| 272 | +``` |
| 273 | + |
| 274 | +### 3. 配置优先级 |
| 275 | +1. 配置文件中的值 (最高优先级) |
| 276 | +2. 代码中的默认值 (配置缺失时使用) |
| 277 | + |
| 278 | +--- |
| 279 | + |
| 280 | +## 📚 相关文件 |
| 281 | + |
| 282 | +- 📄 `/src/main/resources/config.yml` - 默认配置模板 |
| 283 | +- 📄 `ConfigManager.java` - 配置管理器 |
| 284 | +- 📄 `plugins/ConvenientAccess/config.yml` - 实际运行配置 |
| 285 | + |
| 286 | +--- |
| 287 | + |
| 288 | +## 🔄 未来改进计划 |
| 289 | + |
| 290 | +- [ ] 实现配置自动合并功能 |
| 291 | +- [ ] 添加配置版本管理 |
| 292 | +- [ ] 提供配置迁移向导 |
| 293 | +- [ ] 生成配置变更日志 |
| 294 | +- [ ] 支持配置热重载 |
| 295 | + |
| 296 | +--- |
| 297 | + |
| 298 | +**最后更新**: 2025年10月3日 |
| 299 | +**适用版本**: v0.5.0+ |
0 commit comments