From 543284e016a37a823c6b6b35f900ba66c4221920 Mon Sep 17 00:00:00 2001 From: Pierre Maurice Schwang Date: Fri, 4 Feb 2022 18:21:43 +0100 Subject: [PATCH] fix: NPE on unavailable music discs on lower versions (#3475) * fix: NPE on unavailable music discs * chore: documentation for InventoryUtil changes * fix: no need for additional decrement * chore: address requested changes * fix: prevent binary mismatch Co-authored-by: Alex --- .../bukkit/util/BukkitInventoryUtil.java | 22 +++++++++++----- .../com/plotsquared/core/command/Music.java | 11 ++++++-- .../plotsquared/core/plot/PlotInventory.java | 25 ++++++++++++++++++- .../plotsquared/core/plot/PlotItemStack.java | 16 +++++++++++- .../plotsquared/core/util/InventoryUtil.java | 24 +++++++++++++++++- 5 files changed, 87 insertions(+), 11 deletions(-) diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitInventoryUtil.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitInventoryUtil.java index 8a4e57e78..57aefb9b6 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitInventoryUtil.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitInventoryUtil.java @@ -42,6 +42,7 @@ import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.meta.ItemMeta; +import org.checkerframework.checker.nullness.qual.Nullable; import java.util.ArrayList; import java.util.List; @@ -50,11 +51,15 @@ import java.util.stream.IntStream; @Singleton public class BukkitInventoryUtil extends InventoryUtil { - private static ItemStack getItem(PlotItemStack item) { + private static @Nullable ItemStack getItem(PlotItemStack item) { if (item == null) { return null; } - ItemStack stack = new ItemStack(BukkitAdapter.adapt(item.getType()), item.getAmount()); + Material material = BukkitAdapter.adapt(item.getType()); + if (material == null) { + return null; + } + ItemStack stack = new ItemStack(material, item.getAmount()); ItemMeta meta = null; if (item.getName() != null) { meta = stack.getItemMeta(); @@ -104,14 +109,19 @@ public class BukkitInventoryUtil extends InventoryUtil { } @Override - public void setItem(PlotInventory inv, int index, PlotItemStack item) { + public boolean setItemChecked(PlotInventory inv, int index, PlotItemStack item) { BukkitPlayer bp = (BukkitPlayer) inv.getPlayer(); InventoryView opened = bp.player.getOpenInventory(); - if (!inv.isOpen()) { - return; + ItemStack stack = getItem(item); + if (stack == null) { + return false; } - opened.setItem(index, getItem(item)); + if (!inv.isOpen()) { + return true; + } + opened.setItem(index, stack); bp.player.updateInventory(); + return true; } @SuppressWarnings("deprecation") // Paper deprecation diff --git a/Core/src/main/java/com/plotsquared/core/command/Music.java b/Core/src/main/java/com/plotsquared/core/command/Music.java index f83329b59..a8eec9db8 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Music.java +++ b/Core/src/main/java/com/plotsquared/core/command/Music.java @@ -41,6 +41,7 @@ import com.plotsquared.core.plot.flag.implementations.MusicFlag; import com.plotsquared.core.util.EventDispatcher; import com.plotsquared.core.util.InventoryUtil; import com.plotsquared.core.util.Permissions; +import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.item.ItemTypes; import net.kyori.adventure.text.minimessage.Template; import org.checkerframework.checker.nullness.qual.NonNull; @@ -148,8 +149,14 @@ public class Music extends SubCommand { for (final String disc : DISCS) { final String name = String.format("%s", disc); final String[] lore = {TranslatableCaption.of("plotjukebox.click_to_play").getComponent(player)}; - final PlotItemStack item = new PlotItemStack(disc, 1, name, lore); - inv.setItem(index++, item); + ItemType type = ItemTypes.get(disc); + if (type == null) { + continue; + } + final PlotItemStack item = new PlotItemStack(type, 1, name, lore); + if (inv.setItemChecked(index, item)) { + index++; + } } // Always add the cancel button diff --git a/Core/src/main/java/com/plotsquared/core/plot/PlotInventory.java b/Core/src/main/java/com/plotsquared/core/plot/PlotInventory.java index 7cd2a9d72..8cd1f810f 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/PlotInventory.java +++ b/Core/src/main/java/com/plotsquared/core/plot/PlotInventory.java @@ -103,9 +103,32 @@ public class PlotInventory { this.open = false; } + /** + * Put an item into this inventory + * + * @param index the index (= slot) where to place the item + * @param item the item to place + * @see #setItemChecked(int, PlotItemStack) + */ public void setItem(int index, PlotItemStack item) { + setItemChecked(index, item); + } + + /** + * Put an item into this inventory, while also checking the existence of the material in the current version + * + * @param index the index (= slot) where to place the item + * @param item the item to place + * @return {@code true} if the item could be placed, otherwise {@code false} + * @see InventoryUtil#setItemChecked(PlotInventory, int, PlotItemStack) + * @since TODO + */ + public boolean setItemChecked(int index, PlotItemStack item) { + if (!this.inventoryUtil.setItemChecked(this, index, item)) { + return false; + } this.items[index] = item; - this.inventoryUtil.setItem(this, index, item); + return true; } public PlotItemStack getItem(int index) { diff --git a/Core/src/main/java/com/plotsquared/core/plot/PlotItemStack.java b/Core/src/main/java/com/plotsquared/core/plot/PlotItemStack.java index 8ed3534d8..ac1baacac 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/PlotItemStack.java +++ b/Core/src/main/java/com/plotsquared/core/plot/PlotItemStack.java @@ -46,7 +46,21 @@ public class PlotItemStack { final String id, final int amount, final String name, final String... lore ) { - this.type = ItemTypes.get(id); + this(ItemTypes.get(id), amount, name, lore); + } + + /** + * @param type The item type + * @param amount Amount of items in the stack + * @param name The display name of the item stack + * @param lore The item stack lore + * @since TODO + */ + public PlotItemStack( + final ItemType type, final int amount, final String name, + final String... lore + ) { + this.type = type; this.amount = amount; this.name = name; this.lore = lore; diff --git a/Core/src/main/java/com/plotsquared/core/util/InventoryUtil.java b/Core/src/main/java/com/plotsquared/core/util/InventoryUtil.java index e3aa4fa9f..c9affa957 100644 --- a/Core/src/main/java/com/plotsquared/core/util/InventoryUtil.java +++ b/Core/src/main/java/com/plotsquared/core/util/InventoryUtil.java @@ -38,11 +38,33 @@ public abstract class InventoryUtil { public abstract void close(final PlotInventory inv); - public abstract void setItem( + /** + * Attempts to set an item into a {@link PlotInventory} while also checking the existence of the material + * + * @param plotInventory The inventory where the item should be placed + * @param index The index where to place the item + * @param item The item to place into the inventory + * @return {@code true} if the item could be placed, {@code false} otherwise (e.g. item not available in current version) + * @since TODO + */ + public abstract boolean setItemChecked( final PlotInventory plotInventory, final int index, final PlotItemStack item ); + /** + * Attempts to set an item into a {@link PlotInventory} + * + * @param plotInventory The inventory where the item should be placed + * @param index The index where to place the item + * @param item The item to place into the inventory + * @see #setItemChecked(PlotInventory, int, PlotItemStack) + */ + public void setItem(final PlotInventory plotInventory, final int index, + final PlotItemStack item) { + setItemChecked(plotInventory, index, item); + } + public abstract PlotItemStack[] getItems(final PlotPlayer player); public abstract boolean isOpen(final PlotInventory plotInventory);