主题
这页面向 想从别的插件读取或调用 HNWarehouse 能力的开发者。
当前公开入口
当前静态 API 入口类是:
com.github.hnplugins.hnwarehouse.api.HNWarehouseAPI
它当前已经公开:
getServices()deliverItem(...)deliverReward(...)deliverAutoCollect(...)deliverToWarehouse(...)withdraw(...)withdrawToInventory(...)getSummary(...)getWarehouseSummary(...)- 若干访问状态判断方法
另外还提供了工具类 ItemDeliveryResultUtils 用于处理投递结果:
hasBlockedWarehouses(result)getBlockedWarehouseIds(result)getBlockedWarehouseReasonMap(result)describeBlockedWarehouses(result)
接入前提
插件依赖
如果你的插件要直接编译期调用 HNWarehouse API,通常应至少保证:
HNCoreHNWarehouse
都在你的运行环境中可用。
运行时判断
建议在真正调用前先确认插件已加载:
java
Plugin plugin = Bukkit.getPluginManager().getPlugin("HNWarehouse");
if (plugin == null || !plugin.isEnabled()) {
return;
}如果你的业务逻辑允许“有仓库就入仓,没有仓库就走普通发奖”,那这里最好做成可回退流程,而不是硬崩。
关于 reload 窗口
当前 HNWarehouse 的管理员重载已经改成后台执行。
这意味着:
- 插件本体仍然是启用状态,但重载窗口里运行时服务可能暂时不可用
HNWarehouseAPI.getServices()不适合被下游长期缓存后反复直接使用- 更稳妥的做法是:每次真正调用前重新获取服务,或在调用点做好降级 / 跳过 / 重试保护
如果你的业务属于“高频触发、不能接受偶发不可用窗口”,建议额外做:
- 插件可用性判断
- 调用失败后的回退流程
- 避免把
HNWarehouseServices保存成长期单例引用
可以做什么
通过当前 API,你已经可以:
- 把一件物品按默认来源投递到玩家仓库
- 显式投递到指定仓库
- 预判投递结果中的被拦截仓库信息
- 查询玩家整体仓库摘要与单仓库摘要
- 判断仓库当前是否可访问、是否锁定、是否需要解锁
- 从指定条目执行提取 / 回填背包
例如你可以基于它做:
- 任务奖励自动入仓
- 签到奖励或补偿奖励自动入仓
- 其他插件的“共享仓库入口”
- 面板类查询展示
- 条件判断:某个仓库当前是否开放
最常见的三种接入方式
1. 把奖励直接送进仓库
java
import com.github.hnplugins.hnwarehouse.api.HNWarehouseAPI;
import com.github.hnplugins.hnwarehouse.api.ItemDeliveryResultUtils;
import com.github.hnplugins.hnwarehouse.service.result.ItemDeliveryResult;
import org.bukkit.inventory.ItemStack;
UUID playerId = player.getUniqueId();
ItemStack reward = new ItemStack(Material.DIAMOND, 8);
ItemDeliveryResult result = HNWarehouseAPI.deliverReward(playerId, reward);
if (result.deliveredAmount() <= 0) {
player.sendMessage("奖励入仓失败:" + ItemDeliveryResultUtils.describeBlockedWarehouses(result));
}适合:
- 奖励型业务
- 补偿邮件转仓库
- 活动奖励自动入仓
2. 显式投到指定仓库
java
ItemDeliveryResult result = HNWarehouseAPI.deliverToWarehouse(
player.getUniqueId(),
"reward",
ItemDeliverySource.REWARD,
itemStack
);适合:
- 业务侧已经明确知道目标仓库
- 但仍想复用 HNWarehouse 的访问规则、页面路由与
item-admission
3. 先判断仓库可不可用,再决定怎么处理
java
String warehouseId = "main";
if (!HNWarehouseAPI.isWarehouseAccessible(player.getUniqueId(), warehouseId)) {
String reason = HNWarehouseAPI.getWarehouseDenialReason(player.getUniqueId(), warehouseId);
player.sendMessage("仓库当前不可用:" + reason);
return;
}
WarehouseSummary summary = HNWarehouseAPI.getWarehouseSummary(player.getUniqueId(), warehouseId);
player.sendMessage("当前仓库页数:" + summary.totalPages());适合:
- 打开面板前预检
- 业务入口做动态开放判断
- 运营活动只对已开放仓库生效
投递相关入口
默认投递
deliverItem(UUID, ItemStack)deliverReward(UUID, ItemStack)deliverAutoCollect(UUID, ItemStack)
适合场景:
- 由来源语义直接决定默认目标仓库
- 下游只关心“把物品交给仓库系统”,不关心具体落哪一页
指定仓库投递
deliverToWarehouse(UUID, String, ItemStack)deliverToWarehouse(UUID, String, ItemDeliverySource, ItemStack)
适合场景:
- 业务侧明确知道应该进入哪个仓库
- 但仍希望复用仓库访问规则、页面路由与
item-admission
被拦截仓库辅助方法
当使用投递 API 后,可以通过以下工具方法检查投递结果中被拦截的仓库信息:
hasBlockedWarehouses(result)
检查投递结果中是否有被拦截的仓库。
java
ItemDeliveryResult result = HNWarehouseAPI.deliverItem(playerId, itemStack);
if (ItemDeliveryResultUtils.hasBlockedWarehouses(result)) {
// 有仓库被拦截,需要处理
}getBlockedWarehouseIds(result)
获取所有被拦截的仓库 ID 列表。
java
List<String> blockedIds = ItemDeliveryResultUtils.getBlockedWarehouseIds(result);
player.sendMessage("以下仓库拒绝了物品:" + String.join(", ", blockedIds));getBlockedWarehouseReasonMap(result)
获取被拦截仓库的详细原因映射(仓库 ID → 拦截原因)。
java
Map<String, String> reasonMap = ItemDeliveryResultUtils.getBlockedWarehouseReasonMap(result);
for (Map.Entry<String, String> entry : reasonMap.entrySet()) {
player.sendMessage("仓库 " + entry.getKey() + " 拒绝原因:" + entry.getValue());
}describeBlockedWarehouses(result)
生成被拦截仓库的可读描述文本。
java
String description = ItemDeliveryResultUtils.describeBlockedWarehouses(result);
if (!description.isEmpty()) {
player.sendMessage("投递失败详情:\n" + description);
}适合场景:
- 做投递失败提示
- 输出调试日志
- 给管理面板展示"为什么没进去"
- 帮助玩家理解物品为何被拒绝
提取相关入口
当前已提供:
withdraw(UUID, warehouseId, pageId, entryId)withdraw(UUID, warehouseId, pageId, entryId, requestedAmount)withdrawToInventory(UUID, warehouseId, pageId, entryId)withdrawToInventory(UUID, warehouseId, pageId, entryId, requestedAmount)
示例:把指定条目提回玩家背包
java
import com.github.hnplugins.hnwarehouse.service.result.ItemWithdrawalResult;
ItemWithdrawalResult result = HNWarehouseAPI.withdrawToInventory(
player.getUniqueId(),
"main",
"page-1",
entryId,
16
);
if (!result.isSuccessful()) {
player.sendMessage("提取失败:" + result.failureReason());
return;
}
player.sendMessage("提取成功,数量:" + result.withdrawnAmount());使用建议:
- 如果你要做“直接得到提取结果对象”,可用
withdraw(...) - 如果你要做“直接把物品送回玩家背包”,可用
withdrawToInventory(...)
查询相关入口
玩家整体摘要
getSummary(UUID)
说明:
- 如果目标玩家当前在线,通常更接近运行时内存态摘要
- 如果目标玩家离线,摘要查询可能命中短 TTL 缓存
- 写入发生后,相关摘要缓存会主动失效
适合读取:
- 总仓库数 / 总页数 / 总容量
- 当前可访问仓库数与锁定仓库数
- 各仓库摘要列表
示例:读取玩家总览
java
import com.github.hnplugins.hnwarehouse.view.PlayerStorageSummary;
PlayerStorageSummary summary = HNWarehouseAPI.getSummary(player.getUniqueId());
player.sendMessage("总仓库数:" + summary.totalWarehouses());
player.sendMessage("总页数:" + summary.totalPages());
player.sendMessage("可访问仓库:" + summary.accessibleWarehouses());单仓库摘要
getWarehouseSummary(UUID, warehouseId)
适合读取:
- 当前仓库是否可访问
- 是否锁定
- 是否属于“需要一次性解锁”的状态
- 当前不可访问原因
- 锁定时是否允许展示
示例:做仓库状态提示
java
WarehouseSummary summary = HNWarehouseAPI.getWarehouseSummary(player.getUniqueId(), "main");
if (summary.locked()) {
player.sendMessage("仓库当前锁定,原因:" + summary.denialReason());
if (summary.unlockRequired()) {
player.sendMessage("这是可解锁仓库,可以引导玩家执行 /hnwarehouse unlock main");
}
}便捷判断方法
isWarehouseAccessible(...)isWarehouseLocked(...)requiresWarehouseUnlock(...)getWarehouseDenialReason(...)isWarehouseVisibleWhenLocked(...)
关于写操作的建议
虽然当前 API 已经开放了投递与提取写操作,但从下游接入角度,仍建议你:
- 优先通过 API 调用统一 service,而不是自己改玩家 YAML
- 不要绕过访问校验、页面路由或条目逻辑自己拼状态
- 不要把 HNWarehouse 当成“一个纯
List<ItemStack>容器”去硬写
原因是当前实际联动的不只是条目本身,还包括:
- 仓库访问状态
- 解锁 / 购买 / 扩容状态
- 页面优先级与允许来源
item-admission规则- 提取回背包时的在线玩家状态
与 HNCore 的关系
HNWarehouse 当前依赖 HNCore 的公共能力,尤其是:
- 公共日志能力
- 公共命令注册能力
- 共享物品库入口
- 物品身份协议与 PDC 约定的协作边界
如果你只是想复用公共基础能力,优先直接看 HNCore;如果你想复用“仓库路由、访问控制、条目提取”这一层业务语义,再看 HNWarehouse。
当前 API 的边界
当前版本更偏向:
- 业务接入可用
- 查询与统一投递可用
- 仓库系统骨架已稳定
- 但仍不是一个已经完全成熟的“仓储 SDK”
尤其要注意:
- 自动收纳监听器等部分能力仍在骨架阶段
- 原版背包投影与更深层接管尚未完整接入
- GUI 流程当前可用,但玩家入口还不是最终形态
也就是说,它已经足够拿来做:
- 奖励入仓
- 查询展示
- 管理命令联动
- 仓库状态判断
但如果你想做“完全接管玩家所有物品流转”,目前仍建议结合源码与真实场景逐步接入。
新功能(v0.1.0-SNAPSHOT)
搜索功能
HNWarehouse 现已集成 HNCore 2.3.0 的搜索框架,为仓库页面提供智能物品搜索功能。
功能特性
- 智能相关度评分:完全匹配 > 开头匹配 > 包含匹配 > 类型匹配 > ID 匹配
- 多字段搜索:支持按物品名称、类型、条目 ID 搜索
- 搜索结果分页:每页显示 45 个结果,支持翻页浏览
- 直接提取:可从搜索结果直接提取物品
- 审计日志:所有搜索操作都会记录
使用方式
玩家在仓库页面 GUI 中:
- 点击搜索图标(望远镜,槽位 47)
- 在聊天框输入搜索关键词
- 查看搜索结果 GUI
- 点击物品提取或翻页查看更多
取消搜索
输入 cancel 或 取消 可取消搜索操作。
输入会话框架
取款数量输入功能已改造为使用 HNCore 2.3.0 的统一输入会话框架。
功能特性
- 统一会话管理:自动处理会话生命周期
- 自动超时:60 秒无输入自动超时并重新打开页面
- 线程安全:使用 ConcurrentHashMap 管理会话
- 输入验证:支持正整数、"cancel"、"取消"命令
使用方式
玩家在仓库页面 GUI 中:
- Shift + 右键点击物品
- 在聊天框输入要提取的数量
- 系统自动验证并执行提取
取消提取
输入 cancel 或 取消 可取消提取操作。
推荐接入姿势
如果你只是想发一件奖励到玩家仓库
优先使用:
deliverReward(...)
如果你想把某类业务物品固定投到某个仓库
优先使用:
deliverToWarehouse(...)
如果你只是想判断某仓库当前能不能打开
优先读取:
getWarehouseSummary(...)isWarehouseAccessible(...)getWarehouseDenialReason(...)
如果你想做自己的管理面板
优先读取:
getSummary(...)getWarehouseSummary(...)
不要直接读磁盘 YAML 再自己拼页面逻辑。
