From e9886e6352fd18db7bbb2dce18fa0eb1bf680315 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 18:47:45 +0000 Subject: [PATCH 1/4] Initial plan From 1c218a354e9047beb9f78d486d980bb9860dfd24 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 19:07:13 +0000 Subject: [PATCH 2/4] Add custom block support (Oraxen/Nexo/ItemsAdder/CraftEngine) to value, detail, and donate menus Agent-Logs-Url: https://github.com/BentoBoxWorld/Level/sessions/daf183a6-549f-4946-900c-5719c0a27e81 Co-authored-by: tastybento <4407265+tastybento@users.noreply.github.com> --- src/main/java/world/bentobox/level/Level.java | 44 +++++++++++ .../level/commands/IslandDonateCommand.java | 74 ++++++++++++++----- .../level/commands/IslandValueCommand.java | 23 ++---- .../bentobox/level/panels/DetailsPanel.java | 41 ++++++++-- .../bentobox/level/panels/DonationPanel.java | 34 +++++++-- .../bentobox/level/panels/ValuePanel.java | 11 +++ 6 files changed, 176 insertions(+), 51 deletions(-) diff --git a/src/main/java/world/bentobox/level/Level.java b/src/main/java/world/bentobox/level/Level.java index da58a37..bfb89d3 100644 --- a/src/main/java/world/bentobox/level/Level.java +++ b/src/main/java/world/bentobox/level/Level.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.UUID; import org.bukkit.Bukkit; @@ -11,16 +12,21 @@ import org.bukkit.World; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; +import com.nexomc.nexo.api.NexoItems; + import world.bentobox.bentobox.api.addons.Addon; import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.configuration.Config; import world.bentobox.bentobox.api.flags.Flag; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.hooks.ItemsAdderHook; +import world.bentobox.bentobox.hooks.OraxenHook; import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.util.Util; import world.bentobox.level.calculators.Pipeliner; @@ -508,6 +514,44 @@ public boolean isItemsAdder() { return !getSettings().isDisableItemsAdder() && getPlugin().getHooks().getHook("ItemsAdder").isPresent(); } + /** + * Returns the custom-block plugin ID for an ItemStack, checking Oraxen, Nexo, + * and ItemsAdder in that order. Returns {@code null} when the item is not + * recognized as a custom block by any supported plugin. + * + * @param item the ItemStack to check (may be null) + * @return a namespaced custom-block ID such as {@code "oraxen:my_block"}, + * {@code "nexo:my_block"}, or an ItemsAdder ID, or {@code null} + */ + @Nullable + public String getCustomBlockId(ItemStack item) { + if (item == null || item.getType().isAir()) { + return null; + } + // Check Oraxen + if (getPlugin().getHooks().getHook("Oraxen").isPresent()) { + String id = OraxenHook.getIdByItem(item); + if (id != null) { + return "oraxen:" + id; + } + } + // Check Nexo + if (isNexo()) { + String id = NexoItems.idFromItem(item); + if (id != null) { + return "nexo:" + id; + } + } + // Check ItemsAdder + if (isItemsAdder()) { + Optional id = ItemsAdderHook.getNamespacedId(item); + if (id.isPresent()) { + return id.get(); + } + } + return null; + } + /** * @return true if the Nexo plugin is enabled and not disabled in config */ diff --git a/src/main/java/world/bentobox/level/commands/IslandDonateCommand.java b/src/main/java/world/bentobox/level/commands/IslandDonateCommand.java index d4d603e..cd3b682 100644 --- a/src/main/java/world/bentobox/level/commands/IslandDonateCommand.java +++ b/src/main/java/world/bentobox/level/commands/IslandDonateCommand.java @@ -1,6 +1,6 @@ package world.bentobox.level.commands; -import java.util.EnumMap; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -87,13 +87,20 @@ public boolean execute(User user, String label, List args) { */ private boolean handleHandDonation(User user, Island island, List args) { ItemStack hand = user.getPlayer().getInventory().getItemInMainHand(); - if (hand.getType().isAir() || !hand.getType().isBlock()) { + + // Check for a custom block (Oraxen, Nexo, ItemsAdder) first + final String customId = addon.getCustomBlockId(hand); + + // If not a custom block, require a vanilla block + if (customId == null && (hand.getType().isAir() || !hand.getType().isBlock())) { user.sendMessage("island.donate.hand.not-block"); return false; } final Material material = hand.getType(); - final Integer blockValue = addon.getBlockConfig().getValue(getWorld(), material); + final Integer blockValue = customId != null + ? addon.getBlockConfig().getValue(getWorld(), customId) + : addon.getBlockConfig().getValue(getWorld(), material); if (blockValue == null || blockValue <= 0) { user.sendMessage("island.donate.no-value"); return false; @@ -121,18 +128,25 @@ private boolean handleHandDonation(User user, Island island, List args) final long previewPoints = (long) previewAmount * blockValue; final int finalRequested = requested; + Object displayKey = customId != null ? customId : material; String prompt = user.getTranslation("island.donate.hand.confirm-prompt", TextVariables.NUMBER, String.valueOf(previewAmount), - MATERIAL_PLACEHOLDER, Utils.prettifyObject(material, user), + MATERIAL_PLACEHOLDER, Utils.prettifyObject(displayKey, user), POINTS_PLACEHOLDER, Utils.formatNumber(user, previewPoints)); - askConfirmation(user, prompt, () -> performHandDonation(user, island, material, blockValue, finalRequested)); + askConfirmation(user, prompt, () -> performHandDonation(user, island, material, customId, blockValue, finalRequested)); return true; } - private void performHandDonation(User user, Island island, Material material, int blockValue, int requested) { + private void performHandDonation(User user, Island island, Material material, String customId, int blockValue, int requested) { ItemStack currentHand = user.getPlayer().getInventory().getItemInMainHand(); - if (currentHand.getType() != material || currentHand.getAmount() == 0) { + // Verify the item in hand is still the same + if (customId != null) { + if (!customId.equals(addon.getCustomBlockId(currentHand)) || currentHand.getAmount() == 0) { + user.sendMessage("island.donate.hand.not-block"); + return; + } + } else if (currentHand.getType() != material || currentHand.getAmount() == 0) { user.sendMessage("island.donate.hand.not-block"); return; } @@ -145,12 +159,14 @@ private void performHandDonation(User user, Island island, Material material, in currentHand.setAmount(currentHand.getAmount() - amount); } - addon.getManager().donateBlocks(island, user.getUniqueId(), material.name(), amount, points); + String donationId = customId != null ? customId : material.name(); + addon.getManager().donateBlocks(island, user.getUniqueId(), donationId, amount, points); addon.getManager().recalculateAfterDonation(island); + Object displayKey = customId != null ? customId : material; user.sendMessage("island.donate.hand.success", TextVariables.NUMBER, String.valueOf(amount), - MATERIAL_PLACEHOLDER, Utils.prettifyObject(material, user), + MATERIAL_PLACEHOLDER, Utils.prettifyObject(displayKey, user), POINTS_PLACEHOLDER, Utils.formatNumber(user, points)); } @@ -161,7 +177,7 @@ private void performHandDonation(User user, Island island, Material material, in * donatable blocks remain in the inventory. */ private boolean handleInvDonation(User user, Island island) { - Map totals = collectDonatableTotals(user.getPlayer().getInventory()); + Map totals = collectDonatableTotals(user.getPlayer().getInventory()); if (totals.isEmpty()) { user.sendMessage("island.donate.empty"); @@ -171,13 +187,17 @@ private boolean handleInvDonation(User user, Island island) { long totalPoints = 0L; StringBuilder prompt = new StringBuilder( user.getTranslation("island.donate.inv.confirm-header")); - for (Map.Entry e : totals.entrySet()) { - int value = addon.getBlockConfig().getValue(getWorld(), e.getKey()); + for (Map.Entry e : totals.entrySet()) { + // Resolve back to Material when possible for a nicer display label + Object displayKey; + Material mat = Material.matchMaterial(e.getKey()); + displayKey = mat != null ? mat : e.getKey(); + int value = addon.getBlockConfig().getValue(getWorld(), displayKey); long points = (long) value * e.getValue(); totalPoints += points; prompt.append('\n').append(user.getTranslation("island.donate.inv.confirm-line", TextVariables.NUMBER, String.valueOf(e.getValue()), - MATERIAL_PLACEHOLDER, Utils.prettifyObject(e.getKey(), user), + MATERIAL_PLACEHOLDER, Utils.prettifyObject(displayKey, user), POINTS_PLACEHOLDER, Utils.formatNumber(user, points))); } prompt.append('\n').append(user.getTranslation("island.donate.inv.confirm-total", @@ -190,7 +210,7 @@ private boolean handleInvDonation(User user, Island island) { private void performInvDonation(User user, Island island) { PlayerInventory pInv = user.getPlayer().getInventory(); ItemStack[] contents = pInv.getStorageContents(); - Map donated = new EnumMap<>(Material.class); + Map donated = new HashMap<>(); long totalPoints = 0L; for (int i = 0; i < contents.length; i++) { @@ -201,9 +221,11 @@ private void performInvDonation(User user, Island island) { } int amount = item.getAmount(); long points = (long) value * amount; - donated.merge(item.getType(), amount, Integer::sum); + String customId = addon.getCustomBlockId(item); + String donationId = customId != null ? customId : item.getType().name(); + donated.merge(donationId, amount, Integer::sum); totalPoints += points; - addon.getManager().donateBlocks(island, user.getUniqueId(), item.getType().name(), amount, points); + addon.getManager().donateBlocks(island, user.getUniqueId(), donationId, amount, points); contents[i] = null; } pInv.setStorageContents(contents); @@ -219,11 +241,13 @@ private void performInvDonation(User user, Island island) { addon.getManager().recalculateAfterDonation(island); } - private Map collectDonatableTotals(PlayerInventory pInv) { - Map totals = new EnumMap<>(Material.class); + private Map collectDonatableTotals(PlayerInventory pInv) { + Map totals = new HashMap<>(); for (ItemStack item : pInv.getStorageContents()) { if (donationValue(item) != null) { - totals.merge(item.getType(), item.getAmount(), Integer::sum); + String customId = addon.getCustomBlockId(item); + String key = customId != null ? customId : item.getType().name(); + totals.merge(key, item.getAmount(), Integer::sum); } } return totals; @@ -234,7 +258,17 @@ private Map collectDonatableTotals(PlayerInventory pInv) { * positive configured value, or null otherwise */ private Integer donationValue(ItemStack item) { - if (item == null || item.getType().isAir() || !item.getType().isBlock()) { + if (item == null || item.getType().isAir()) { + return null; + } + // Check custom block plugins first (Oraxen, Nexo, ItemsAdder) + String customId = addon.getCustomBlockId(item); + if (customId != null) { + Integer value = addon.getBlockConfig().getValue(getWorld(), customId); + return (value != null && value > 0) ? value : null; + } + // Fall back to vanilla block check + if (!item.getType().isBlock()) { return null; } Integer value = addon.getBlockConfig().getValue(getWorld(), item.getType()); diff --git a/src/main/java/world/bentobox/level/commands/IslandValueCommand.java b/src/main/java/world/bentobox/level/commands/IslandValueCommand.java index 92141ff..3501911 100644 --- a/src/main/java/world/bentobox/level/commands/IslandValueCommand.java +++ b/src/main/java/world/bentobox/level/commands/IslandValueCommand.java @@ -11,12 +11,9 @@ import org.bukkit.inventory.PlayerInventory; import org.eclipse.jdt.annotation.NonNull; -import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; -import world.bentobox.bentobox.hooks.ItemsAdderHook; -import world.bentobox.bentobox.hooks.OraxenHook; import world.bentobox.bentobox.util.Util; import world.bentobox.level.Level; import world.bentobox.level.objects.IslandLevels; @@ -80,21 +77,11 @@ private void executeHandCommand(User user) { return; } - // Oraxen - if (BentoBox.getInstance().getHooks().getHook("Oraxen").isPresent()) { - String id = OraxenHook.getIdByItem(mainHandItem); - if (id != null) { - printValue(user, "oraxen:" + id); - return; - } - } - // ItemsAdder - if (addon.isItemsAdder()) { - Optional id = ItemsAdderHook.getNamespacedId(mainHandItem); - if (id.isPresent()) { - printValue(user, id.get()); - return; - } + // Check custom block plugins first (Oraxen, Nexo, ItemsAdder) + String customId = addon.getCustomBlockId(mainHandItem); + if (customId != null) { + printValue(user, customId); + return; } printValue(user, mainHandItem.getType()); diff --git a/src/main/java/world/bentobox/level/panels/DetailsPanel.java b/src/main/java/world/bentobox/level/panels/DetailsPanel.java index d19769b..3a27485 100644 --- a/src/main/java/world/bentobox/level/panels/DetailsPanel.java +++ b/src/main/java/world/bentobox/level/panels/DetailsPanel.java @@ -12,8 +12,10 @@ import org.bukkit.inventory.ItemStack; import com.google.common.base.Enums; +import com.nexomc.nexo.api.NexoItems; import lv.id.bonne.panelutils.PanelUtils; +import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.TemplatedPanel; @@ -23,6 +25,7 @@ import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.hooks.ItemsAdderHook; +import world.bentobox.bentobox.hooks.OraxenHook; import world.bentobox.level.Level; import world.bentobox.level.objects.IslandLevels; import world.bentobox.level.util.Utils; @@ -738,14 +741,38 @@ private BlockDataRec getBlockData(Object key) { Objects.requireNonNullElse(this.addon.getBlockConfig().getLimit(e), 0), Utils.prettifyObject(key, this.user), this.user.getTranslation(this.world, "level.gui.buttons.spawner.block-name")); - } else if (key instanceof String s && addon.isItemsAdder()) { - Optional opt = ItemsAdderHook.getItemStack(s); - ItemStack icon = opt.orElse(new ItemStack(Material.PAPER)); - String disp = opt.filter(is -> is.getItemMeta().hasDisplayName()) - .map(is -> is.getItemMeta().getDisplayName()).orElse(Utils.prettifyObject(key, this.user)); - return new BlockDataRec(icon, this.user.getTranslationOrNothing(ref + "id", "[id]", s), + } else if (key instanceof String s) { + ItemStack icon = new ItemStack(Material.PAPER); + String disp = Utils.prettifyObject(s, this.user); + + if (s.startsWith("oraxen:") && BentoBox.getInstance().getHooks().getHook("Oraxen").isPresent()) { + Optional opt = OraxenHook.getOptionalItemById(s.substring(7)); + if (opt.isPresent()) { + icon = opt.get().build(); + if (icon.getItemMeta() != null && icon.getItemMeta().hasDisplayName()) { + disp = icon.getItemMeta().getDisplayName(); + } + } + } else if (s.startsWith("nexo:") && addon.isNexo()) { + com.nexomc.nexo.items.ItemBuilder nexoItem = NexoItems.itemFromId(s.substring(5)); + if (nexoItem != null) { + icon = nexoItem.build(); + if (icon.getItemMeta() != null && icon.getItemMeta().hasDisplayName()) { + disp = icon.getItemMeta().getDisplayName(); + } + } + } else if (addon.isItemsAdder() && ItemsAdderHook.isInRegistry(s)) { + Optional opt = ItemsAdderHook.getItemStack(s); + icon = opt.orElse(new ItemStack(Material.PAPER)); + disp = opt.filter(is -> is.getItemMeta() != null && is.getItemMeta().hasDisplayName()) + .map(is -> is.getItemMeta().getDisplayName()).orElse(Utils.prettifyObject(s, this.user)); + } + + return new BlockDataRec(icon, + this.user.getTranslationOrNothing(ref + "id", "[id]", s), this.addon.getBlockConfig().getBlockValues().getOrDefault(s, 0), - Objects.requireNonNullElse(this.addon.getBlockConfig().getLimit(s), 0), disp, ""); + Objects.requireNonNullElse(this.addon.getBlockConfig().getLimit(s), 0), + disp, ""); } return new BlockDataRec(new ItemStack(Material.PAPER), "", 0, 0, Utils.prettifyObject(key, this.user), ""); } diff --git a/src/main/java/world/bentobox/level/panels/DonationPanel.java b/src/main/java/world/bentobox/level/panels/DonationPanel.java index ccb5ae7..760611e 100644 --- a/src/main/java/world/bentobox/level/panels/DonationPanel.java +++ b/src/main/java/world/bentobox/level/panels/DonationPanel.java @@ -137,7 +137,10 @@ private long calculateDonationValue() { for (int slot : layout.donationSlots) { ItemStack item = inventory.getItem(slot); if (item != null && !item.getType().isAir()) { - Integer value = addon.getBlockConfig().getValue(world, item.getType()); + String customId = addon.getCustomBlockId(item); + Integer value = customId != null + ? addon.getBlockConfig().getValue(world, customId) + : addon.getBlockConfig().getValue(world, item.getType()); if (value != null && value > 0) { total += (long) value * item.getAmount(); } @@ -176,15 +179,24 @@ private void processDonation() { for (int slot : layout.donationSlots) { ItemStack item = inventory.getItem(slot); if (item != null && !item.getType().isAir()) { - Material mat = item.getType(); - Integer value = addon.getBlockConfig().getValue(world, mat); + String customId = addon.getCustomBlockId(item); + String donationId; + Integer value; + if (customId != null) { + value = addon.getBlockConfig().getValue(world, customId); + donationId = customId; + } else { + Material mat = item.getType(); + value = addon.getBlockConfig().getValue(world, mat); + donationId = mat.name(); + } if (value != null && value > 0) { int count = item.getAmount(); long points = (long) value * count; - donations.merge(mat.name(), count, Integer::sum); + donations.merge(donationId, count, Integer::sum); totalPoints += points; // Record each material type as a separate donation log entry - addon.getManager().donateBlocks(island, user.getUniqueId(), mat.name(), count, points); + addon.getManager().donateBlocks(island, user.getUniqueId(), donationId, count, points); // Clear the slot - items are consumed inventory.setItem(slot, null); } else { @@ -337,7 +349,17 @@ private void handleDonationSlotClick(int slot, Player player) { } private boolean isValidDonationItem(ItemStack item) { - if (item == null || item.getType().isAir() || !item.getType().isBlock()) { + if (item == null || item.getType().isAir()) { + return false; + } + // Check custom block plugins first (Oraxen, Nexo, ItemsAdder) + String customId = addon.getCustomBlockId(item); + if (customId != null) { + Integer value = addon.getBlockConfig().getValue(world, customId); + return value != null && value > 0; + } + // Fall back to vanilla block check + if (!item.getType().isBlock()) { return false; } Integer value = addon.getBlockConfig().getValue(world, item.getType()); diff --git a/src/main/java/world/bentobox/level/panels/ValuePanel.java b/src/main/java/world/bentobox/level/panels/ValuePanel.java index 70a0bf1..23361ed 100644 --- a/src/main/java/world/bentobox/level/panels/ValuePanel.java +++ b/src/main/java/world/bentobox/level/panels/ValuePanel.java @@ -28,6 +28,7 @@ import world.bentobox.bentobox.api.panels.builders.TemplatedPanelBuilder; import world.bentobox.bentobox.api.panels.reader.ItemTemplateRecord; import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.hooks.CraftEngineHook; import world.bentobox.bentobox.hooks.ItemsAdderHook; import world.bentobox.bentobox.util.Util; import world.bentobox.level.Level; @@ -735,6 +736,14 @@ private Material getIcon(String key) { if (key.startsWith("oraxen:") && BentoBox.getInstance().getHooks().getHook("Oraxen").isPresent()) { return Material.PAPER; } + // Try Nexo + if (key.startsWith("nexo:") && addon.isNexo()) { + return Material.PAPER; + } + // Try CraftEngine — IDs are already namespaced (e.g. "mynamespace:my_block") + if (addon.isCraftEngine() && CraftEngineHook.exists(key)) { + return Material.PAPER; + } return null; } @@ -769,6 +778,8 @@ private PanelItem createMaterialButton(ItemTemplateRecord template, BlockRecord builder.icon((icon == null || icon == Material.AIR) ? Material.PAPER : icon); if (key.startsWith("oraxen:")) { key = key.substring(7); + } else if (key.startsWith("nexo:")) { + key = key.substring(5); } String displayMaterial = (icon == null) ? Util.prettifyText(key) : Utils.prettifyObject(key, user); // Special handling for spawn eggs From 9c3e38a38da1865c183f9f6d0476fc4f952c0588 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 19:11:25 +0000 Subject: [PATCH 3/4] Refactor: extract getCustomBlockItemStack helper, add null guard for inv donation value Agent-Logs-Url: https://github.com/BentoBoxWorld/Level/sessions/daf183a6-549f-4946-900c-5719c0a27e81 Co-authored-by: tastybento <4407265+tastybento@users.noreply.github.com> --- .../level/commands/IslandDonateCommand.java | 12 +++-- .../bentobox/level/panels/DetailsPanel.java | 53 ++++++++++--------- 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/src/main/java/world/bentobox/level/commands/IslandDonateCommand.java b/src/main/java/world/bentobox/level/commands/IslandDonateCommand.java index cd3b682..520298c 100644 --- a/src/main/java/world/bentobox/level/commands/IslandDonateCommand.java +++ b/src/main/java/world/bentobox/level/commands/IslandDonateCommand.java @@ -188,12 +188,14 @@ private boolean handleInvDonation(User user, Island island) { StringBuilder prompt = new StringBuilder( user.getTranslation("island.donate.inv.confirm-header")); for (Map.Entry e : totals.entrySet()) { - // Resolve back to Material when possible for a nicer display label - Object displayKey; + // Resolve back to Material when possible for correct key-casing in getValue() + // (vanilla keys are stored uppercase by material.name(), but blockValues uses lowercase). + // For custom blocks the key is already the right namespaced string. Material mat = Material.matchMaterial(e.getKey()); - displayKey = mat != null ? mat : e.getKey(); - int value = addon.getBlockConfig().getValue(getWorld(), displayKey); - long points = (long) value * e.getValue(); + Object displayKey = mat != null ? mat : e.getKey(); + Integer rawValue = addon.getBlockConfig().getValue(getWorld(), displayKey); + if (rawValue == null) continue; + long points = (long) rawValue * e.getValue(); totalPoints += points; prompt.append('\n').append(user.getTranslation("island.donate.inv.confirm-line", TextVariables.NUMBER, String.valueOf(e.getValue()), diff --git a/src/main/java/world/bentobox/level/panels/DetailsPanel.java b/src/main/java/world/bentobox/level/panels/DetailsPanel.java index 3a27485..6e345b7 100644 --- a/src/main/java/world/bentobox/level/panels/DetailsPanel.java +++ b/src/main/java/world/bentobox/level/panels/DetailsPanel.java @@ -742,31 +742,12 @@ private BlockDataRec getBlockData(Object key) { Utils.prettifyObject(key, this.user), this.user.getTranslation(this.world, "level.gui.buttons.spawner.block-name")); } else if (key instanceof String s) { - ItemStack icon = new ItemStack(Material.PAPER); - String disp = Utils.prettifyObject(s, this.user); - - if (s.startsWith("oraxen:") && BentoBox.getInstance().getHooks().getHook("Oraxen").isPresent()) { - Optional opt = OraxenHook.getOptionalItemById(s.substring(7)); - if (opt.isPresent()) { - icon = opt.get().build(); - if (icon.getItemMeta() != null && icon.getItemMeta().hasDisplayName()) { - disp = icon.getItemMeta().getDisplayName(); - } - } - } else if (s.startsWith("nexo:") && addon.isNexo()) { - com.nexomc.nexo.items.ItemBuilder nexoItem = NexoItems.itemFromId(s.substring(5)); - if (nexoItem != null) { - icon = nexoItem.build(); - if (icon.getItemMeta() != null && icon.getItemMeta().hasDisplayName()) { - disp = icon.getItemMeta().getDisplayName(); - } - } - } else if (addon.isItemsAdder() && ItemsAdderHook.isInRegistry(s)) { - Optional opt = ItemsAdderHook.getItemStack(s); - icon = opt.orElse(new ItemStack(Material.PAPER)); - disp = opt.filter(is -> is.getItemMeta() != null && is.getItemMeta().hasDisplayName()) - .map(is -> is.getItemMeta().getDisplayName()).orElse(Utils.prettifyObject(s, this.user)); - } + Optional optItem = getCustomBlockItemStack(s); + ItemStack icon = optItem.orElse(new ItemStack(Material.PAPER)); + String disp = optItem + .filter(is -> is.getItemMeta() != null && is.getItemMeta().hasDisplayName()) + .map(is -> is.getItemMeta().getDisplayName()) + .orElse(Utils.prettifyObject(s, this.user)); return new BlockDataRec(icon, this.user.getTranslationOrNothing(ref + "id", "[id]", s), @@ -777,6 +758,28 @@ private BlockDataRec getBlockData(Object key) { return new BlockDataRec(new ItemStack(Material.PAPER), "", 0, 0, Utils.prettifyObject(key, this.user), ""); } + /** + * Returns the best available ItemStack for a custom-block string ID. + * Checks Oraxen, Nexo, and ItemsAdder in order; returns empty when none matches. + * + * @param id the custom block ID (e.g. "oraxen:my_block", "nexo:my_block", or an ItemsAdder ID) + * @return an Optional containing the representative ItemStack, or empty + */ + private Optional getCustomBlockItemStack(String id) { + if (id.startsWith("oraxen:") && BentoBox.getInstance().getHooks().getHook("Oraxen").isPresent()) { + return OraxenHook.getOptionalItemById(id.substring(7)) + .map(ib -> ib.build()); + } + if (id.startsWith("nexo:") && addon.isNexo()) { + com.nexomc.nexo.items.ItemBuilder nexoItem = NexoItems.itemFromId(id.substring(5)); + return nexoItem != null ? Optional.of(nexoItem.build()) : Optional.empty(); + } + if (addon.isItemsAdder() && ItemsAdderHook.isInRegistry(id)) { + return ItemsAdderHook.getItemStack(id); + } + return Optional.empty(); + } + // --------------------------------------------------------------------- // Section: Other Methods From 7d5b8dbb5e94a292b49e78676da8888af0711f40 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 19:13:56 +0000 Subject: [PATCH 4/4] Polish: improve clarity of comments and variable names from code review Agent-Logs-Url: https://github.com/BentoBoxWorld/Level/sessions/daf183a6-549f-4946-900c-5719c0a27e81 Co-authored-by: tastybento <4407265+tastybento@users.noreply.github.com> --- .../bentobox/level/commands/IslandDonateCommand.java | 8 +++++--- .../java/world/bentobox/level/panels/DetailsPanel.java | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/world/bentobox/level/commands/IslandDonateCommand.java b/src/main/java/world/bentobox/level/commands/IslandDonateCommand.java index 520298c..80af368 100644 --- a/src/main/java/world/bentobox/level/commands/IslandDonateCommand.java +++ b/src/main/java/world/bentobox/level/commands/IslandDonateCommand.java @@ -188,9 +188,11 @@ private boolean handleInvDonation(User user, Island island) { StringBuilder prompt = new StringBuilder( user.getTranslation("island.donate.inv.confirm-header")); for (Map.Entry e : totals.entrySet()) { - // Resolve back to Material when possible for correct key-casing in getValue() - // (vanilla keys are stored uppercase by material.name(), but blockValues uses lowercase). - // For custom blocks the key is already the right namespaced string. + // Vanilla keys are stored as Material.name() (e.g. "STONE"), but blockValues uses + // the lowercase namespaced key (e.g. "stone"). Resolving to a Material first lets + // getValue() derive the correct lowercase key via material.getKey().getKey(). + // Custom-block keys (e.g. "oraxen:my_block") do not match any Material, so they + // are passed through as Strings and match blockValues directly. Material mat = Material.matchMaterial(e.getKey()); Object displayKey = mat != null ? mat : e.getKey(); Integer rawValue = addon.getBlockConfig().getValue(getWorld(), displayKey); diff --git a/src/main/java/world/bentobox/level/panels/DetailsPanel.java b/src/main/java/world/bentobox/level/panels/DetailsPanel.java index 6e345b7..2445cc9 100644 --- a/src/main/java/world/bentobox/level/panels/DetailsPanel.java +++ b/src/main/java/world/bentobox/level/panels/DetailsPanel.java @@ -768,11 +768,11 @@ private BlockDataRec getBlockData(Object key) { private Optional getCustomBlockItemStack(String id) { if (id.startsWith("oraxen:") && BentoBox.getInstance().getHooks().getHook("Oraxen").isPresent()) { return OraxenHook.getOptionalItemById(id.substring(7)) - .map(ib -> ib.build()); + .map(itemBuilder -> itemBuilder.build()); } if (id.startsWith("nexo:") && addon.isNexo()) { - com.nexomc.nexo.items.ItemBuilder nexoItem = NexoItems.itemFromId(id.substring(5)); - return nexoItem != null ? Optional.of(nexoItem.build()) : Optional.empty(); + com.nexomc.nexo.items.ItemBuilder nexoBuilder = NexoItems.itemFromId(id.substring(5)); + return nexoBuilder != null ? Optional.of(nexoBuilder.build()) : Optional.empty(); } if (addon.isItemsAdder() && ItemsAdderHook.isInRegistry(id)) { return ItemsAdderHook.getItemStack(id);