From 1db6385082aa1500f3f6afa4492b4c087cc2ff2e Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Fri, 24 Jan 2025 12:13:44 +0100 Subject: [PATCH 1/6] Make sure rename work when null --- .../cuanvil/listener/PrepareAnvilListener.kt | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt index 68370d4..87afba6 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt @@ -116,26 +116,27 @@ class PrepareAnvilListener : Listener { } private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory, player: HumanEntity): Int { - // Rename item and add renaming cost - resultItem.itemMeta?.let { - val displayName = ChatColor.stripColor(it.displayName) - var inventoryName = ChatColor.stripColor(inventory.renameText) + // Can be null + var inventoryName = ChatColor.stripColor(inventory.renameText) - var sumCost = 0 + var sumCost = 0 + var useColor = false + if(ConfigOptions.renameColorPossible && inventoryName != null){ + val resultString = StringBuilder(inventoryName) - var useColor = false - if(ConfigOptions.renameColorPossible){ - val resultString = StringBuilder(inventoryName) + useColor = AnvilColorUtil.handleRenamingColor(resultString, player) - useColor = AnvilColorUtil.handleRenamingColor(resultString, player) + if(useColor) { + inventoryName = resultString.toString() - if(useColor) { - inventoryName = resultString.toString() - - sumCost+= ConfigOptions.useOfColorCost - } + sumCost+= ConfigOptions.useOfColorCost } + } + // Rename item and add renaming cost + resultItem.itemMeta?.let { + + val displayName = ChatColor.stripColor(it.displayName) if ((!useColor && (!displayName.contentEquals(inventoryName))) || (useColor && !(it.displayName).contentEquals(inventoryName))) { it.setDisplayName(inventoryName) resultItem.itemMeta = it From 0d034c890e9429115534700adef2a9b66455caa5 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Fri, 24 Jan 2025 12:33:50 +0100 Subject: [PATCH 2/6] Add dependency error safety. --- .../cuanvil/listener/AnvilResultListener.kt | 18 +++++++++++++++++- .../cuanvil/listener/PrepareAnvilListener.kt | 16 +++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index 6622767..a9d3cd5 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -4,6 +4,7 @@ import io.delilaheve.CustomAnvil import io.delilaheve.util.ConfigOptions import io.delilaheve.util.ItemUtil.canMergeWith import io.delilaheve.util.ItemUtil.unitRepair +import org.bukkit.ChatColor import org.bukkit.GameMode import org.bukkit.Material import org.bukkit.entity.Player @@ -23,6 +24,7 @@ import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe import xyz.alexcrea.cuanvil.util.AnvilXpUtil import xyz.alexcrea.cuanvil.util.CustomRecipeUtil import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair +import java.util.logging.Level import kotlin.math.min class AnvilResultListener: Listener { @@ -45,8 +47,22 @@ class AnvilResultListener: Listener { if (event.rawSlot != ANVIL_OUTPUT_SLOT) { return } + // Test if the event should bypass custom anvil. - if(DependencyManager.tryClickAnvilResultBypass(event, inventory)) return + var shouldBypass: Boolean + try { + shouldBypass = DependencyManager.tryClickAnvilResultBypass(event, inventory) + } catch (e: Exception){ + shouldBypass = true + CustomAnvil.instance.logger.log(Level.SEVERE, "Error while trying to handle custom anvil supported plugin: ", e) + + // Just in case to avoid illegal items + event.inventory.setItem(ANVIL_OUTPUT_SLOT, null) + + // Finally, warn the player, maybe a lot of time but better warn than do nothing + player.sendMessage(ChatColor.RED.toString() + "Error while handling the anvil.") + } + if(shouldBypass) return val output = inventory.getItem(ANVIL_OUTPUT_SLOT) ?: return val leftItem = inventory.getItem(ANVIL_INPUT_LEFT) ?: return diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt index 87afba6..ab50036 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt @@ -22,6 +22,7 @@ import xyz.alexcrea.cuanvil.util.AnvilColorUtil import xyz.alexcrea.cuanvil.util.AnvilXpUtil import xyz.alexcrea.cuanvil.util.CustomRecipeUtil import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair +import java.util.logging.Level /** * Listener for anvil events @@ -45,7 +46,20 @@ class PrepareAnvilListener : Listener { val player: HumanEntity = event.viewers.first() // Test if the event should bypass custom anvil. - if(DependencyManager.tryEventPreAnvilBypass(event, player)) return + var shouldBypass: Boolean + try { + shouldBypass = DependencyManager.tryEventPreAnvilBypass(event, player) + } catch (e: Exception){ + shouldBypass = true + CustomAnvil.instance.logger.log(Level.SEVERE, "Error while trying to handle custom anvil supported plugin: ", e) + + // Just in case to avoid illegal items + event.inventory.setItem(ANVIL_OUTPUT_SLOT, null) + + // Finally, warn the player, maybe a lot of time but better warn than do nothing + player.sendMessage(ChatColor.RED.toString() + "Error while handling the anvil.") + } + if(shouldBypass) return val inventory = event.inventory val first = inventory.getItem(ANVIL_INPUT_LEFT) ?: return From 4e46206541df034020258ed8eac1c569d578ae1e Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Fri, 24 Jan 2025 12:34:19 +0100 Subject: [PATCH 3/6] version up --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index e10c058..45ea74c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,7 +16,7 @@ plugins { } group = "xyz.alexcrea" -version = "1.7.0" +version = "1.7.1" repositories { // EcoEnchants From 0df33911ce960500136477354f70d3d8972eb8d7 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sat, 25 Jan 2025 01:31:01 +0100 Subject: [PATCH 4/6] made rename logic more readable --- .../xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt index ab50036..5f17031 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt @@ -149,9 +149,11 @@ class PrepareAnvilListener : Listener { // Rename item and add renaming cost resultItem.itemMeta?.let { + val displayName = + if (useColor) it.displayName + else ChatColor.stripColor(it.displayName) - val displayName = ChatColor.stripColor(it.displayName) - if ((!useColor && (!displayName.contentEquals(inventoryName))) || (useColor && !(it.displayName).contentEquals(inventoryName))) { + if (!displayName.contentEquals(inventoryName)) { it.setDisplayName(inventoryName) resultItem.itemMeta = it From 48cc28442d02a6ea21d1c36eaa8410e2fa374d08 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sat, 25 Jan 2025 01:51:16 +0100 Subject: [PATCH 5/6] Moved error handling responsibility also handle safely tryTreatAnvilResult --- .../cuanvil/dependency/DependencyManager.kt | 55 ++++++++++++++++++- .../cuanvil/listener/AnvilResultListener.kt | 24 ++------ .../cuanvil/listener/PrepareAnvilListener.kt | 25 +++------ 3 files changed, 64 insertions(+), 40 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt index e97744e..437f3d5 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt @@ -2,6 +2,7 @@ package xyz.alexcrea.cuanvil.dependency import io.delilaheve.CustomAnvil import org.bukkit.Bukkit +import org.bukkit.ChatColor import org.bukkit.entity.HumanEntity import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.PrepareAnvilEvent @@ -15,6 +16,8 @@ import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerSelector import xyz.alexcrea.cuanvil.dependency.scheduler.BukkitScheduler import xyz.alexcrea.cuanvil.dependency.scheduler.FoliaScheduler import xyz.alexcrea.cuanvil.dependency.scheduler.TaskScheduler +import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT +import java.util.logging.Level object DependencyManager { @@ -96,10 +99,25 @@ object DependencyManager { // Then handle plugin reload ecoEnchantCompatibility?.handleConfigReload() - } + // Return true if should bypass (either by a dependency or error) fun tryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean { + try { + return unsafeTryEventPreAnvilBypass(event, player) + } catch (e: Exception){ + CustomAnvil.instance.logger.log(Level.SEVERE, "Error while trying to handle custom anvil supported plugin: ", e) + + // Just in case to avoid illegal items + event.inventory.setItem(ANVIL_OUTPUT_SLOT, null) + + // Finally, warn the player, maybe a lot of time but better warn than do nothing + event.view.player.sendMessage(ChatColor.RED.toString() + "Error while handling the anvil.") + return true + } + } + + private fun unsafeTryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean { var bypass = false // Test if disenchantment used prepare anvil @@ -118,11 +136,44 @@ object DependencyManager { return bypass } - fun treatAnvilResult(event: PrepareAnvilEvent, result: ItemStack) { + // Return true only if error occurred (and so should bypass rest) + fun tryTreatAnvilResult(event: PrepareAnvilEvent, result: ItemStack): Boolean { + try { + unsafeTryTreatAnvilResult(event, result) + return false + } catch (e: Exception){ + CustomAnvil.instance.logger.log(Level.SEVERE, "Error while trying to handle custom anvil supported plugin: ", e) + + // Just in case to avoid illegal items + event.inventory.setItem(ANVIL_OUTPUT_SLOT, null) + + // Finally, warn the player, maybe a lot of time but better warn than do nothing + event.view.player.sendMessage(ChatColor.RED.toString() + "Error while handling the anvil.") + return true + } + } + + private fun unsafeTryTreatAnvilResult(event: PrepareAnvilEvent, result: ItemStack) { excellentEnchantsCompatibility?.treatAnvilResult(event, result) } + // Return true if should bypass (either by a dependency or error) fun tryClickAnvilResultBypass(event: InventoryClickEvent, inventory: AnvilInventory): Boolean { + try { + return unsafeTryClickAnvilResultBypass(event, inventory) + } catch (e: Exception){ + CustomAnvil.instance.logger.log(Level.SEVERE, "Error while trying to handle custom anvil supported plugin: ", e) + + // Just in case to avoid illegal items + event.inventory.setItem(ANVIL_OUTPUT_SLOT, null) + + // Finally, warn the player, maybe a lot of time but better warn than do nothing + event.whoClicked.sendMessage(ChatColor.RED.toString() + "Error while handling the anvil.") + return true + } + } + + private fun unsafeTryClickAnvilResultBypass(event: InventoryClickEvent, inventory: AnvilInventory): Boolean { var bypass = false // Test if disenchantment used event click diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index a9d3cd5..1153248 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -4,7 +4,6 @@ import io.delilaheve.CustomAnvil import io.delilaheve.util.ConfigOptions import io.delilaheve.util.ItemUtil.canMergeWith import io.delilaheve.util.ItemUtil.unitRepair -import org.bukkit.ChatColor import org.bukkit.GameMode import org.bukkit.Material import org.bukkit.entity.Player @@ -24,7 +23,6 @@ import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe import xyz.alexcrea.cuanvil.util.AnvilXpUtil import xyz.alexcrea.cuanvil.util.CustomRecipeUtil import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair -import java.util.logging.Level import kotlin.math.min class AnvilResultListener: Listener { @@ -49,26 +47,13 @@ class AnvilResultListener: Listener { } // Test if the event should bypass custom anvil. - var shouldBypass: Boolean - try { - shouldBypass = DependencyManager.tryClickAnvilResultBypass(event, inventory) - } catch (e: Exception){ - shouldBypass = true - CustomAnvil.instance.logger.log(Level.SEVERE, "Error while trying to handle custom anvil supported plugin: ", e) - - // Just in case to avoid illegal items - event.inventory.setItem(ANVIL_OUTPUT_SLOT, null) - - // Finally, warn the player, maybe a lot of time but better warn than do nothing - player.sendMessage(ChatColor.RED.toString() + "Error while handling the anvil.") - } - if(shouldBypass) return + if(DependencyManager.tryClickAnvilResultBypass(event, inventory)) return val output = inventory.getItem(ANVIL_OUTPUT_SLOT) ?: return val leftItem = inventory.getItem(ANVIL_INPUT_LEFT) ?: return val rightItem = inventory.getItem(ANVIL_INPUT_RIGHT) - if(!GameMode.CREATIVE.equals(player.gameMode) && inventory.repairCost >= inventory.maximumRepairCost) { + if(GameMode.CREATIVE != player.gameMode && inventory.repairCost >= inventory.maximumRepairCost) { event.result = Event.Result.DENY return } @@ -112,7 +97,6 @@ class AnvilResultListener: Listener { } } - private fun onCustomCraft(event: InventoryClickEvent, recipe: AnvilCustomRecipe, player: Player, @@ -138,7 +122,7 @@ class AnvilResultListener: Listener { // Handle not creative middle click... if (event.click != ClickType.MIDDLE && - !handleCustomCraftClick(event, recipe, inventory, player, leftItem, rightItem, amount, xpCost)) return; + !handleCustomCraftClick(event, recipe, inventory, player, leftItem, rightItem, amount, xpCost)) return // Finally, we add the item to the player if (slotDestination.type == SlotType.CURSOR) { @@ -238,7 +222,7 @@ class AnvilResultListener: Listener { resultCopy: ItemStack, resultAmount: Int): Int { if (player.gameMode == GameMode.CREATIVE) return 0 - var repairCost = 0; + var repairCost = 0 // Get repairCost leftItem.itemMeta?.let { leftMeta -> val leftName = leftMeta.displayName diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt index 5f17031..f37a193 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt @@ -46,20 +46,7 @@ class PrepareAnvilListener : Listener { val player: HumanEntity = event.viewers.first() // Test if the event should bypass custom anvil. - var shouldBypass: Boolean - try { - shouldBypass = DependencyManager.tryEventPreAnvilBypass(event, player) - } catch (e: Exception){ - shouldBypass = true - CustomAnvil.instance.logger.log(Level.SEVERE, "Error while trying to handle custom anvil supported plugin: ", e) - - // Just in case to avoid illegal items - event.inventory.setItem(ANVIL_OUTPUT_SLOT, null) - - // Finally, warn the player, maybe a lot of time but better warn than do nothing - player.sendMessage(ChatColor.RED.toString() + "Error while handling the anvil.") - } - if(shouldBypass) return + if (DependencyManager.tryEventPreAnvilBypass(event, player)) return val inventory = event.inventory val first = inventory.getItem(ANVIL_INPUT_LEFT) ?: return @@ -90,6 +77,7 @@ class PrepareAnvilListener : Listener { } + // return true if a custom recipe exist with these ingredient private fun testCustomRecipe(event: PrepareAnvilEvent, inventory: AnvilInventory, player: HumanEntity, first: ItemStack, second: ItemStack?): Boolean { @@ -103,7 +91,7 @@ class PrepareAnvilListener : Listener { resultItem.amount *= amount event.result = resultItem - DependencyManager.treatAnvilResult(event, resultItem) + if(DependencyManager.tryTreatAnvilResult(event, resultItem)) return true AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, recipe.xpCostPerCraft * amount, true) return true @@ -122,7 +110,7 @@ class PrepareAnvilListener : Listener { } event.result = resultItem - DependencyManager.treatAnvilResult(event, resultItem) + if(DependencyManager.tryTreatAnvilResult(event, resultItem)) return anvilCost += AnvilXpUtil.calculatePenalty(first, null, resultItem) @@ -195,11 +183,12 @@ class PrepareAnvilListener : Listener { // Finally, we set result event.result = resultItem - DependencyManager.treatAnvilResult(event, resultItem) + if(DependencyManager.tryTreatAnvilResult(event, resultItem)) return AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost) } + // return true if there is a valid unit repair with these ingredients private fun testUnitRepair(event: PrepareAnvilEvent, inventory: AnvilInventory, player: HumanEntity, first: ItemStack, second: ItemStack): Boolean { val unitRepairAmount = first.getRepair(second) ?: return false @@ -221,7 +210,7 @@ class PrepareAnvilListener : Listener { return true } event.result = resultItem - DependencyManager.treatAnvilResult(event, resultItem) + if(DependencyManager.tryTreatAnvilResult(event, resultItem)) return true AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost) return true From af84ba56f035dd49c4c62a30dd0696295de09f43 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sat, 25 Jan 2025 02:03:09 +0100 Subject: [PATCH 6/6] Add rename to null test --- .../io/delilaheve/util/ConfigOptions.kt | 4 +-- .../cuanvil/anvil/AnvilFuseTests.java | 28 +++++++++++++++++-- .../cuanvil/util/AnvilFuseTestData.java | 15 ++++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt index f192ff9..dc47bc6 100644 --- a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt +++ b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt @@ -48,8 +48,8 @@ object ConfigOptions { private const val KEY_ITEM = "item" // Debug flag - private const val DEBUG_LOGGING = "debug_log" - private const val VERBOSE_DEBUG_LOGGING = "debug_log_verbose" + const val DEBUG_LOGGING = "debug_log" + const val VERBOSE_DEBUG_LOGGING = "debug_log_verbose" // ---------------------- // Default config values diff --git a/src/test/java/xyz/alexcrea/cuanvil/anvil/AnvilFuseTests.java b/src/test/java/xyz/alexcrea/cuanvil/anvil/AnvilFuseTests.java index fde2a68..16a01e3 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/anvil/AnvilFuseTests.java +++ b/src/test/java/xyz/alexcrea/cuanvil/anvil/AnvilFuseTests.java @@ -1,11 +1,15 @@ package xyz.alexcrea.cuanvil.anvil; +import io.delilaheve.util.ConfigOptions; +import net.kyori.adventure.text.Component; +import org.bukkit.Material; import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.AnvilInventory; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.Repairable; +import org.eclipse.aether.util.ConfigUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -32,8 +36,9 @@ public static void setUp() { AnvilFuseTests.anvil = (AnvilInventory) anvil; player.openInventory(anvil); - ConfigHolder.DEFAULT_CONFIG.getConfig().set("debug_log", true); - ConfigHolder.DEFAULT_CONFIG.getConfig().set("debug_log_verbose", true); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(ConfigOptions.DEBUG_LOGGING, true); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(ConfigOptions.VERBOSE_DEBUG_LOGGING, true); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(ConfigOptions.ALLOW_COLOR_CODE, true); // For rename test } @BeforeEach @@ -100,4 +105,23 @@ public void underFuseTest(){ AnvilFuseTestUtil.executeAnvilTest(anvil, player, data); } + // Note: currently anvil can only have null name. maybe handle differently later + @Test + public void nullNameResetTest(){ + ItemStack base = new ItemStack(Material.NETHERITE_SWORD); + ItemStack expected = base.clone(); + + ItemMeta meta = expected.getItemMeta(); + meta.displayName(Component.text("test")); + base.setItemMeta(meta); + + AnvilFuseTestData data = new AnvilFuseTestData( + base, null, + expected, expected, null + // TODO add expected price + ); + + AnvilFuseTestUtil.executeAnvilTest(anvil, player, data); + } + } diff --git a/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestData.java b/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestData.java index 2268d44..cc042f2 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestData.java +++ b/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestData.java @@ -36,4 +36,19 @@ public AnvilFuseTestData( this(leftItem, rightItem, expectedResult, null ); } + + public AnvilFuseTestData( + @Nullable ItemStack leftItem, + @Nullable ItemStack rightItem, + @Nullable ItemStack expectedResult, + + @Nullable ItemStack expectedAfterLeftPlaced, + @Nullable ItemStack expectedAfterRightPlaced + ){ + this(leftItem, rightItem, + expectedResult, expectedAfterLeftPlaced, expectedAfterRightPlaced, + null, null, null + ); + } + }