You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spigot InventoryClickEvent空指针异常求助:特殊工作台配方检测异常

解决Spigot特殊工作台InventoryClickEvent的NullPointerException问题

我来帮你分析并解决这个困扰你的问题——从错误日志和描述来看,这个异常的核心原因很明确,咱们一步步拆解:

问题根源

你遇到的IllegalArgumentException: Result cannot be null其实是Bukkit.getRecipesFor()方法抛出的参数校验错误:当你放置第一个物品时,代码传入了null作为这个方法的参数。

看你控制台的第一次输出,全是null的数组,说明此时代码尝试读取的槽位数据还没更新——Spigot的InventoryClickEvent触发时机是在物品完成槽位放置之前,所以刚放第一个物品时,直接读取槽位会拿到更新前的空值,传入getRecipesFor()就触发了非空校验异常。而放第二个物品时,第一个物品已经稳定在槽位里,读取到的不是null,所以能正常执行。

具体修复方案

1. 先做Null校验,再调用配方API

在调用Bukkit.getRecipesFor()之前,必须先检查目标物品栈是否非null,避免触发参数错误:

// 假设你要读取合成槽的某个物品
ItemStack inputItem = event.getInventory().getItem(slotIndex);
if (inputItem != null) {
    List<Recipe> matchingRecipes = Bukkit.getRecipesFor(inputItem);
    // 后续的配方匹配逻辑
} else {
    // 槽位为空时,跳过配方查询或者给出提示
    return;
}

2. 延迟读取槽位数据,确保物品放置完成

因为事件触发时物品还没真正放到槽位里,咱们可以延迟1 tick再执行配方查询,这样能拿到更新后的正确数据:

// 替换yourPluginInstance为你的插件主类实例
Bukkit.getScheduler().runTaskLater(yourPluginInstance, () -> {
    Inventory workbenchInv = event.getInventory();
    ItemStack[] inputSlots = new ItemStack[9];
    // 假设你的特殊工作台前9格是输入槽
    for (int i = 0; i < 9; i++) {
        inputSlots[i] = workbenchInv.getItem(i);
    }
    // 在这里执行配方匹配逻辑,不管是原版还是自定义配方
}, 1L);

3. 分离自定义配方的匹配逻辑

自定义配方没必要依赖Bukkit.getRecipesFor(),建议提前把自定义配方存在一个Map里,比如用输入物品的组合作为Key,结果物品作为Value:

// 初始化自定义配方(可以在插件加载时完成)
Map<List<ItemStack>, ItemStack> customRecipes = new HashMap<>();
// 示例:添加一个自定义配方,比如3个橡木木板换一个石剑
customRecipes.put(Arrays.asList(new ItemStack(Material.OAK_PLANKS), new ItemStack(Material.OAK_PLANKS), new ItemStack(Material.OAK_PLANKS)), new ItemStack(Material.STONE_SWORD));

// 匹配时直接遍历输入槽对比
List<ItemStack> currentInput = Arrays.asList(inputSlots);
if (customRecipes.containsKey(currentInput)) {
    // 匹配到自定义配方,设置结果槽物品
    workbenchInv.setItem(9, customRecipes.get(currentInput));
}

额外调试建议

  • 打印日志时,别只输出数组,加上槽位索引和物品类型,能更清楚定位问题:
    ItemStack[] contents = workbenchInv.getContents();
    for (int i = 0; i < contents.length; i++) {
        ItemStack item = contents[i];
        Bukkit.getLogger().info("槽位 " + i + ": " + (item == null ? "空" : item.getType().name()));
    }
    
  • 记得在事件监听里先判断当前打开的是不是你的特殊工作台,避免误处理普通工作台的事件:
    if (!event.getView().getTitle().equals("你的特殊工作台标题")) {
        return;
    }
    

内容的提问来源于stack exchange,提问作者F4LS3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 19:57:44