Skip to content

事件 API

EmakiStation 在 emaki.jiuwu.craft.station.api.event 包发布三个 Bukkit 事件。

三个事件全部在合成玩家的 owner 线程触发:Folia 上是实体调度器 owner,Paper 上是主服务器线程。

事件可取消触发时机
StationCraftSubmitEvent扣款与扣材料之前。
StationCraftCancelEvent移除队列条目与退还之前。
StationCraftCompletedEvent结算完成、产物路由之后。

StationCraftSubmitEvent

java
public class StationCraftSubmitEvent extends Event implements Cancellable
成员类型说明
getPlayer()Player提交的玩家。
getStationId()String工作站 id。
getRecipeId()String配方 id。
getBatch()long本次提交的倍率。
getChannel()MaterialChannel材料通道,已不再决定取材来源。
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 变为空列表。