Skip to content
On this page

为第三方插件注册页面

第三方 Bukkit 插件可以把自己的页面交给 ChaUI 统一管理。注册成功后,页面会立即进入 ChaUI 的已加载页面,可以直接打开,不需要 reload,也不需要再执行 /chaui reload

这个入口的重点是“不覆盖”:ChaUI 不会覆盖服务器管理员已经修改过的同 ID 页面,第三方插件升级时也不会用 Jar 内的默认页面替换它。

使用前准备

第三方插件应对 ChaUI 添加编译依赖,并在 plugin.yml 中声明依赖关系。如果你的插件没有 ChaUI 就无法工作,使用 depend;如果只是可选增强,使用 softdepend 并在调用前检查 ChaUI 是否已启用。

yaml
name: ExamplePlugin
main: example.plugin.ExamplePlugin
version: 1.0.0
api-version: "1.20"
depend:
  - ChaUI

不要直接写 ChaUI 目录

请不要自己查找 plugins/ChaUI/pages/、复制文件或覆盖旧文件。只调用公开注册 API,由 ChaUI 负责查重、验证、保存和立即加载。

方式一:注册 Jar 内的 yml

先在你的插件工程中放入完整页面,例如 src/main/resources/chaui/shop_help.yml

yaml
# 页面 ID 是全服唯一身份,与资源文件名无关
id: example_shop_help
version: 1
title: 商店帮助
size:
  width: 240
  height: 140
coordinateMode: absolute
display:
  mode: screen
  screen:
    dimBackground: false
vars:
  openedFromShop: true
events:
  open: |-
    log("商店帮助页已打开")
methods:
  关闭帮助: |-
    close()
elements:
  - id: panel
    type: rect
    layout:
      x: 20
      y: 20
      width: 200
      height: 100
    pointerEvents: block
    rect:
      color: "#20252D"
  - id: title
    type: text
    layout:
      x: 36
      y: 34
      width: 168
      height: 18
    text:
      value: 商店帮助
      textSize: 1.2
      color: "#FFFFFF"
  - id: close_button
    type: button
    layout:
      x: 78
      y: 82
      width: 84
      height: 22
    button:
      label: 关闭
      textSize: 1.0
    events:
      leftClick: |-
        methods.关闭帮助()

在插件启用阶段的 Bukkit 主线程中注册:

java
import com.github.ginirohikocha.chaui.api.ChaUIAPI;
import com.github.ginirohikocha.chaui.api.PageRegistrationException;
import com.github.ginirohikocha.chaui.api.PageRegistrationResult;
import org.bukkit.plugin.java.JavaPlugin;

public final class ExamplePlugin extends JavaPlugin {
    @Override
    public void onEnable() {
        // 成功返回时,页面已可以立即打开。
        PageRegistrationResult result = ChaUIAPI.registerPage(
                this,
                "chaui/shop_help.yml"
        );
        getLogger().info("页面注册结果:" + result);
    }
}

resourcePath 是你自己 Jar 内的相对路径。yml 根级 id 才是页面身份;上例最终创建的是 pages/example_shop_help.yml,不是 shop_help.ymlchaui/shop_help

方式二:注册 YamlConfiguration

页面由代码或你自己的配置组装时,可以直接传入 Bukkit YamlConfiguration。下面示例创建了一个可直接打开的完整页面:

java
import com.github.ginirohikocha.chaui.api.ChaUIAPI;
import com.github.ginirohikocha.chaui.api.PageRegistrationException;
import com.github.ginirohikocha.chaui.api.PageRegistrationResult;
import org.bukkit.configuration.file.YamlConfiguration;

YamlConfiguration page = new YamlConfiguration();
page.set("id", "example_runtime_help");
page.set("version", 1);
page.set("title", "运行时帮助");
page.set("size.width", 220);
page.set("size.height", 120);
page.set("coordinateMode", "absolute");
page.set("display.mode", "screen");
page.set("display.screen.dimBackground", false);
page.set("vars.source", "example_plugin");
page.set("events.open", "log(\"帮助页已打开\")");
page.set("methods.关闭", "close()");

// elements 仍然是页面使用的完整组件列表。
page.set("elements", java.util.List.of(
        java.util.Map.of(
                "id", "message",
                "type", "text",
                "layout", java.util.Map.of(
                        "x", 30, "y", 32, "width", 160, "height", 20
                ),
                "text", java.util.Map.of(
                        "value", "这是第三方插件注册的页面",
                        "textSize", 1.0,
                        "color", "#FFFFFF"
                )
        ),
        java.util.Map.of(
                "id", "close_button",
                "type", "button",
                "layout", java.util.Map.of(
                        "x", 70, "y", 72, "width", 80, "height", 22
                ),
                "button", java.util.Map.of(
                        "label", "关闭",
                        "textSize", 1.0
                ),
                "events", java.util.Map.of(
                        "leftClick", "methods.关闭()"
                )
        )
));

PageRegistrationResult result = ChaUIAPI.registerPage(this, page);
getLogger().info("页面注册结果:" + result);

三种返回结果

结果发生了什么你通常需要做什么
COPIED_AND_LOADEDChaUI 中原本没有这个 ID,已创建文件并立即加载可直接使用
EXISTING_FILE_LOADED磁盘上已有同 ID 文件,ChaUI 没有覆盖它,而是加载了现有文件保留管理员的配置,可直接使用
ALREADY_LOADED该 ID 已在 ChaUI 缓存中不会重复加载,可直接使用

无论返回哪个成功结果,都不需要追加 reload。已有文件可以位于 pages/ 任意子目录,ChaUI 会在整棵目录中按根级 id 查找。

异常处理

建议在启用阶段记录异常,不要忽略失败原因:

java
try {
    PageRegistrationResult result = ChaUIAPI.registerPage(
            this,
            "chaui/shop_help.yml"
    );
    getLogger().info("页面注册结果:" + result);
} catch (PageRegistrationException exception) {
    // 资源读取、目录冲突、落盘或页面加载失败。
    getLogger().severe("页面注册失败:" + exception.getMessage());
} catch (IllegalStateException exception) {
    // 调用发生在异步线程。请切回 Bukkit 主线程后再注册。
    getLogger().severe("页面注册线程错误:" + exception.getMessage());
} catch (IllegalArgumentException exception) {
    // 参数、页面 ID 或页面配置不合法。
    getLogger().severe("页面配置错误:" + exception.getMessage());
}

资源不存在、非 UTF-8 无 BOM、页面 ID 不合法、Schema 校验失败,或整棵 pages/ 中出现重复 ID 时,会抛出 PageRegistrationException 或对应的参数异常。失败不会在页面缓存或目录中留下半成品。

常见错误

在异步任务中直接注册

注册是同步主线程 API。异步调用会立即抛出 IllegalStateException,ChaUI 不会在内部暗中调度。

把资源文件名当成页面 ID

页面 ID 只看 yml 根级 id。资源路径和文件名只用于找到资源。

期望插件升级覆盖管理员页面

注册 API 刻意不覆盖。如果你需要迁移页面结构,应将它设计为明确的迁移流程,而不是在插件启用时静默覆盖服务器配置。

下一步

页面注册成功后,可以使用 ChaUIAPI.open(...) 打开普通页面,或使用 ChaUIAPI.openSubPage(...)screen 页面叠加在玩家当前 GUI 上。完整子页面交互见在 GUI 上打开子页面