English
Events
Storage events live in emaki.jiuwu.craft.storage.api.event. All four are synchronous cancellable Bukkit events published on the storage owner's owner thread. Their fields are immutable transaction snapshots and no mutable business field is exposed
| Event | Timing | Cancellation effect | Runtime path |
|---|---|---|---|
StorageDepositEvent | After the capacity pre-check, before inventory removal (when there is one) and the entry credit | Blocks the removal and the storage increase | The transaction deposit and depositDirect, including depositAsync(..., source=api), the GUI, commands and actions |
StorageWithdrawEvent | After the withdrawable amount is computed, before the entry debit and the item delivery | Blocks the debit and the delivery | StorageTransactionService.withdraw, including withdrawAsync(..., source=api), the GUI, commands and actions |
StorageUnlockEvent | After the total price is computed, before any currency or item charge and the purchased-slot increase | Blocks every charge and the unlock | The paid unlock service; the admin grantSlotsAsync does not fire it |
StorageBatchEvent | Before a batch operation commits, ahead of any escrow debit or write | Aborts the whole batch; no per-op Deposit/Withdraw event is fired inside a batch | applyBatchAsync |
The payload is fixed per event: deposit, withdraw and unlock carry playerId(), a cloned and normalised template(), requestedAmount() and source(); withdraw adds storedAmount(); unlock carries slotAmount(), purchasedSlotsBefore() and currencyCost() (currency only — an item price is not reflected in this event). StorageBatchEvent carries playerId(), the op list (ops() returns an immutable List<StorageBatchOp> whose templates are copies with amount == 1), the allOrNothing() flag and source(). Accessors are record-style without a get prefix. Threading contract: the asynchronous facade only submits and dispatches; the event still fires synchronously inside the real owner-thread transaction, and a future callback does not inherit that thread guarantee
source is a runtime surface id with exactly 5 possible values: gui / command / api / action / auto_pickup. Of these, auto_pickup only ever appears on deposit events (auto-pickup goes through the direct deposit path); StorageUnlockEvent currently only ever carries gui, because paid expansion has no entry point in this plugin other than the GUI
Emission rule: these events are emitted by the runtime transaction paths. No synthetic event is published when the bridge is unavailable; the future-returning facade operations report explicit result failures instead