简体中文
公开 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-storage-api</artifactId><version>1.1.3</version><scope>provided</scope></dependency>kotlin
repositories { maven("https://repo.crypticlib.com/repository/maven-public/") }
dependencies { compileOnly("emaki.jiuwu.craft:emaki-storage-api:1.1.3") }仅编译依赖
runtime 已内嵌未 relocate 的 API 类. 不要安装, bundle, shade 或 relocate API Jar; 重复 ClassLoader 类型会破坏事件与 bridge
门面
可用性以 EmakiStorageApi.status().usable() 为准. 业务层只有 operations() 恒为非 null; install, uninstall 与 Bridge 只属于 runtime, 调用方不得依赖
全部异步方法
方法约定: 除 openGui 外, 当前公开读写方法均带 Async 并返回 CompletableFuture<EmakiResult<...>>:
| 方法 | 含义 |
|---|---|
readSnapshotAsync(UUID) | 读取分离的 StorageSnapshot, 未缓存时从文件 lane 加载 |
depositAsync(UUID,ItemStack,long) | 向仓库增加, 不从调用方库存扣物 |
withdrawAsync(UUID,ItemStack,long) | 从仓库扣减并交付给在线 owner |
countOfAsync(UUID,ItemStack) | 返回真实数量, 包括合法的 0 |
countAllAsync(UUID,Collection<ItemStack>) | 一次统计多个模板, 返回 Map<ItemStack,Long>. 仓库里没有的模板映射为 0L 而不是缺键. 对离线玩家可用 |
applyBatchAsync(UUID,StorageBatchRequest) | 原子批量增减. allOrNothing 在 StorageBatchRequest 内声明, 不是独立参数. 载荷为 StorageBatchResult. 操作数超出 behavior.batch_max_ops 时返回 INVALID_INPUT 与 batch_too_large, 不执行任何操作 |
reserveAsync(UUID,StorageBatchRequest,Duration) | 只挂住请求中的扣减侧, 载荷是 ReservationHandle. 请求里的存入操作被忽略: 预留只锁库存, 不预订容量. ttl 非正数被拒绝; 预留跨重启存活, 载入时超过 ttl 即释放 |
commitAsync(ReservationHandle) | 提交预留, 载荷为 StorageBatchResult. 只有 handle 一个参数, 没有 UUID. 提交会重跑存入侧预检 |
releaseAsync(ReservationHandle) | 释放预留, 载荷为 Unit. 只有 handle 一个参数. 可重复调用且结果不变: 未知或已释放的 handle 返回 NOT_FOUND 而不是报错 |
grantSlotsAsync(UUID,int) | 调整管理型 granted-slot 池 |
setStackLimitAsync(UUID,long) | 设置玩家默认单槽上限; 0 恢复配置继承 |
setSlotStackLimitAsync(UUID,int,long) | 设置逻辑 entry 上限; 0 恢复玩家默认继承 |
线程契约: 这些 future 可从任意线程提交, runtime 会在文件 lane 或玩家 owner thread 完成实际工作, 但 future callback 不保证位于 Bukkit owner thread. 触碰玩家, 库存或世界前必须重新调度
同步方法的线程要求: openGui(Player) 是唯一同步操作, 必须在 viewer/owner 的 entity-owner thread; 错误线程返回 WRONG_THREAD, 不会替调用方延迟打开
返回模型: StorageSnapshot 是不可变分离快照. StorageAmount 含 requested, applied, remaining() 与 complete(); 容量不足可返回携带实际 applied 的 Partial
事件边界
触发规则: 异步 API 在其实际 transaction path 中触发对应同步事件, 不得因方法名相似就假定所有底层编辑都有事件. 特别是 direct async withdraw 的当前实现路径应以 runtime transaction service 为准, 事件页列出确切覆盖
批量与预留的边界: 整个批量操作只触发一次 StorageBatchEvent, 批内不再逐条触发 Deposit/Withdraw 事件. 预留中的存量仍可通过 StorageEntrySnapshot#reservedAmount() 看到, 但不会被 applyBatchAsync 取走, 同一份存量不会同时被承诺给两处
来源固定: 公开 API 的每个方法都会把来源记为 api, 调用方无法指定来源; gui, command, action, auto_pickup 这几种来源只由插件自身的对应入口产生
结果说明
结果契约: 无负载成功使用 EmakiResult<Unit>; 可选负载通过 optionalValue() 读取. FailureKind 取值精确为 UNAVAILABLE, NOT_FOUND, INVALID_INPUT, REJECTED, CANCELLED, TARGET_OFFLINE, WRONG_THREAD, INTERNAL_ERROR. 普通业务失败由结果表示, 不依赖 future 异常