API 与集成
EmakiCodexApi 是 EmakiCodex 对第三方插件开放的静态 API 门面。第三方插件只需要把 emaki-codex-api 作为编译依赖;运行时由服务器中安装的 EmakiCodex 插件本体提供实现。
服务器服主只安装 EmakiCodex-*.jar,不要把 emaki-codex-api-*.jar 放进 plugins/。
Maven 依赖
<dependency>
<groupId>emaki.jiuwu.craft</groupId>
<artifactId>emaki-codex-api</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
</dependency>如果你的插件通过 Maven 构建,请确保运行服务器时已安装同版本或更高版本的 EmakiCodex 插件本体。
Gradle 依赖
dependencies {
compileOnly("emaki.jiuwu.craft:emaki-codex-api:1.0.0")
}可用性检查
import emaki.jiuwu.craft.codex.api.EmakiCodexApi;
if (!EmakiCodexApi.available() || !EmakiCodexApi.isReady()) {
return;
}available() 表示 Codex API bridge 已安装;isReady() 表示插件已启用并完成初始化。
也可以使用迁移辅助类:
import emaki.jiuwu.craft.codex.api.EmakiCodexApiProvider;
if (EmakiCodexApiProvider.available()) {
EmakiCodexApiProvider.requireAvailable();
}EmakiCodexApiProvider 只用于可用性检查;不要把它当成实例服务入口。
授予节点
import java.util.UUID;
import emaki.jiuwu.craft.codex.api.EmakiCodexApi;
UUID playerId = player.getUniqueId();
boolean changed = EmakiCodexApi.grantAdvancement(playerId, "example/first_step");
if (!changed) {
// 玩家不在线、调用线程不持有该玩家归属、节点未注册,或玩家已经完成该节点。
}同步方法要求调用线程已经持有目标玩家的线程归属;不满足时直接返回 false。不确定归属时请使用下方的异步重载。
advancementId 支持两种写法:
| 写法 | 示例 |
|---|---|
| 短写 | example/first_step |
| 完整 key | emakicodex:example/first_step |
授予节点会奖励内部 codex criterion。节点首次完成时,会触发原版完成链路,并执行该节点配置的 actions.complete。
撤销节点
import java.util.UUID;
import emaki.jiuwu.craft.codex.api.EmakiCodexApi;
UUID playerId = player.getUniqueId();
boolean changed = EmakiCodexApi.revokeAdvancement(playerId, "example/first_step");
if (!changed) {
// 玩家不在线、调用线程不持有该玩家归属、节点未注册,或玩家尚未完成该节点。
}撤销只处理已注册的 Codex 节点;不会删除配置文件,也不会移除服务器注册表中的 Advancement 定义。
异步写入
grantAdvancement / revokeAdvancement 要求调用方已经持有目标玩家的线程归属。如果你不确定当前线程是否拥有该玩家,改用异步重载,由 EmakiCodex 负责调度到正确的 owner 线程:
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import emaki.jiuwu.craft.codex.api.EmakiCodexApi;
CompletableFuture<Boolean> future =
EmakiCodexApi.grantAdvancementAsync(playerId, "example/first_step");
future.thenAccept(changed -> {
// 回调线程不保证是主线程;接触 Bukkit 状态前请自行调度。
});| 方法 | 返回值 | 说明 |
|---|---|---|
grantAdvancementAsync(UUID, String) | CompletableFuture<Boolean> | 异步授予节点。API 不可用时返回已完成的 false。 |
revokeAdvancementAsync(UUID, String) | CompletableFuture<Boolean> | 异步撤销节点。API 不可用时返回已完成的 false。 |
这两个方法不承诺切换线程:目标玩家离线、API 不可用或调度失败时,返回的 future 可能已经完成。回调中若需要操作 Bukkit / Paper / Folia 状态,必须自行调度到对应 owner 线程。
版本与插件名
String version = EmakiCodexApi.apiVersion();
String pluginName = EmakiCodexApi.pluginName();当 API 不可用时,这两个方法返回空字符串。
集成边界
- API 只暴露静态门面,不暴露
AdvancementService、loader、listener 或配置 parser。 - API 方法面向在线玩家 UUID;离线玩家不会被加载或改写。
- 如果要在配置动作链中授予节点,优先使用 CoreLib 动作;如果是第三方插件代码集成,再使用
EmakiCodexApi。 - 如果需要在玩家客户端刷新坐标化成就树,当前公开 API 不提供 resync 方法;可在 CoreLib Action 中调用
codex_resync_advancement。