修复:配置写入 MCDR 数据目录,删除后可正确重建 (26.9.15)

This commit is contained in:
SKYMirror committed 2026-09-14 01:19:38 +08:00
1 parent 18e13a861b
commit b3187e30d4
5 files changed
+77 -75

No files matched your search

+12
View File
@@ -5,6 +5,18 @@ This file records notable changes to Iridium.
--- ---
## [26.9.15] - 2026-09-14
### 修复 / Fixed
- 配置文件写到错误路径导致「删掉后重载不生成」:改用 MCDR 数据目录 `config/iridium/iridium.json`(`get_data_folder`)
- Config written to the wrong path so delete+reload did not recreate it; now uses MCDR data folder `config/iridium/iridium.json`
### 变更 / Changed
- 文档中的配置路径更新为 `config/iridium/iridium.json`
- Docs updated to the correct config path
---
## [26.9.14] - 2026-09-14 ## [26.9.14] - 2026-09-14
### 修复 / Fixed ### 修复 / Fixed
+2 -2
View File
@@ -4,7 +4,7 @@ MCDReforged 插件:物品展示 / 戴头 / 获取头颅 / 游戏内计算器 /
| | | | | |
|---|---| |---|---|
| 版本 | **26.9.14** | | 版本 | **26.9.15** |
| 作者 | 云镜之端/SKYMirror | | 作者 | 云镜之端/SKYMirror |
| 许可 | 保留所有权益(All Rights Reserved) | | 许可 | 保留所有权益(All Rights Reserved) |
| 前置 | MCDReforged `>= 2.6.0` | | 前置 | MCDReforged `>= 2.6.0` |
@@ -79,7 +79,7 @@ rcon.password=your_password
## 配置 ## 配置
路径:`config/iridium.json`(首次加载自动生成) 路径:`config/iridium/iridium.json`(首次加载自动生成;若存在旧文件 `config/iridium.json` 会自动迁移)
```json ```json
{ {
+2 -2
View File
@@ -4,7 +4,7 @@ MCDReforged plugin: item share / wear on head / player head / calculator / join
| | | | | |
|---|---| |---|---|
| Version | **26.9.14** | | Version | **26.9.15** |
| Author | 云镜之端/SKYMirror | | Author | 云镜之端/SKYMirror |
| License | All Rights Reserved | | License | All Rights Reserved |
| Requires | MCDReforged `>= 2.6.0` | | Requires | MCDReforged `>= 2.6.0` |
@@ -48,7 +48,7 @@ rcon.password=your_password
## Config ## Config
Path: `config/iridium.json` (auto-created with comments on first load) Path: `config/iridium/iridium.json` (auto-created on first load; migrates legacy `config/iridium.json` if present)
| Field | Default | Description | | Field | Default | Description |
|------|---------|-------------| |------|---------|-------------|
+60 -70
View File
@@ -1,4 +1,5 @@
import json import json
import shutil
from datetime import date from datetime import date
from pathlib import Path from pathlib import Path
from typing import List, Optional from typing import List, Optional
@@ -29,13 +30,7 @@ class Config(Serializable):
motd_enabled: bool = True motd_enabled: bool = True
# 开服日期,格式 YYYY-MM-DD;默认为配置生成当天(当天算第 1 天) # 开服日期,格式 YYYY-MM-DD;默认为配置生成当天(当天算第 1 天)
motd_start_day: str = _today() motd_start_day: str = _today()
# MOTD 文本行。支持: # MOTD 文本行
# {player} 玩家名
# {days} 开服天数
# {online} 在线人数(拿不到时显示 ?)
# {link:显示文字|https://url} 可点击链接
# {link:https://url} 链接,显示为完整 URL
# § 颜色代码
motd_lines: List[str] = [ motd_lines: List[str] = [
"§6欢迎 §e{player}§6 加入服务器!", "§6欢迎 §e{player}§6 加入服务器!",
"§7服务器已开服 §b{days}§7 天", "§7服务器已开服 §b{days}§7 天",
@@ -44,7 +39,10 @@ class Config(Serializable):
] ]
CONFIG_FILE = "config/iridium.json" # MCDR data folder: config/<plugin_id>/iridium.json
CONFIG_FILE_NAME = "iridium.json"
# 旧路径(仅用于迁移)
LEGACY_CONFIG_FILE = "config/iridium.json"
def build_default_config_text() -> str: def build_default_config_text() -> str:
@@ -95,7 +93,6 @@ def build_default_config_text() -> str:
""" """
# 兼容旧引用
DEFAULT_CONFIG_TEXT = build_default_config_text() DEFAULT_CONFIG_TEXT = build_default_config_text()
# 模块级单例;on_load 时原地更新字段,避免各模块持有过期引用 # 模块级单例;on_load 时原地更新字段,避免各模块持有过期引用
@@ -147,80 +144,73 @@ def _strip_json_comments(text: str) -> str:
return "".join(out) return "".join(out)
def _candidate_paths(server: PluginServerInterface) -> List[Path]: def config_file_path(server: PluginServerInterface) -> Path:
"""Possible config file locations, best first.""" """Canonical path: MCDR data folder → config/iridium/iridium.json"""
paths: List[Path] = [] return Path(server.get_data_folder()) / CONFIG_FILE_NAME
seen = set()
def add(p: Path) -> None:
try:
rp = p.expanduser().resolve()
except Exception:
rp = p
key = str(rp)
if key not in seen:
seen.add(key)
paths.append(rp)
def _legacy_path(server: PluginServerInterface) -> Path:
try: try:
wd = server.get_mcdr_config().get("working_directory") wd = server.get_mcdr_config().get("working_directory") or "."
if wd: return (Path(wd) / LEGACY_CONFIG_FILE).expanduser().resolve()
add(Path(wd) / CONFIG_FILE)
except Exception: except Exception:
pass return Path.cwd() / LEGACY_CONFIG_FILE
try:
add(Path.cwd() / CONFIG_FILE)
except Exception:
pass
# Fallback: next to CWD if MCDR launched from elsewhere
add(Path.cwd() / "config" / "iridium.json")
return paths
def config_path(server: PluginServerInterface) -> Path: def _write_commented_default(path: Path, server: PluginServerInterface) -> bool:
"""Prefer an existing file; else the first writable candidate."""
candidates = _candidate_paths(server)
for p in candidates:
if p.is_file():
return p
return candidates[0]
def ensure_config_file(server: PluginServerInterface) -> Path:
"""Create commented default config if missing. Always returns absolute path."""
path = config_path(server)
try: try:
path.parent.mkdir(parents=True, exist_ok=True) path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(build_default_config_text(), encoding="utf-8")
server.logger.info(f"已生成配置文件: {path}")
return True
except Exception as e: except Exception as e:
server.logger.error(f"无法创建配置目录 {path.parent}: {e}") server.logger.error(f"写入配置文件失败 {path}: {e}")
return path return False
if not path.is_file():
try:
path.write_text(build_default_config_text(), encoding="utf-8") def _migrate_legacy(server: PluginServerInterface, dest: Path) -> None:
server.logger.info(f"已生成配置文件: {path}") """If old config/iridium.json exists, copy it to the data folder path."""
except Exception as e: src = _legacy_path(server)
server.logger.error(f"写入配置文件失败 {path}: {e}") try:
return path if src.is_file() and src.resolve() != dest.resolve() and not dest.is_file():
dest.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(src, dest)
server.logger.info(f"已从旧路径迁移配置: {src} -> {dest}")
except Exception as e:
server.logger.warning(f"迁移旧配置失败 {src}: {e}")
def load_config(server: PluginServerInterface) -> Config: def load_config(server: PluginServerInterface) -> Config:
"""Load config; recreate a commented default whenever the file is missing.""" """
path = ensure_config_file(server) Load config using MCDR's official data folder (config/iridium/iridium.json).
1. Prefer that path; create commented default if missing
2. Migrate legacy config/iridium.json if present
3. Fallback: load_config_simple
"""
path = config_file_path(server)
_migrate_legacy(server, path)
if not path.is_file(): if not path.is_file():
server.logger.warning(f"配置文件不存在且无法创建,使用内存默认值: {path}") _write_commented_default(path, server)
return Config()
if path.is_file():
try:
raw = path.read_text(encoding="utf-8")
data = json.loads(_strip_json_comments(raw))
server.logger.info(f"配置已加载: {path}")
return Config.deserialize(data)
except Exception as e:
server.logger.error(f"读取/解析配置失败 {path}: {e},尝试 load_config_simple")
# Official MCDR loader as last resort
try: try:
raw = path.read_text(encoding="utf-8") cfg = server.load_config_simple(
CONFIG_FILE_NAME,
target_class=Config,
in_data_folder=True,
)
server.logger.info(f"配置已通过 load_config_simple 加载: {path}")
return cfg
except Exception as e: except Exception as e:
server.logger.error(f"读取配置失败 {path}: {e},使用默认值") server.logger.error(f"load_config_simple 失败: {e},使用内存默认值")
return Config()
try:
data = json.loads(_strip_json_comments(raw))
except json.JSONDecodeError as e:
server.logger.error(f"配置文件 JSON 解析失败 {path}: {e},使用默认值")
return Config()
try:
return Config.deserialize(data)
except Exception as e:
server.logger.error(f"配置反序列化失败 {path}: {e},使用默认值")
return Config() return Config()
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"id": "iridium", "id": "iridium",
"version": "26.9.14", "version": "26.9.15",
"name": "Iridium", "name": "Iridium",
"description": { "description": {
"zh_cn": "物品展示 / 戴头 / 获取头颅 / 游戏内计算器 / 进服 MOTD", "zh_cn": "物品展示 / 戴头 / 获取头颅 / 游戏内计算器 / 进服 MOTD",