strings = new ArrayList<>();
- List> list = (List>) value;
for (Object object : list) {
strings.add(String.valueOf(object));
}
return strings;
+ } else {
+ return null;
}
}
diff --git a/src/main/java/net/knarcraft/blacksmith/util/InputParsingHelper.java b/src/main/java/net/knarcraft/blacksmith/util/InputParsingHelper.java
index d5d5259..b91b734 100644
--- a/src/main/java/net/knarcraft/blacksmith/util/InputParsingHelper.java
+++ b/src/main/java/net/knarcraft/blacksmith/util/InputParsingHelper.java
@@ -21,7 +21,7 @@ public final class InputParsingHelper {
*/
public static boolean isEmpty(String input) {
return input == null || input.equalsIgnoreCase("null") || input.equals("\"\"") ||
- input.trim().isEmpty() || input.equals("-1");
+ input.isBlank() || input.equals("-1");
}
/**
@@ -41,7 +41,13 @@ public final class InputParsingHelper {
* @return The enchantment matching the string, or null if not found
*/
public static Enchantment matchEnchantment(String input) {
- return Enchantment.getByKey(NamespacedKey.minecraft(input.replace("-", "_")));
+ try {
+ return Enchantment.getByKey(NamespacedKey.minecraft(
+ input.replace("-", "_").replace(" ", "_").toLowerCase()));
+ } catch (IllegalArgumentException exception) {
+ //Invalid characters, such as : will normally throw an illegal argument exception
+ return null;
+ }
}
/**
diff --git a/src/main/java/net/knarcraft/blacksmith/util/ItemHelper.java b/src/main/java/net/knarcraft/blacksmith/util/ItemHelper.java
index 6d604c4..854c206 100644
--- a/src/main/java/net/knarcraft/blacksmith/util/ItemHelper.java
+++ b/src/main/java/net/knarcraft/blacksmith/util/ItemHelper.java
@@ -20,11 +20,13 @@ public final class ItemHelper {
/**
* Gets whether the given item is repairable
*
- * @param item The item to check
+ * @param item The item to check
+ * @param disableMaterialLimitation Whether to disable the EnchantmentTarget.BREAKABLE limitation
* @return True if the item is repairable
*/
- public static boolean isRepairable(ItemStack item) {
- return item.getItemMeta() instanceof Damageable && EnchantmentTarget.BREAKABLE.includes(item);
+ public static boolean isRepairable(ItemStack item, boolean disableMaterialLimitation) {
+ return item.getItemMeta() instanceof Damageable && (disableMaterialLimitation ||
+ EnchantmentTarget.BREAKABLE.includes(item));
}
/**
diff --git a/src/main/java/net/knarcraft/blacksmith/util/SalvageHelper.java b/src/main/java/net/knarcraft/blacksmith/util/SalvageHelper.java
index 52bb6f2..6751e82 100644
--- a/src/main/java/net/knarcraft/blacksmith/util/SalvageHelper.java
+++ b/src/main/java/net/knarcraft/blacksmith/util/SalvageHelper.java
@@ -23,14 +23,16 @@ public final class SalvageHelper {
*
* Note: Only items craft-able in a crafting table are salvageable. Netherite gear is therefore not salvageable.
*
- * @param server The server to get recipes from
- * @param salvagedItem The item stack to salvage
- * @param ignoredSalvage Any material which should not be returned as part of the salvage.
+ * @param server The server to get recipes from
+ * @param salvagedItem The item stack to salvage
+ * @param ignoredSalvage Any material which should not be returned as part of the salvage.
+ * @param limitationDisabled Whether the repairable item limitation is disabled
* @return The items to return to the user, or null if not salvageable
*/
- public static List getSalvage(Server server, ItemStack salvagedItem, List ignoredSalvage) {
+ public static List getSalvage(Server server, ItemStack salvagedItem, List ignoredSalvage,
+ boolean limitationDisabled) {
if (salvagedItem == null || salvagedItem.getAmount() < 1 ||
- !ItemHelper.isRepairable(salvagedItem)) {
+ !ItemHelper.isRepairable(salvagedItem, limitationDisabled)) {
return null;
}
@@ -71,10 +73,12 @@ public final class SalvageHelper {
ingredients.removeIf((item) -> ignoredSalvage.contains(item.getType()));
}
+ Random random = new Random();
+
//Make sure to give salvage for all items if a stack > 1 is provided
List allSalvage = new ArrayList<>();
for (int i = 0; i < salvagedItem.getAmount(); i++) {
- allSalvage.addAll(getSalvage(copyItems(ingredients), salvagedItem));
+ allSalvage.addAll(getSalvage(copyItems(ingredients), salvagedItem, random));
}
return combineStacks(allSalvage);
@@ -101,15 +105,15 @@ public final class SalvageHelper {
*
* @param recipeItems All items required for crafting the item to salvage
* @param salvagedItem The item to be salvaged
+ * @param random The randomness generator to use
* @return The items to be returned to the user as salvage
*/
- private static List getSalvage(List recipeItems, ItemStack salvagedItem) {
+ private static List getSalvage(List recipeItems, ItemStack salvagedItem, Random random) {
double percentageRemaining = (ItemHelper.getDurability(salvagedItem) /
(double) ItemHelper.getMaxDurability(salvagedItem));
int totalItems = totalItems(recipeItems);
//Get the amount of recipe items to be returned
int itemsToReturn = (int) Math.floor(percentageRemaining * totalItems);
- Random random = new Random();
int bound = recipeItems.size();
List salvage = new ArrayList<>();
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index 0afe128..b8f24c5 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -33,6 +33,10 @@ global:
# The cost of fully repairing a damaged anvil
damagedAnvilReforgingCost: 20.0
+
+ # This disables the EnchantmentTarget.BREAKABLE limitation. If set to true, all items able to have durability are seen
+ # as reforgeAble. This should not be set to true unless you have special needs.
+ disableMaterialLimitation: false
# The settings which are set to any new NPC. To change any of these settings for an existing NPC, you must change the
# Citizens NPC file, or use the /blacksmith command
@@ -107,4 +111,13 @@ defaults:
successMessage: "There you go! All better!"
# The message to display if a player is trying to reforge an item with full durability
- notDamagedMessage: "&cThat item is not in need of repair"
\ No newline at end of file
+ notDamagedMessage: "&cThat item is not in need of repair"
+
+ # The message to display if the player tries to salvage an item the blacksmith cannot salvage
+ cannotSalvageMessage: "&cI'm unable to salvage that item"
+
+ # The message to display if reforging the player's item would result in no salvage
+ tooDamagedForSalvageMessage: "&cThat item is too damaged to be salvaged into anything useful"
+
+ # The message to display when an item is successfully salvaged
+ successSalvagedMessage: "&cThere you go!"
\ No newline at end of file
diff --git a/src/test/java/net/knarcraft/blacksmith/util/ConfigHelperTest.java b/src/test/java/net/knarcraft/blacksmith/util/ConfigHelperTest.java
new file mode 100644
index 0000000..48d1a58
--- /dev/null
+++ b/src/test/java/net/knarcraft/blacksmith/util/ConfigHelperTest.java
@@ -0,0 +1,130 @@
+package net.knarcraft.blacksmith.util;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * A test class to test the config helper
+ */
+public class ConfigHelperTest {
+
+ private static List expectedStringList;
+
+ @BeforeAll
+ public static void setUp() {
+ expectedStringList = new ArrayList<>();
+ for (int i = 1; i < 8; i++) {
+ expectedStringList.add(String.valueOf(i));
+ }
+ }
+
+ @Test
+ public void asStringListStringTest() {
+ assertEquals(expectedStringList, ConfigHelper.asStringList("1,2,3,4,5,6,7"));
+ }
+
+ @Test
+ public void asStringListStringListTest() {
+ List testValues = new ArrayList<>();
+ for (int i = 1; i < 8; i++) {
+ testValues.add(String.valueOf(i));
+ }
+ assertEquals(expectedStringList, ConfigHelper.asStringList(testValues));
+ }
+
+ @Test
+ public void asStringListIntListTest() {
+ List testValues = new ArrayList<>();
+ for (int i = 1; i < 8; i++) {
+ testValues.add(i);
+ }
+ assertEquals(expectedStringList, ConfigHelper.asStringList(testValues));
+ }
+
+ @Test
+ public void asDoubleDoubleTest() {
+ assertEquals(5.244352345, ConfigHelper.asDouble(5.244352345));
+ }
+
+ @Test
+ public void asDoubleIntTest() {
+ assertEquals(554636d, ConfigHelper.asDouble(554636));
+ }
+
+ @Test
+ public void asDoubleDoubleStringTest() {
+ assertEquals(54.54642388, ConfigHelper.asDouble("54.54642388"));
+ }
+
+ @Test
+ public void asDoubleIntStringTest() {
+ assertEquals(967876554, ConfigHelper.asDouble("967876554"));
+ }
+
+ @Test
+ public void asDoubleInvalidDoubleStringTest() {
+ assertThrows(NumberFormatException.class, () -> ConfigHelper.asDouble("Potato"));
+ }
+
+ @Test
+ public void asDoubleInvalidObjectTest() {
+ assertThrows(ClassCastException.class, () -> ConfigHelper.asDouble(new ArrayList<>()));
+ }
+
+ @Test
+ public void asBooleanTrueTest() {
+ assertTrue(ConfigHelper.asBoolean(true));
+ }
+
+ @Test
+ public void asBooleanFalseTest() {
+ assertFalse(ConfigHelper.asBoolean(false));
+ }
+
+ @Test
+ public void asBooleanTrueStringTest() {
+ assertTrue(ConfigHelper.asBoolean("trUe"));
+ }
+
+ @Test
+ public void asBooleanFalseStringTest() {
+ assertFalse(ConfigHelper.asBoolean("faLse"));
+ }
+
+ @Test
+ public void asBooleanInvalidStringTest() {
+ assertFalse(ConfigHelper.asBoolean("potato"));
+ }
+
+ @Test
+ public void asBooleanInvalidObjectTest() {
+ assertThrows(ClassCastException.class, () -> {
+ boolean result = ConfigHelper.asBoolean(new ArrayList<>());
+ assertFalse(result);
+ });
+ }
+
+ @Test
+ public void asIntIntTest() {
+ assertEquals(5466547, ConfigHelper.asInt(5466547));
+ }
+
+ @Test
+ public void asIntStringIntTest() {
+ assertEquals(976586547, ConfigHelper.asInt("976586547"));
+ }
+
+ @Test
+ public void asIntInvalidTest() {
+ assertThrows(ClassCastException.class, () -> ConfigHelper.asInt(54675467d));
+ }
+
+}
diff --git a/src/test/java/net/knarcraft/blacksmith/util/InputParsingHelperTest.java b/src/test/java/net/knarcraft/blacksmith/util/InputParsingHelperTest.java
new file mode 100644
index 0000000..0dd1c12
--- /dev/null
+++ b/src/test/java/net/knarcraft/blacksmith/util/InputParsingHelperTest.java
@@ -0,0 +1,104 @@
+package net.knarcraft.blacksmith.util;
+
+import be.seeseemelk.mockbukkit.enchantments.EnchantmentMock;
+import org.bukkit.Material;
+import org.bukkit.NamespacedKey;
+import org.bukkit.enchantments.Enchantment;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * A test class for testing input parsing
+ */
+public class InputParsingHelperTest {
+
+ private static Enchantment curseOfBinding;
+
+ @BeforeAll
+ public static void setUp() {
+ //Note: When not testing against a real server, no default enchantments are loaded!
+ curseOfBinding = new EnchantmentMock(NamespacedKey.minecraft("binding_curse"),
+ "CURSE_OF_BINDING");
+ Enchantment.registerEnchantment(curseOfBinding);
+ }
+
+ @Test
+ public void isEmptyTrueTest() {
+ assertTrue(InputParsingHelper.isEmpty(null));
+ assertTrue(InputParsingHelper.isEmpty("-1"));
+ assertTrue(InputParsingHelper.isEmpty("\"\""));
+ assertTrue(InputParsingHelper.isEmpty("null"));
+ assertTrue(InputParsingHelper.isEmpty(" "));
+ }
+
+ @Test
+ public void isEmptyFalseTest() {
+ assertFalse(InputParsingHelper.isEmpty("potato"));
+ assertFalse(InputParsingHelper.isEmpty("67465775"));
+ assertFalse(InputParsingHelper.isEmpty("657.4655467"));
+ assertFalse(InputParsingHelper.isEmpty(" a "));
+ assertFalse(InputParsingHelper.isEmpty("\"fish\""));
+ assertFalse(InputParsingHelper.isEmpty("-657858"));
+ assertFalse(InputParsingHelper.isEmpty("-6578.58"));
+ }
+
+ @Test
+ public void matchMaterialValidTest() {
+ assertEquals(Material.DIAMOND_PICKAXE, InputParsingHelper.matchMaterial("DIAMOND_PICKAXE"));
+ assertEquals(Material.DIAMOND_AXE, InputParsingHelper.matchMaterial("DIAMOND_axe"));
+ assertEquals(Material.IRON_SWORD, InputParsingHelper.matchMaterial("iron-SWORD"));
+ assertEquals(Material.WOODEN_HOE, InputParsingHelper.matchMaterial("wOoDeN-HoE"));
+ assertEquals(Material.ACACIA_CHEST_BOAT, InputParsingHelper.matchMaterial("ACACIA-chest_bOaT"));
+ assertEquals(Material.NETHERITE_PICKAXE, InputParsingHelper.matchMaterial("netherite pickaxe"));
+ assertEquals(Material.STONE_SHOVEL, InputParsingHelper.matchMaterial("minecraft:stone_shovel"));
+ assertEquals(Material.GOLDEN_BOOTS, InputParsingHelper.matchMaterial("minecraft:golden BOOTS"));
+ }
+
+ @Test
+ public void matchMaterialInvalidTest() {
+ assertNull(InputParsingHelper.matchMaterial("this_item_does_not_exist"));
+ assertNull(InputParsingHelper.matchMaterial("stone:pickaxe"));
+ assertNull(InputParsingHelper.matchMaterial("aron sword"));
+ assertNull(InputParsingHelper.matchMaterial("minecraft : golden BOOTS"));
+ assertNull(InputParsingHelper.matchMaterial("minecraft: golden BOOTS"));
+ assertNull(InputParsingHelper.matchMaterial("MINECRAFT:golden-BOOTS"));
+ assertNull(InputParsingHelper.matchMaterial("minecraft: golden-BOOTS"));
+ }
+
+ @Test
+ public void matchEnchantmentValidTest() {
+ for (Enchantment enchantment : Enchantment.values()) {
+ assertEquals(enchantment, InputParsingHelper.matchEnchantment(enchantment.getKey().getKey()));
+ }
+ assertEquals(curseOfBinding, InputParsingHelper.matchEnchantment("binding_curse"));
+ assertEquals(curseOfBinding, InputParsingHelper.matchEnchantment("binding-curse"));
+ assertEquals(curseOfBinding, InputParsingHelper.matchEnchantment("binding curse"));
+ assertEquals(curseOfBinding, InputParsingHelper.matchEnchantment("BINDING curse"));
+ }
+
+ @Test
+ public void matchEnchantmentInvalidTest() {
+ for (Enchantment enchantment : Enchantment.values()) {
+ assertEquals(enchantment, InputParsingHelper.matchEnchantment(enchantment.getKey().getKey()));
+ }
+ assertNotEquals(curseOfBinding, InputParsingHelper.matchEnchantment("bonding_curse"));
+ assertNotEquals(curseOfBinding, InputParsingHelper.matchEnchantment("binding curse"));
+ assertNotEquals(curseOfBinding, InputParsingHelper.matchEnchantment(" BINDING curse"));
+ assertNotEquals(curseOfBinding, InputParsingHelper.matchEnchantment("binding:curse"));
+ }
+
+ @Test
+ public void regExIfyTest() {
+ assertEquals("NO REGEX HERE", InputParsingHelper.regExIfy("no regEx here"));
+ assertEquals("NO_REGEX_HERE", InputParsingHelper.regExIfy("no-regEx-here"));
+ assertEquals("NETHERITE.*", InputParsingHelper.regExIfy("netherite*"));
+ assertEquals("GOLDEN_.*", InputParsingHelper.regExIfy("golden-*"));
+ }
+
+}
diff --git a/src/test/java/net/knarcraft/blacksmith/util/ItemHelperTest.java b/src/test/java/net/knarcraft/blacksmith/util/ItemHelperTest.java
new file mode 100644
index 0000000..102032d
--- /dev/null
+++ b/src/test/java/net/knarcraft/blacksmith/util/ItemHelperTest.java
@@ -0,0 +1,62 @@
+package net.knarcraft.blacksmith.util;
+
+import be.seeseemelk.mockbukkit.MockBukkit;
+import net.knarcraft.blacksmith.CustomServerMock;
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.Damageable;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Tests for the ItemHelper class
+ */
+public class ItemHelperTest {
+
+ @BeforeAll
+ public static void setUp() {
+ MockBukkit.mock(new CustomServerMock());
+ }
+
+ @AfterAll
+ public static void tearDown() {
+ MockBukkit.unmock();
+ }
+
+ @Test
+ public void isRepairableTest() {
+ for (Material material : Material.values()) {
+ String name = material.name();
+ if (name.endsWith("_SWORD") || name.endsWith("_PICKAXE") || name.endsWith("_AXE") ||
+ name.endsWith("_HOE") || name.endsWith("_SHOVEL") || name.endsWith("_CHESTPLATE") ||
+ name.endsWith("_HELMET") || name.equals("ELYTRA") || name.endsWith("BOW") ||
+ name.endsWith("_LEGGINGS") || name.endsWith("_BOOTS") || name.equals("TRIDENT") ||
+ name.equals("FISHING_ROD") || name.equals("FLINT_AND_STEEL") || name.equals("SHEARS")) {
+ assertTrue(ItemHelper.isRepairable(new ItemStack(material, 1), false));
+ }
+ }
+ assertFalse(ItemHelper.isRepairable(new ItemStack(Material.POTATO, 1), false));
+ assertFalse(ItemHelper.isRepairable(new ItemStack(Material.DIRT, 1), false));
+ }
+
+ @Test
+ public void isRepairableLimitDisabledTest() {
+ /*The assertFalse pert of this test is kind of pointless, as every material in the game seems to implement
+ Damageable */
+ for (Material material : Material.values()) {
+ ItemStack itemStack = new ItemStack(material, 1);
+ if (new ItemStack(material, 1).getItemMeta() instanceof Damageable) {
+ assertTrue(ItemHelper.isRepairable(itemStack, true));
+ } else {
+ assertFalse(ItemHelper.isRepairable(itemStack, true));
+ }
+ }
+ assertTrue(ItemHelper.isRepairable(new ItemStack(Material.POTATO, 1), true));
+ assertTrue(ItemHelper.isRepairable(new ItemStack(Material.DIRT, 1), true));
+ }
+
+}
diff --git a/src/test/java/net/knarcraft/blacksmith/util/SalvageHelperTest.java b/src/test/java/net/knarcraft/blacksmith/util/SalvageHelperTest.java
index 2e59bd0..6092168 100644
--- a/src/test/java/net/knarcraft/blacksmith/util/SalvageHelperTest.java
+++ b/src/test/java/net/knarcraft/blacksmith/util/SalvageHelperTest.java
@@ -7,6 +7,7 @@ import org.bukkit.Server;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
+import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@@ -31,17 +32,22 @@ public class SalvageHelperTest {
server = MockBukkit.mock(new CustomServerMock());
}
+ @AfterAll
+ public static void tearDown() {
+ MockBukkit.unmock();
+ }
+
@Test
public void getNullForInvalidItemTest() {
//Assert that a non-reforge-able item will return null
- assertNull(SalvageHelper.getSalvage(server, new ItemStack(Material.POTATO, 1), null));
+ assertNull(SalvageHelper.getSalvage(server, new ItemStack(Material.POTATO, 1), null, false));
}
@Test
public void getNullForLessThanOneItemTest() {
//Assert that 0 or 1 items will return null
- assertNull(SalvageHelper.getSalvage(server, new ItemStack(Material.IRON_AXE, 0), null));
- assertNull(SalvageHelper.getSalvage(server, new ItemStack(Material.IRON_SWORD, -1), null));
+ assertNull(SalvageHelper.getSalvage(server, new ItemStack(Material.IRON_AXE, 0), null, false));
+ assertNull(SalvageHelper.getSalvage(server, new ItemStack(Material.IRON_SWORD, -1), null, false));
}
@Test
@@ -51,7 +57,7 @@ public class SalvageHelperTest {
expectedSalvage.add(new ItemStack(Material.STICK, 2));
ItemStack itemToSalvage = new ItemStack(Material.DIAMOND_PICKAXE, 1);
//Note: Conversion to sets makes sure the order doesn't matter
- assertEquals(expectedSalvage, new HashSet<>(SalvageHelper.getSalvage(server, itemToSalvage, null)));
+ assertEquals(expectedSalvage, new HashSet<>(SalvageHelper.getSalvage(server, itemToSalvage, null, false)));
}
@Test
@@ -61,7 +67,7 @@ public class SalvageHelperTest {
expectedSalvage.add(new ItemStack(Material.STICK, 14));
ItemStack itemToSalvage = new ItemStack(Material.DIAMOND_PICKAXE, 7);
//Note: Conversion to sets makes sure the order doesn't matter
- assertEquals(expectedSalvage, new HashSet<>(SalvageHelper.getSalvage(server, itemToSalvage, null)));
+ assertEquals(expectedSalvage, new HashSet<>(SalvageHelper.getSalvage(server, itemToSalvage, null, false)));
}
@Test
@@ -76,7 +82,7 @@ public class SalvageHelperTest {
damageable.setDamage(100);
}
itemToSalvage.setItemMeta(meta);
- List salvage = SalvageHelper.getSalvage(server, itemToSalvage, null);
+ List salvage = SalvageHelper.getSalvage(server, itemToSalvage, null, false);
//Assert that some items are given
assertNotEquals(salvage, new ArrayList<>());
//Assert that a damaged item won't give full salvage
@@ -96,7 +102,7 @@ public class SalvageHelperTest {
damageable.setDamage(100);
}
itemToSalvage.setItemMeta(meta);
- List salvage = SalvageHelper.getSalvage(server, itemToSalvage, ignoredSalvage);
+ List salvage = SalvageHelper.getSalvage(server, itemToSalvage, ignoredSalvage, false);
//Assert that some items are given
assertNotEquals(salvage, new ArrayList<>());
//Assert that a damaged diamond pickaxe with sticks ignored returns 2 diamonds a salvage