Flag

Flag

使用内置 flag、查询 flag 元数据、注册自定义 flag 和配置 UI 分组。

两类 Flag

类型Java 类型典型用途示例
环境 flagEnvFlag与玩家身份无关的领地环境规则Flags.FIRE_SPREADFlags.CREEPER_EXPLODE
权限 flagPriFlag玩家、成员、组和访客可以执行的动作Flags.PLACEFlags.CONTAINERFlags.TELEPORT

EnvFlag 主要由 Dominion 的环境事件使用;PriFlag 需要结合玩家和位置执行权限检查。不要把两者混用在 checkPrivilegeFlagcheckEnvironmentFlag 中。

使用内置 Flag

boolean canBuild = DominionAPI.getInstance().checkPrivilegeFlagSilence(
        location,
        Flags.PLACE,
        player
);

EnvFlag flag = Flags.getEnvFlag("creeper_explode");
PriFlag privilege = Flags.getPreFlag("container");

当前源码中的查找方法名确实是 getPreFlag(String),这是 API 已发布的拼写,不能写成不存在的 getPriFlag

Flags 提供以下枚举和查找方法:

方法说明
getAllFlags()所有已注册 flag
getAllEnvFlags() / getAllPriFlags()分类型获取所有 flag
getAllFlagsEnable()获取 getEnable()true 的 flag
getAllEnvFlagsEnable() / getAllPriFlagsEnable()分类型获取已启用 flag
getFlag(String) / getEnvFlag(String) / getPreFlag(String)getFlagName() 查找

这些列表应当视为只读快照/查询结果使用,不要在附属中直接向列表添加对象;注册请使用 registerEnvFlagregisterPriFlag

Flag 元数据

每个 Flag 都包含:

  • getFlagName():程序使用的唯一名称;
  • getDisplayName()getDescription():默认展示文本;
  • getDefaultValue():没有单独配置时的默认值;
  • getEnable():该 flag 是否启用;
  • getMaterial():Chest UI 中使用的图标材质;
  • getDisplayNameKey()getDescriptionKey():语言文件键;
  • getConfiguration...Key():配置字段键。

flag 元数据可以被修改,例如 setDisplayNamesetDescriptionsetDefaultValuesetEnablesetMaterial。修改默认配置或展示信息后,应调用 Flags.applyChanges() 等待应用完成。

注册自定义 Flag

public static final EnvFlag NO_RAIN = new EnvFlag(
        "no_rain",
        "No Rain",
        "Whether rain is blocked in this dominion.",
        false,
        true,
        Material.SUNFLOWER
);

public static final PriFlag USE_SPECIAL_TOOL = new PriFlag(
        "use_special_tool",
        "Use Special Tool",
        "Whether players may use the special tool.",
        false,
        true,
        Material.BLAZE_ROD
);

boolean envRegistered = Flags.registerEnvFlag(this, NO_RAIN);
boolean priRegistered = Flags.registerPriFlag(this, USE_SPECIAL_TOOL);

if (envRegistered || priRegistered) {
    Flags.applyChanges().thenRun(() ->
            getLogger().info("Dominion custom flags are ready."));
}

注册过程会触发 FlagRegisterEvent。其他插件可以取消该事件,因此注册方法返回值必须检查。flag 名称需要在所有已注册 flag 中保持唯一;建议使用小写、下划线或连字符,并带有自己的插件前缀。

自定义 Flag 不会自动实现游戏行为

注册 NO_RAIN 不会自动阻止降雨,注册 USE_SPECIAL_TOOL 也不会自动改变交互权限。附属需要自己监听对应的 Bukkit/Paper 事件,并调用:

if (!DominionAPI.getInstance().checkEnvironmentFlag(location, NO_RAIN)) {
    // 在你的附属逻辑中决定如何处理 NO_RAIN
}

具体事件、取消时机和线程处理由附属负责。Flag 只提供 Dominion 的存储、查询、UI 展示和权限数据入口。

FlagGroup

FlagGroup 只用于逻辑分组、展示和批量编辑,不参与权限计算。环境组使用 EnvFlagGroup,权限组使用 PriFlagGroup

EnvFlagGroup weather = new EnvFlagGroup(
        "weather",
        "Weather",
        "Environment rules related to weather.",
        Material.SUNFLOWER
);
weather.addFlag(NO_RAIN);
FlagGroups.registerEnvFlagGroup(this, weather);

组 ID 必须符合 [a-z0-9_-]+,并且不能使用保留的 ungrouped。组可以通过 setDisplayNamesetDescriptionsetMaterialaddFlagremoveFlagcontainsFlag 管理成员。

FlagGroups 的主要方法:

方法说明
registerEnvFlagGroup / registerPriFlagGroup注册环境/权限组
unregisterEnvFlagGroup / unregisterPriFlagGroup按 ID 注销组
getEnvFlagGroup / getPriFlagGroup按 ID 查询组
getEnvFlagGroups / getPriFlagGroups获取已注册组
getUngroupedEnvFlags / getUngroupedPriFlags获取未加入任何组的动态分组
getRevision()获取分组注册表修订号

应用变更

Flags.applyChanges() 返回一个 CompletableFuture<Void>,用于等待自定义 flag 和分组变更完成:

Flags.applyChanges().thenRun(() -> {
    // 这里表示本次 flag 应用流程已完成
});

旧的 Flags.applyNewCustomFlags() 已弃用,而且不会为调用方提供可观察的完成 Future。新代码应使用 applyChanges()