Skip to content

公开 API ​

编译依赖 ​

xml
<repositories>
  <repository><id>jiuwu-releases</id><url>https://repo.crypticlib.com/repository/maven-public/</url></repository>
</repositories>
<dependency>
  <groupId>emaki.jiuwu.craft</groupId><artifactId>emaki-forge-api</artifactId>
  <version>4.8.6</version><scope>provided</scope>
</dependency>
kotlin
repositories { maven("https://repo.crypticlib.com/repository/maven-public/") }
dependencies { compileOnly("emaki.jiuwu.craft:emaki-forge-api:4.8.6") }

仅编译依赖

不要把 API Jar 放入 plugins/, 也不要 bundle, shade 或 relocate. EmakiForge-4.8.8.jar 已内嵌未 relocate 的 API 类; 重复 ClassLoader 类型会破坏 Bukkit 事件与静态 bridge

门面与真实分层 ​

先检查 EmakiForgeApi.status().usable(). catalog(), operations(), extensions() 永不返回 null; 不可用时返回空查询, unavailable 结果或空扩展层

  • catalog(): 配方, 材料, 匹配, 校验, 接受状态
  • operations(): 程序化锻造, GUI, 配方书和物品刷新
  • extensions(): 当前为空的保留实验层, 不存在可注册扩展点

install, uninstall 和 Bridge 只属于 runtime 生命周期; 第三方不得调用, 实现或代理

Catalog ​

recipes() 按配方书顺序返回已加载配方 (不可用时为空列表); recipe(String) 用 Locale.ROOT 归一化后查表. recipes(), recipe(String), materialById(String), materialByItem(ItemStack) 与 accepting() 可读加载后的不可变定义, 任意线程可调用; 实时物品须遵守其 holder owner thread. matchRecipe(Player, ForgeInputs) 与 validate(Player, String, ForgeInputs) 需要玩家 owner thread. validate 的业务不通过仍是 Success(ForgeValidation), 应检查 allowed(); ForgeValidation 另带 reasonKey() 与 placeholders() 供渲染拒绝原因

实验性 previewResult(Player, String, ForgeInputs) 也要求玩家 owner thread; 它只构建当前预览, 不执行配置动作, 不消耗输入, 不写入历史且不交付物品. 实验性 mastery(Player, String) 读取玩家该配方已持久化的成功锻造次数; 当前会话数据尚未加载时返回 UNAVAILABLE, 不会伪造为 0

程序化锻造 ​

java
CompletableFuture<EmakiResult<ForgeOutcome>> future =
        EmakiForgeApi.operations().forgeAsync(player, recipeId, inputs);

forgeAsync 可从任意线程提交, runtime 会把所有玩家/Bukkit 阶段调度到玩家 owner thread. ForgeInputs 是调用方预先保留的分离 escrow 快照, 字段为 targetItem, blueprints, requiredMaterials, optionalMaterials, 构造与读取时都会复制; 另有 ForgeInputs.empty() 与 ForgeInputs.ofRequired(map) 两个便捷构造. API 不会扫描或扣除玩家任意库存槽; 调用方必须在 future 期间锁住实物, 并在成功时提交 escrow, 失败时释放

ForgeOutcome 只在结果物品已交付且 commit boundary 已跨越后产生, 包含 recipeId, 克隆的 resultItem, quality 与 multiplier. 普通摇点失败, 验证拒绝, 事件取消, 不可用和执行错误由外层 EmakiResult 表示. 取消 future 不能回滚已经越过交付提交点的尝试

其他 Operations ​

  • openForgeGui(Player[, recipeId]), openRecipeBook(Player, page), viewingRecipeBook(Player): 玩家 owner thread. page 从 0 开始计页, 负数按 0 处理; viewingRecipeBook 用 EmakiResult<Boolean> 区分"未打开"与"不可用"
  • refreshItem(ItemStack): holder owner thread; 非锻造物品返回 Partial
  • refreshPlayer(Player): 刷新库存, 护甲, 副手与光标, 玩家 owner thread

结果说明 ​

无负载成功使用 EmakiResult<Unit>, 不是 Void. 读取可选负载使用 optionalValue(); Success/Partial 记录本身的直接访问器仍是 value(). FailureKind 精确为: UNAVAILABLE, NOT_FOUND, INVALID_INPUT, REJECTED, CANCELLED, TARGET_OFFLINE, WRONG_THREAD, INTERNAL_ERROR