正在载入

等待时间过长时请刷新页面

编写于

最近更新

配置文件

ConfigService 将 Java 配置对象映射为插件数据目录中的 YAML 或 JSON 文件。Java 类声明结构与默认值,磁盘文件保存管理员可以修改的实际配置。

定义配置对象

配置类使用 @ConfigFile,并遵循文件服务概览 ⇱中的对象约束:

@ConfigFile(name = "config", format = FileType.YAML)
@NamingStyle(NamingStyle.Style.KEBAB)
@Comment("插件主配置文件")
public class MainConfig {

    @Comment("当前全局语言")
    public String language = "zh_CN";

    @Key("debug")
    public boolean debugMode = false;

    public Database database = new Database();

    public static class Database {
        public String host = "127.0.0.1";
        public int port = 3306;
    }
}

默认 KEBAB 命名会把 debugMode 转换为 debug-mode;@Key("debug") 会覆盖自动命名。@Comment 只写入 YAML,JSON 不保存注释。

文件位置

@ConfigFile 的主要参数为:

参数作用
name不含扩展名的文件名,默认为 config
path相对于插件数据目录的子目录
formatFileType.YAML 或 FileType.JSON
emit是否允许创建、修复和写回文件,默认为 true

例如:

@ConfigFile(name = "database", path = "settings", format = FileType.JSON)
public class DatabaseConfig {
}

对应文件为 plugins/<YourPlugin>/settings/database.json。

绑定配置

ConfigService configs = lin.linFile().config();
MainConfig config = configs.bind(MainConfig.class);

绑定会读取或创建文件、执行适用的版本迁移、合并缺失默认值并校验字段。全部检查通过后,服务才更新活动对象。错误定位和失败保护见配置校验 ⇱。

已有文件缺少代码声明的键时,活动对象会先使用代码默认值,插件可以继续读取配置;原文件不会因此自动改变。允许输出时,服务会生成 config-diff.yml 之类的差异文件,列出缺失路径和待写入的默认值。差异文件仅供管理员查看,不参与配置读取。

修复缺失键

管理员确认差异内容后,可以执行:

/linlang files repair <插件名称>

这条命令会重新读取目标插件已经绑定的配置和语言文件,再把当时仍然缺失的键写入原文件。插件名称支持 Tab 补全,但不能指定 Linlang 运行时插件本身。它不会直接套用先前缓存的差异,因此管理员在检测后所做的修改不会被旧快照覆盖。修复期间不会再次生成或更新差异文件,也不会重复输出缺失键告警;已有差异文件保留为本次修复前的记录。

需要一次修复全部已注册插件时,可以执行:

/linlang files repair-all

批量修复会隔离每个目标的失败;某个插件修复失败时,其余插件仍会继续处理。命令先输出检查、修复和失败总数,再逐项列出实际发生修复的插件及其配置键、语言键数量;没有变化的插件不会重复列出。

开发者也可以在明确的管理操作中调用:

int repaired = configs.repairMissingKeys();

返回值是本次实际补入的键数。普通 bind(...) 和 reload() 不代表修复授权。

需要让服务器持续自动修复时,可以在 plugins/LinlangRuntimeBukkit/config.yml 中明确开启:

file-service:
  auto-repair-missing-keys: true

该策略在运行时启动时读取并应用。修改后执行 /linlang reload-all,运行时会在重载各插件前重新应用策略,因此本次重载发现的缺失键即可按新设置处理。该设置作用于运行时自身的文件服务以及随后创建的插件 Facade,默认值为 false。

YAML 中每个补入的键前都会写入 # [Linlang] 缺失键修复自动补入。JSON 语法不允许注释,Linlang 不会插入额外元数据破坏配置结构,而是保留对应的 -diff.json 作为修复记录。

保存与重载

业务代码修改活动对象后,可以保存所有已绑定配置:

config.debugMode = true;
configs.saveAll();

saveAll() 会用内存状态覆盖磁盘内容。管理员可能已经编辑文件时,应先决定是保存内存修改还是执行重载,不要无条件保存。

configs.reload();

重载会尽量原地更新根对象,但未保存的内存修改不会与磁盘内容合并。失败文件保留旧活动值,其他文件仍继续重载;调用方应检查汇总异常,不能在部分失败后发送“全部成功”。

Map、List、数组和 ConfigText 字段可能在重载中被替换,应从根配置对象重新取得。Facade 的参数应用不会读取配置文件;完整的 Facade 重建则需要重新取得服务并绑定。

只读配置可以使用 @ConfigFile(emit = false)、@NoEmit 或 bind(..., false)。三者都会禁止创建文件、生成差异、修复缺失键和显式保存,详细规则见文件服务概览 ⇱。

字段注解

注解作用
@ConfigFile声明文件名、子目录、格式和写回策略
@NamingStyle设置字段的自动命名方式
@Key覆盖单个字段的文件键名
@Comment为 YAML 类或字段写入注释
@NoEmit禁止生成和写回文件
@ConfigVersion声明结构版本和版本键

配置迁移

@ConfigVersion 在文件中记录结构版本,默认版本键为 _linlang-version:

@ConfigFile(name = "config")
@ConfigVersion(2)
public class MainConfig {
    public String newName = "default";
}

迁移器必须在绑定配置类之前注册:

configs.registerMigrator(new Migrator() {
    public int from() {
        return 1;
    }

    public int to() {
        return 2;
    }

    public boolean supports(Class<?> type) {
        return type == MainConfig.class;
    }

    public void migrate(MutableDocument doc) {
        doc.set("new-name", doc.get("old-name"));
        doc.remove("old-name");
    }
});

MainConfig config = configs.bind(MainConfig.class);

服务从文件版本开始连续执行迁移,再按新结构填充对象。迁移链缺失、同一起始版本存在多个适用迁移器,或文件版本高于代码支持版本时,绑定会失败。

每一步的 to() 必须向目标版本推进。可以注册 1 -> 2、2 -> 3,也可以由一个迁移器完成 1 -> 3;批量注册使用 registerMigrators(...)。

讨论

请登录账号