简体中文
事件 API
EmakiStation 在 emaki.jiuwu.craft.station.api.event 包发布三个 Bukkit 事件
| 事件 | 可取消 | 触发时机 | 触发线程 |
|---|---|---|---|
StationCraftSubmitEvent | 是 | 扣款与扣材料之前 | 见下方说明 (API 路径不保证 owner 线程) |
StationCraftCancelEvent | 是 | 移除队列条目与退还之前 | 队列所有者的 owner 线程 |
StationCraftCompletedEvent | 否 | 结算完成, 产物路由之后 | 合成玩家的 owner 线程 |
后两个事件总是通过实体的 owner 调度触发: Folia 上是实体调度器 owner, Paper 上是主服务器线程
StationCraftSubmitEvent 在 GUI 与命令路径上也在 owner 线程触发, 但API 的 submitAsync 允许任意线程调用且直接在该调用线程上派发事件. 因此监听器不得假定该事件总在 owner 线程触发; 需要修改玩家状态时必须自行切回 owner 线程
StationCraftSubmitEvent
java
public class StationCraftSubmitEvent extends Event implements Cancellable| 成员 | 类型 | 说明 |
|---|---|---|
getPlayer() | Player | 提交的玩家 |
getStationId() | String | 工作站 id |
getRecipeId() | String | 配方 id |
getBatch() | long | 本次提交的倍率 |
getChannel() | MaterialChannel | 事件携带的材料通道. 它是 bridge 按工作站配置推定的取值: 工作站启用了 channels.storage 且仓库通道可用时为 STORAGE, 否则为 BACKPACK; 不代表本次提交实际从哪个通道扣料 |
isCancelled() / setCancelled(boolean) | boolean | 取消控制 |
取消意味着整笔提交停止: 不扣款, 不扣材料, 不建立队列条目. 这是唯一可以零补偿否决一次合成的时点
覆盖范围: 任何通过前置校验 (工作站/配方存在, 倍率合法, 配方可用, 权限, 条件门, 队列容量, 待领取上限) 并到达扣款阶段的提交, 无论来自 GUI, 命令还是 StationOperations#submitAsync. 事件在材料与余额校验之前触发, 因此之后因材料或余额不足而失败的提交也已收到本事件
被权限, 条件, 队列容量或待领取上限提前拒绝的提交不会触发本事件; 队列条目的后续推进或结算也不会触发本事件
StationCraftCancelEvent
java
public class StationCraftCancelEvent extends Event implements Cancellable| 成员 | 类型 | 说明 |
|---|---|---|
getPlayer() | Player | 队列所有者 |
getStationId() | String | 工作站 id |
getRecipeId() | String | 配方 id |
getIndex() | int | 队列位置, 从 0 开始 |
getConsumedMaterials() | List<ConsumedMaterial> | 该条目已消耗的材料清单 |
getRefundRate() | double | 即将应用的退还比例 |
isCancelled() / setCancelled(boolean) | boolean | 取消控制 |
取消意味着该条目留在队列, 什么都不退, 材料继续投在这次合成上. 被否决时调用方收到 FailureKind.CANCELLED 与原因键 station.cancel_vetoed
getRefundRate() 的取值来自工作站的 queue.cancel_refund_rate
覆盖范围: 玩家从 GUI 或命令发起的取消, 以及 StationOperations#cancelAsync. 条目正常完成时不会触发本事件, 队列数据被管理性丢弃时也不会触发本事件
PENDING_CLAIM 状态的条目在触发本事件之前就被拒绝, 返回 station.cancel_pending_claim, 因此监听器不会看到这类取消
StationCraftCompletedEvent
java
public class StationCraftCompletedEvent extends Event不可取消: 触发时材料早已消耗, 产物已发放或已转入待领取, 没有可否决的内容
| 成员 | 类型 | 说明 |
|---|---|---|
getPlayer() | Player | 合成玩家 |
getStationId() | String | 工作站 id |
getRecipeId() | String | 配方 id |
getBatch() | long | 本次结算的倍率 |
getDeliveredOutputs() | List<PendingOutput> | 已成功投递的产物 |
getPendingOutputs() | List<PendingOutput> | 未能投递, 转入待领取的产物 |
覆盖范围: 队列条目的结算, 以及零耗时配方的立即结算
getPendingOutputs() 非空表示没有任何已配置目标能接收产物, 这些产物当前等待手动领取. 因此"completed"描述的是合成本身完成, 而不是投递成功
本事件不会在玩家后来领取停放产物时触发, 也不是审计日志: 被取消的条目永远到不了这里
示例
java
@EventHandler(ignoreCancelled = true)
public void onSubmit(StationCraftSubmitEvent event) {
if (isBlacklisted(event.getRecipeId())) {
event.setCancelled(true);
}
}
@EventHandler
public void onCompleted(StationCraftCompletedEvent event) {
if (!event.getPendingOutputs().isEmpty()) {
event.getPlayer().sendMessage("有产物未能投递,请清理仓库或背包后领取。");
}
}两个事件类的构造器都对传入的列表做防御性复制, 传入 null 时得到空列表