legacyEnchantments = new HashMap<>();
static {
- enchants.put("SHARPNESS", Enchantment.DAMAGE_ALL);
- enchants.put("POWER", Enchantment.ARROW_DAMAGE);
- enchants.put("FIRE_PROTECTION", Enchantment.PROTECTION_FIRE);
- enchants.put("FEATHER_FALLING", Enchantment.PROTECTION_FALL);
- enchants.put("PROTECTION", Enchantment.PROTECTION_ENVIRONMENTAL);
- enchants.put("BLAST_PROTECTION", Enchantment.PROTECTION_EXPLOSIONS);
- enchants.put("PROJECTILE_PROTECTION", Enchantment.PROTECTION_PROJECTILE);
- enchants.put("RESPIRATION", Enchantment.OXYGEN);
- enchants.put("INFINITY", Enchantment.ARROW_INFINITE);
- enchants.put("AQUA_AFFINITY", Enchantment.WATER_WORKER);
- enchants.put("UNBREAKING", Enchantment.DURABILITY);
- enchants.put("SMITE", Enchantment.DAMAGE_UNDEAD);
- enchants.put("BANE_OF_ARTHROPODS", Enchantment.DAMAGE_ARTHROPODS);
- enchants.put("EFFICIENCY", Enchantment.DIG_SPEED);
- enchants.put("FIRE_ASPECT", Enchantment.FIRE_ASPECT);
- enchants.put("SILK_TOUCH", Enchantment.SILK_TOUCH);
- enchants.put("FORTUNE", Enchantment.LOOT_BONUS_BLOCKS);
- enchants.put("LOOTING", Enchantment.LOOT_BONUS_MOBS);
- enchants.put("PUNCH", Enchantment.ARROW_KNOCKBACK);
- enchants.put("FLAME", Enchantment.ARROW_FIRE);
- enchants.put("KNOCKBACK", Enchantment.KNOCKBACK);
- enchants.put("THORNS", Enchantment.THORNS);
- enchants.put("MENDING", Enchantment.MENDING);
- enchants.put("DEPTH_STRIDER", Enchantment.DEPTH_STRIDER);
- enchants.put("FROST_WALKER", Enchantment.FROST_WALKER);
+ // backwards compatibility for looking up legacy bukkit enums
+ addLegacyEnchantmentLookup("SHARPNESS", "DAMAGE_ALL");
+ addLegacyEnchantmentLookup("POWER", "ARROW_DAMAGE");
+ addLegacyEnchantmentLookup("FIRE_PROTECTION", "PROTECTION_FIRE");
+ addLegacyEnchantmentLookup("FEATHER_FALLING", "PROTECTION_FALL");
+ addLegacyEnchantmentLookup("PROTECTION", "PROTECTION_ENVIRONMENTAL");
+ addLegacyEnchantmentLookup("BLAST_PROTECTION", "PROTECTION_EXPLOSIONS");
+ addLegacyEnchantmentLookup("PROJECTILE_PROTECTION", "PROTECTION_PROJECTILE");
+ addLegacyEnchantmentLookup("RESPIRATION", "OXYGEN");
+ addLegacyEnchantmentLookup("INFINITY", "ARROW_INFINITE");
+ addLegacyEnchantmentLookup("AQUA_AFFINITY", "WATER_WORKER");
+ addLegacyEnchantmentLookup("UNBREAKING", "DURABILITY");
+ addLegacyEnchantmentLookup("SMITE", "DAMAGE_UNDEAD");
+ addLegacyEnchantmentLookup("BANE_OF_ARTHROPODS", "DAMAGE_ARTHROPODS");
+ addLegacyEnchantmentLookup("EFFICIENCY", "DIG_SPEED");
+ addLegacyEnchantmentLookup("FORTUNE", "LOOT_BONUS_BLOCKS");
+ addLegacyEnchantmentLookup("LOOTING", "LOOT_BONUS_MOBS");
+ addLegacyEnchantmentLookup("PUNCH", "ARROW_KNOCKBACK");
+ addLegacyEnchantmentLookup("FLAME", "ARROW_FIRE");
}
/**
@@ -43,11 +38,19 @@ public class EnchantmentUtils {
*
* @return Enchantment or null if no enchantment was found
*/
- public static Enchantment getByName(String enchantmentName) {
- if (enchants.containsKey(enchantmentName)) {
- return enchants.get(enchantmentName);
+ @SuppressWarnings("deprecation")
+ public static @Nullable Enchantment getByName(String enchantmentName) {
+ if (legacyEnchantments.containsKey(enchantmentName)) {
+ return legacyEnchantments.get(enchantmentName);
}
return Enchantment.getByName(enchantmentName);
}
+
+ @SuppressWarnings("deprecation")
+ private static void addLegacyEnchantmentLookup(String enchantmentName, String legacyBukkitName) {
+ if (Enchantment.getByName(legacyBukkitName) != null) {
+ legacyEnchantments.put(enchantmentName, Enchantment.getByName(legacyBukkitName));
+ }
+ }
}
diff --git a/src/main/java/com/gmail/nossr50/util/ItemUtils.java b/src/main/java/com/gmail/nossr50/util/ItemUtils.java
index 6055582e3..2b7cccc48 100644
--- a/src/main/java/com/gmail/nossr50/util/ItemUtils.java
+++ b/src/main/java/com/gmail/nossr50/util/ItemUtils.java
@@ -23,6 +23,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
+import static java.util.Objects.requireNonNull;
+
public final class ItemUtils {
/**
* This is a static utility class, therefore we don't want any instances of
@@ -41,6 +43,37 @@ public final class ItemUtils {
return mcMMO.getMaterialMapStore().isBow(item.getType().getKey().getKey());
}
+ /**
+ * Exhaustive lookup for a Material by name.
+ *
+ * This method will first try a normal lookup, then a legacy lookup, then a lookup by ENUM name,
+ * and finally a lookup by ENUM name with legacy name.
+ * @param materialName The name of the material to lookup
+ * @return The Material if found, or null if not found
+ */
+ public static @Nullable Material exhaustiveMaterialLookup(@NotNull String materialName) {
+ requireNonNull(materialName, "materialName cannot be null");
+
+ // First try a normal lookup
+ Material material = Material.matchMaterial(materialName);
+
+ // If that fails, try a legacy lookup
+ if (material == null) {
+ material = Material.matchMaterial(materialName, true);
+ }
+
+ // try to match to Material ENUM
+ if (material == null) {
+ material = Material.getMaterial(materialName.toUpperCase());
+ }
+
+ // try to match to Material ENUM with legacy name
+ if (material == null) {
+ material = Material.getMaterial(materialName.toUpperCase(), true);
+ }
+ return material;
+ }
+
/**
* Checks if a player has an item in their inventory or offhand.
*
@@ -100,6 +133,10 @@ public final class ItemUtils {
return mcMMO.getMaterialMapStore().isTrident(item.getType().getKey().getKey());
}
+ public static boolean isMace(@NotNull ItemStack item) {
+ return mcMMO.getMaterialMapStore().isMace(item.getType().getKey().getKey());
+ }
+
public static boolean hasItemInEitherHand(@NotNull Player player, Material material) {
return player.getInventory().getItemInMainHand().getType() == material || player.getInventory().getItemInOffHand().getType() == material;
}
@@ -681,7 +718,8 @@ public final class ItemUtils {
if(itemMeta == null)
return;
- itemMeta.addEnchant(Enchantment.DIG_SPEED, existingEnchantLevel + mcMMO.p.getAdvancedConfig().getEnchantBuff(), true);
+ itemMeta.addEnchant(mcMMO.p.getEnchantmentMapper().getEfficiency(),
+ existingEnchantLevel + mcMMO.p.getAdvancedConfig().getEnchantBuff(), true);
itemStack.setItemMeta(itemMeta);
}
diff --git a/src/main/java/com/gmail/nossr50/util/MaterialMapStore.java b/src/main/java/com/gmail/nossr50/util/MaterialMapStore.java
index b0f623602..a0ad84326 100644
--- a/src/main/java/com/gmail/nossr50/util/MaterialMapStore.java
+++ b/src/main/java/com/gmail/nossr50/util/MaterialMapStore.java
@@ -50,6 +50,7 @@ public class MaterialMapStore {
private final @NotNull HashSet crossbows;
private final @NotNull HashSet tools;
private final @NotNull HashSet enchantables;
+ private final @NotNull HashSet maces;
private final @NotNull HashSet ores;
private final @NotNull HashSet intendedToolPickAxe;
@@ -97,6 +98,7 @@ public class MaterialMapStore {
shovels = new HashSet<>();
hoes = new HashSet<>();
tridents = new HashSet<>();
+ maces = new HashSet<>();
enchantables = new HashSet<>();
@@ -453,6 +455,7 @@ public class MaterialMapStore {
enchantables.addAll(tridents);
enchantables.addAll(bows);
enchantables.addAll(crossbows);
+ enchantables.addAll(maces);
enchantables.add("shears");
enchantables.add("fishing_rod");
@@ -476,6 +479,7 @@ public class MaterialMapStore {
fillHoes();
fillShovels();
fillTridents();
+ fillMaces();
fillStringTools();
fillBows();
fillCrossbows();
@@ -491,6 +495,7 @@ public class MaterialMapStore {
tools.addAll(stringTools);
tools.addAll(bows);
tools.addAll(crossbows);
+ tools.addAll(maces);
}
private void fillBows() {
@@ -507,6 +512,10 @@ public class MaterialMapStore {
stringTools.add("carrot_on_a_stick");
}
+ private void fillMaces() {
+ maces.add("mace");
+ }
+
private void fillTridents() {
tridents.add("trident");
}
@@ -824,6 +833,14 @@ public class MaterialMapStore {
return tridents.contains(id);
}
+ public boolean isMace(@NotNull Material material) {
+ return isMace(material.getKey().getKey());
+ }
+
+ public boolean isMace(@NotNull String id) {
+ return maces.contains(id);
+ }
+
public boolean isLeatherArmor(@NotNull Material material) {
return isLeatherArmor(material.getKey().getKey());
}
diff --git a/src/main/java/com/gmail/nossr50/util/Permissions.java b/src/main/java/com/gmail/nossr50/util/Permissions.java
index 6dcd9b800..5a78bcf18 100644
--- a/src/main/java/com/gmail/nossr50/util/Permissions.java
+++ b/src/main/java/com/gmail/nossr50/util/Permissions.java
@@ -246,6 +246,14 @@ public final class Permissions {
}
public static boolean tridentsLimitBreak(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.tridents.superability"); }
+ /* MACES */
+ public static boolean macesSuper(Permissible permissible) {
+ // TODO: When a super is added, change this
+ return false;
+ }
+
+ public static boolean macesLimitBreak(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.maces.limitbreak"); }
+
/*
* PARTY
*/
diff --git a/src/main/java/com/gmail/nossr50/util/PotionCompatibilityType.java b/src/main/java/com/gmail/nossr50/util/PotionCompatibilityType.java
new file mode 100644
index 000000000..ea070814d
--- /dev/null
+++ b/src/main/java/com/gmail/nossr50/util/PotionCompatibilityType.java
@@ -0,0 +1,6 @@
+package com.gmail.nossr50.util;
+
+public enum PotionCompatibilityType {
+ PRE_1_20_5,
+ POST_1_20_5
+}
diff --git a/src/main/java/com/gmail/nossr50/util/PotionEffectMapper.java b/src/main/java/com/gmail/nossr50/util/PotionEffectMapper.java
new file mode 100644
index 000000000..f58c66834
--- /dev/null
+++ b/src/main/java/com/gmail/nossr50/util/PotionEffectMapper.java
@@ -0,0 +1,142 @@
+package com.gmail.nossr50.util;
+
+import com.gmail.nossr50.mcMMO;
+import org.bukkit.potion.PotionEffectType;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+final public class PotionEffectMapper {
+ private static final PotionEffectType haste;
+ private static final PotionEffectType nausea;
+ private static final Method potionEffectTypeWrapperGetPotionEffectType;
+ private static final Class> classPotionEffectTypeWrapper;
+
+ private PotionEffectMapper() {
+ // Utility class
+ }
+
+ static {
+ potionEffectTypeWrapperGetPotionEffectType = getPotionEffectTypeWrapperGetPotionEffectType();
+ classPotionEffectTypeWrapper = getClassPotionEffectTypeWrapper();
+
+ haste = initHaste();
+ nausea = initNausea();
+ }
+
+ private static Method getPotionEffectTypeWrapperGetPotionEffectType() {
+ try {
+ return classPotionEffectTypeWrapper.getMethod("getType");
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+
+ private static Class> getClassPotionEffectTypeWrapper() {
+ try {
+ return Class.forName("org.bukkit.potion.PotionEffectTypeWrapper");
+ } catch (ClassNotFoundException e) {
+ return null;
+ }
+ }
+
+ private static PotionEffectType initNausea() {
+ if (classPotionEffectTypeWrapper != null) {
+ return getNauseaLegacy();
+ } else {
+ return getNauseaModern();
+ }
+ }
+
+ private static PotionEffectType getNauseaModern() {
+// PotionEffectType potionEffectType = Registry.EFFECT.match("nausea");
+// if (potionEffectType != null) {
+// return potionEffectType;
+// }
+//
+// // Look for the potion effect type by name
+// for (PotionEffectType pet : Registry.EFFECT) {
+// if (pet.getKey().getKey().equalsIgnoreCase("CONFUSION")
+// || pet.getKey().getKey().equalsIgnoreCase("NAUSEA")
+// || pet.getName().equalsIgnoreCase("CONFUSION")
+// || pet.getName().equalsIgnoreCase("NAUSEA")) {
+// return pet;
+// }
+// }
+
+ try {
+ return (PotionEffectType) PotionEffectType.class.getField("NAUSEA").get(null);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ mcMMO.p.getLogger().severe("Unable to find the Nausea potion effect type, " +
+ "mcMMO will not function properly.");
+ throw new IllegalStateException("Unable to find the Nausea potion effect type");
+ }
+ }
+
+ private static PotionEffectType getNauseaLegacy() {
+ try {
+ Object potionEffectTypeWrapper = PotionEffectType.class.getField("CONFUSION").get(null);
+ PotionEffectType potionEffectType = (PotionEffectType) potionEffectTypeWrapperGetPotionEffectType
+ .invoke(potionEffectTypeWrapper);
+ return potionEffectType;
+ } catch (IllegalAccessException | NoSuchFieldException | InvocationTargetException e) {
+ mcMMO.p.getLogger().severe("Unable to find the Nausea potion effect type, " +
+ "mcMMO will not function properly.");
+ throw new IllegalStateException("Unable to find the Nausea potion effect type");
+ }
+ }
+
+ private static PotionEffectType initHaste() {
+
+
+ mcMMO.p.getLogger().severe("Unable to find the Haste potion effect type, " +
+ "mcMMO will not function properly.");
+ throw new IllegalStateException("Unable to find the Haste potion effect type");
+ }
+
+ private static PotionEffectType getHasteLegacy() {
+ try {
+ Object potionEffectTypeWrapper = PotionEffectType.class.getField("FAST_DIGGING").get(null);
+ PotionEffectType potionEffectType = (PotionEffectType) potionEffectTypeWrapperGetPotionEffectType
+ .invoke(potionEffectTypeWrapper);
+ return potionEffectType;
+ } catch (IllegalAccessException | NoSuchFieldException | InvocationTargetException e) {
+ mcMMO.p.getLogger().severe("Unable to find the Haste potion effect type, " +
+ "mcMMO will not function properly.");
+ throw new IllegalStateException("Unable to find the Haste potion effect type");
+ }
+ }
+
+ private static PotionEffectType getHasteModern() {
+// PotionEffectType potionEffectType = Registry.EFFECT.match("haste");
+// if (potionEffectType != null) {
+// return potionEffectType;
+// }
+//
+// // Look for the potion effect type by name
+// for (PotionEffectType pet : Registry.EFFECT) {
+// if (pet.getKey().getKey().equalsIgnoreCase("HASTE")
+// || pet.getKey().getKey().equalsIgnoreCase("FAST_DIGGING")
+// || pet.getName().equalsIgnoreCase("HASTE")
+// || pet.getName().equalsIgnoreCase("FAST_DIGGING")) {
+// return pet;
+// }
+// }
+
+ try {
+ return (PotionEffectType) PotionEffectType.class.getField("HASTE").get(null);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ mcMMO.p.getLogger().severe("Unable to find the Haste potion effect type, " +
+ "mcMMO will not function properly.");
+ throw new IllegalStateException("Unable to find the Haste potion effect type");
+ }
+ }
+
+ public static PotionEffectType getHaste() {
+ return haste;
+ }
+
+ public static PotionEffectType getNausea() {
+ return nausea;
+ }
+}
diff --git a/src/main/java/com/gmail/nossr50/util/PotionUtil.java b/src/main/java/com/gmail/nossr50/util/PotionUtil.java
new file mode 100644
index 000000000..d1e255bde
--- /dev/null
+++ b/src/main/java/com/gmail/nossr50/util/PotionUtil.java
@@ -0,0 +1,447 @@
+package com.gmail.nossr50.util;
+
+import com.gmail.nossr50.mcMMO;
+import org.bukkit.NamespacedKey;
+import org.bukkit.inventory.meta.PotionMeta;
+import org.bukkit.potion.PotionEffectType;
+import org.bukkit.potion.PotionType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class PotionUtil {
+ // Some of the old potion types got renamed, our configs can still contain these old names
+ private static final Map legacyPotionTypes = new HashMap<>();
+ private static final Method methodPotionTypeGetKey;
+ private static final Method methodPotionTypeGetEffectType;
+ private static final Method methodPotionTypeGetPotionEffects;
+ private static final Method methodPotionDataIsUpgraded;
+ private static final Method methodPotionDataIsExtended;
+ private static final Method methodPotionDataGetType;
+ private static final Method methodPotionMetaGetBasePotionData;
+ private static final Method methodPotionMetaGetBasePotionType;
+ private static final Method methodPotionMetaSetBasePotionType;
+ private static final Method methodSetBasePotionData;
+ private static final Class> potionDataClass;
+
+ public static final String STRONG = "STRONG";
+ public static final String LONG = "LONG";
+ public static final String LEGACY_WATER_POTION_TYPE = "WATER";
+
+ private static final PotionCompatibilityType COMPATIBILITY_MODE;
+
+ static {
+ // We used to use uncraftable as the potion type
+ // this type isn't available anymore, so water will do
+ legacyPotionTypes.put("UNCRAFTABLE", "WATER");
+ legacyPotionTypes.put("JUMP", "LEAPING");
+ legacyPotionTypes.put("SPEED", "SWIFTNESS");
+ legacyPotionTypes.put("INSTANT_HEAL", "HEALING");
+ legacyPotionTypes.put("INSTANT_DAMAGE", "HARMING");
+ legacyPotionTypes.put("REGEN", "REGENERATION");
+ methodPotionTypeGetKey = getKeyMethod();
+ methodPotionDataIsUpgraded = getPotionDataIsUpgraded();
+ methodPotionDataIsExtended = getIsExtended();
+ methodPotionMetaGetBasePotionData = getBasePotionData();
+ methodPotionMetaGetBasePotionType = getBasePotionType();
+ methodPotionMetaSetBasePotionType = getMethodPotionMetaSetBasePotionType();
+ methodPotionDataGetType = getPotionDataGetType();
+ methodPotionTypeGetEffectType = getPotionTypeEffectType();
+ methodPotionTypeGetPotionEffects = getPotionTypeGetPotionEffects();
+ methodSetBasePotionData = getSetBasePotionData();
+ potionDataClass = getPotionDataClass();
+
+ if (methodPotionMetaGetBasePotionData != null) {
+ COMPATIBILITY_MODE = PotionCompatibilityType.PRE_1_20_5;
+ } else {
+ COMPATIBILITY_MODE = PotionCompatibilityType.POST_1_20_5;
+ }
+ }
+
+ /**
+ * Derive a potion from a partial name, and whether it should be upgraded or extended.
+ * @param partialName potion type as a string, can be a substring of the potion type but must match exactly
+ * @return The potion type
+ */
+ public static PotionType matchPotionType(String partialName, boolean isUpgraded, boolean isExtended) {
+ if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
+ return matchLegacyPotionType(partialName);
+ } else {
+ String updatedName = convertLegacyNames(partialName);
+ return Arrays.stream(PotionType.values())
+ .filter(potionType -> getKeyGetKey(potionType).toUpperCase().contains(partialName)
+ || getKeyGetKey(potionType).toUpperCase().contains(convertLegacyNames(updatedName)))
+ .filter(potionType -> !isUpgraded || potionType.name().toUpperCase().contains(STRONG))
+ .filter(potionType -> !isExtended || potionType.name().toUpperCase().contains(LONG))
+ .findAny().orElse(null);
+ }
+ }
+
+ public static String getKeyGetKey(PotionType potionType) {
+ try {
+ if (getKeyMethod() != null) {
+ NamespacedKey key = (NamespacedKey) methodPotionTypeGetKey.invoke(potionType);
+ return key.getKey();
+ } else {
+ return potionType.name();
+ }
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ mcMMO.p.getLogger().warning("Failed to get potion key for " + potionType.name());
+ return potionType.name();
+ }
+ }
+
+ private static Class> getPotionDataClass() {
+ try {
+ return Class.forName("org.bukkit.potion.PotionData");
+ } catch (ClassNotFoundException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Older versions of Spigot do not have getKey() in PotionType
+ * We need to check for the existence of this method before calling it
+ * @return The getKey method
+ */
+ private static @Nullable Method getKeyMethod() {
+ try {
+ return PotionType.class.getMethod("getKey");
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+
+ private static Method getMethodPotionMetaSetBasePotionType() {
+ try {
+ return PotionMeta.class.getMethod("setBasePotionType", PotionType.class);
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+
+ private static Method getSetBasePotionData() {
+ try {
+ return PotionMeta.class.getMethod("setBasePotionData", potionDataClass);
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+
+ private static @Nullable Method getPotionDataIsUpgraded() {
+ try {
+ // TODO: > Needed?
+ final Class> clazz = Class.forName("org.bukkit.potion.PotionData");
+ return clazz.getMethod("isUpgraded");
+ } catch (NoSuchMethodException | ClassNotFoundException e) {
+ return null;
+ }
+ }
+
+ private static @Nullable Method getIsExtended() {
+ try {
+ // TODO: > Needed?
+ final Class> clazz = Class.forName("org.bukkit.potion.PotionData");
+ return clazz.getMethod("isExtended");
+ } catch (NoSuchMethodException | ClassNotFoundException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Newer versions of Spigot do not have getBasePotionData() in PotionMeta
+ *
+ * @return the getBasePotionData method, or null if it does not exist
+ */
+ private static @Nullable Method getBasePotionData() {
+ try {
+ return PotionType.class.getMethod("getBasePotionData");
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+
+ private static Method getBasePotionType() {
+ try {
+ return PotionMeta.class.getMethod("getBasePotionType");
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+
+ private static Method getPotionDataGetType() {
+ try {
+ final Class> clazz = Class.forName("org.bukkit.potion.PotionData");
+ return clazz.getMethod("getType");
+ } catch (NoSuchMethodException | ClassNotFoundException e) {
+ return null;
+ }
+ }
+
+ private static Method getPotionTypeEffectType() {
+ try {
+ return PotionType.class.getMethod("getEffectType");
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+
+ private static Method getPotionTypeGetPotionEffects() {
+ try {
+ return PotionType.class.getMethod("getPotionEffects");
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Legacy matching for {@link PotionType}
+ *
+ * @param partialName The partial name of the potion
+ * @return The potion type
+ */
+ private static PotionType matchLegacyPotionType(String partialName) {
+ String updatedName = convertLegacyNames(partialName);
+
+ return Arrays.stream(PotionType.values())
+ .filter(potionType -> getKeyGetKey(potionType).equalsIgnoreCase(partialName)
+ || getKeyGetKey(potionType).equalsIgnoreCase(convertLegacyNames(updatedName))
+ || potionType.name().equalsIgnoreCase(partialName)
+ || potionType.name().equalsIgnoreCase(convertLegacyNames(updatedName)))
+ .findAny().orElse(null);
+ }
+
+ public static String convertPotionConfigName(String legacyName) {
+ String replacementName = legacyName;
+
+ // Remove generated potions.yml config naming convention
+ if (replacementName.contains("POTION_OF_")) {
+ replacementName = replacementName.replace("POTION_OF_", "");
+ }
+
+ if (replacementName.contains("_II")) {
+ replacementName = replacementName.replace("_II", "");
+ replacementName = "STRONG_" + replacementName;
+ } else if (replacementName.contains("_EXTENDED")) {
+ replacementName = replacementName.replace("_EXTENDED", "");
+ replacementName = "LONG_" + replacementName;
+ }
+ return replacementName;
+ }
+
+ public static String convertLegacyNames(String legacyPotionType) {
+ String modernized = legacyPotionType;
+ // check for legacy names
+ for (var key : legacyPotionTypes.keySet()) {
+ if (modernized.contains(key)) {
+ // Replace the legacy name with the new name
+ modernized = modernized.replace(key, legacyPotionTypes.get(key));
+ break;
+ }
+ }
+ return modernized;
+ }
+
+ public static boolean hasLegacyName(String potionType) {
+ for (var key : legacyPotionTypes.keySet()) {
+ if (potionType.contains(key)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean isStrong(PotionMeta potionMeta) {
+ if (methodPotionMetaGetBasePotionData == null) {
+ return isStrongModern(potionMeta);
+ } else {
+ return isStrongLegacy(potionMeta);
+ }
+
+ }
+
+ public static boolean isLong(PotionMeta potionMeta) {
+ if (methodPotionMetaGetBasePotionData == null) {
+ return isLongModern(potionMeta);
+ } else {
+ return isLongLegacy(potionMeta);
+ }
+ }
+
+ private static boolean isLongLegacy(PotionMeta potionMeta) {
+ try {
+ Object potionData = methodPotionMetaGetBasePotionData.invoke(potionMeta);
+ return (boolean) methodPotionDataIsExtended.invoke(potionData);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static boolean isLongModern(PotionMeta potionMeta) {
+ try {
+ return getModernPotionTypeKey(potionMeta).getKey().startsWith(LONG);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static boolean isStrongLegacy(PotionMeta potionMeta) {
+ try {
+ Object potionData = methodPotionMetaGetBasePotionData.invoke(potionMeta);
+ return (boolean) methodPotionDataIsUpgraded.invoke(potionData);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static boolean isStrongModern(PotionMeta potionMeta) {
+ try {
+ return getModernPotionTypeKey(potionMeta).getKey().startsWith(STRONG);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static NamespacedKey getModernPotionTypeKey(PotionMeta potionMeta) throws IllegalAccessException, InvocationTargetException {
+ PotionType potionType = (PotionType) methodPotionMetaGetBasePotionType.invoke(potionMeta);
+ return (NamespacedKey) methodPotionTypeGetKey.invoke(potionType);
+ }
+
+ public static boolean isPotionTypeWater(@NotNull PotionMeta potionMeta) {
+ if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
+ return isPotionTypeWaterLegacy(potionMeta);
+ } else {
+ return isPotionTypeWaterModern(potionMeta);
+ }
+ }
+
+ private static boolean isPotionTypeWaterLegacy(@NotNull PotionMeta potionMeta) {
+ try {
+ Object potionData = methodPotionMetaGetBasePotionData.invoke(potionMeta);
+ PotionType potionType = (PotionType) methodPotionDataGetType.invoke(potionData);
+ return potionType.name().equalsIgnoreCase(LEGACY_WATER_POTION_TYPE)
+ || PotionType.valueOf(LEGACY_WATER_POTION_TYPE) == potionType;
+ } catch (InvocationTargetException | IllegalAccessException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private static boolean isPotionTypeWaterModern(@NotNull PotionMeta potionMeta) {
+ try {
+ return getModernPotionTypeKey(potionMeta).getKey().equalsIgnoreCase(LEGACY_WATER_POTION_TYPE);
+ } catch (IllegalAccessException | InvocationTargetException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public static boolean samePotionType(PotionMeta potionMeta, PotionMeta otherPotionMeta) {
+ if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
+ return samePotionTypeLegacy(potionMeta, otherPotionMeta);
+ } else {
+ return samePotionTypeModern(potionMeta, otherPotionMeta);
+ }
+ }
+
+ private static boolean samePotionTypeLegacy(PotionMeta potionMeta, PotionMeta otherPotionMeta) {
+ try {
+ Object potionData = methodPotionMetaGetBasePotionData.invoke(potionMeta);
+ Object otherPotionData = methodPotionMetaGetBasePotionData.invoke(otherPotionMeta);
+ PotionType potionType = (PotionType) methodPotionDataGetType.invoke(potionData);
+ PotionType otherPotionType = (PotionType) methodPotionDataGetType.invoke(otherPotionData);
+ return potionType == otherPotionType;
+ } catch (IllegalAccessException | InvocationTargetException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private static boolean samePotionTypeModern(PotionMeta potionMeta, PotionMeta otherPotionMeta) {
+ try {
+ PotionType potionType = (PotionType) methodPotionMetaGetBasePotionType.invoke(potionMeta);
+ PotionType otherPotionType = (PotionType) methodPotionMetaGetBasePotionType.invoke(otherPotionMeta);
+ return potionType == otherPotionType;
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static boolean samePotionEffects(PotionMeta potionMeta, PotionMeta otherPotionMeta) {
+ if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
+ return true;
+ } else {
+ return samePotionEffectsModern(potionMeta, otherPotionMeta);
+ }
+ }
+
+ private static boolean samePotionEffectsModern(PotionMeta potionMeta, PotionMeta otherPotionMeta) {
+ return potionMeta.getCustomEffects().equals(otherPotionMeta.getCustomEffects());
+ }
+
+ public static boolean hasBasePotionEffects(PotionMeta potionMeta) {
+ if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
+ return hasBasePotionEffectsLegacy(potionMeta);
+ } else {
+ return hasBasePotionEffectsModern(potionMeta);
+ }
+ }
+
+ private static boolean hasBasePotionEffectsLegacy(PotionMeta potionMeta) {
+ try {
+ Object potionData = methodPotionMetaGetBasePotionData.invoke(potionMeta);
+ PotionType potionType = (PotionType) methodPotionDataGetType.invoke(potionData);
+ return methodPotionTypeGetEffectType.invoke(potionType) != null;
+ } catch (IllegalAccessException | InvocationTargetException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private static boolean hasBasePotionEffectsModern(PotionMeta potionMeta) {
+ try {
+ PotionType potionType = (PotionType) methodPotionMetaGetBasePotionType.invoke(potionMeta);
+ List potionEffectTypeList = (List) methodPotionTypeGetPotionEffects.invoke(potionType);
+ return potionEffectTypeList != null || !potionEffectTypeList.isEmpty();
+ } catch (IllegalAccessException | InvocationTargetException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ /**
+ * Set the base potion type of a potion meta.
+ * Note that extended/upgraded are ignored in 1.20.5 and later.
+ *
+ * @param potionMeta the potion meta
+ * @param extended true if the potion is extended
+ * @param upgraded true if the potion is upgraded
+ */
+ public static void setBasePotionType(PotionMeta potionMeta, PotionType potionType, boolean extended, boolean upgraded) {
+ if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
+ setBasePotionTypeLegacy(potionMeta, potionType, extended, upgraded);
+ } else {
+ setBasePotionTypeModern(potionMeta, potionType);
+ }
+ }
+
+ private static void setBasePotionTypeLegacy(PotionMeta potionMeta, PotionType potionType, boolean extended,
+ boolean upgraded) {
+ try {
+ Object potionData = potionDataClass.getConstructor(PotionType.class, boolean.class, boolean.class)
+ .newInstance(potionType, extended, upgraded);
+ methodSetBasePotionData.invoke(potionMeta, potionData);
+ } catch (IllegalAccessException | InvocationTargetException | InstantiationException | NoSuchMethodException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private static void setBasePotionTypeModern(PotionMeta potionMeta, PotionType potionType) {
+ try {
+ methodPotionMetaSetBasePotionType.invoke(potionMeta, potionType);
+ } catch (IllegalAccessException | InvocationTargetException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+}
diff --git a/src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java b/src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java
index 0946b4cc5..ced2cbf25 100644
--- a/src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java
+++ b/src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java
@@ -33,6 +33,9 @@ public final class CommandRegistrationManager {
private static void registerSkillCommands() {
for (PrimarySkillType skill : PrimarySkillType.values()) {
+ if (skill == PrimarySkillType.MACES)
+ continue;
+
String commandName = skill.toString().toLowerCase(Locale.ENGLISH);
String localizedName = mcMMO.p.getSkillTools().getLocalizedSkillName(skill).toLowerCase(Locale.ENGLISH);
@@ -77,6 +80,10 @@ public final class CommandRegistrationManager {
command.setExecutor(new HerbalismCommand());
break;
+ case MACES:
+ // command.setExecutor(new MacesCommand());
+ break;
+
case MINING:
command.setExecutor(new MiningCommand());
break;
@@ -113,7 +120,7 @@ public final class CommandRegistrationManager {
break;
default:
- break;
+ throw new IllegalStateException("Unexpected value: " + skill);
}
}
}
diff --git a/src/main/java/com/gmail/nossr50/util/compat/CompatibilityManager.java b/src/main/java/com/gmail/nossr50/util/compat/CompatibilityManager.java
index 11d4a6d68..012524adb 100644
--- a/src/main/java/com/gmail/nossr50/util/compat/CompatibilityManager.java
+++ b/src/main/java/com/gmail/nossr50/util/compat/CompatibilityManager.java
@@ -23,7 +23,6 @@ import java.util.HashMap;
* In 2.2 we are switching to modules and that will clean things up significantly
*
*/
-//TODO: I need to delete this crap
public class CompatibilityManager {
private @NotNull HashMap supportedLayers;
private boolean isFullyCompatibleServerSoftware = true; //true if all compatibility layers load successfully
@@ -159,7 +158,7 @@ public class CompatibilityManager {
return masterAnglerCompatibility;
}
- public @Nullable MinecraftGameVersion getMinecraftGameVersion() {
+ public @NotNull MinecraftGameVersion getMinecraftGameVersion() {
return minecraftGameVersion;
}
}
diff --git a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java
index fd2d240c2..168d778a3 100644
--- a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java
+++ b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java
@@ -111,6 +111,7 @@ public final class CombatUtils {
}
}
}
+
private static void processTridentCombatMelee(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) {
if (event.getCause() == DamageCause.THORNS) {
return;
@@ -214,6 +215,32 @@ public final class CombatUtils {
delayArrowMetaCleanup(arrow);
}
+ private static void processMacesCombat(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) {
+ if (event.getCause() == DamageCause.THORNS) {
+ return;
+ }
+
+ double boostedDamage = event.getDamage();
+
+ McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
+
+ //Make sure the profiles been loaded
+ if(mcMMOPlayer == null) {
+ return;
+ }
+
+ // MacesManager macesManager = mcMMOPlayer.getMacesManager();
+
+ if(canUseLimitBreak(player, target, SubSkillType.MACES_MACES_LIMIT_BREAK)) {
+ boostedDamage += (getLimitBreakDamage(player, target, SubSkillType.MACES_MACES_LIMIT_BREAK) * mcMMOPlayer.getAttackStrength());
+ }
+
+ event.setDamage(boostedDamage);
+ processCombatXP(mcMMOPlayer, target, PrimarySkillType.MACES);
+
+ printFinalDamageDebug(player, event, mcMMOPlayer);
+ }
+
private static void processAxeCombat(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) {
if (event.getCause() == DamageCause.THORNS) {
return;
@@ -498,6 +525,15 @@ public final class CombatUtils {
processTridentCombatMelee(target, player, event);
}
}
+ else if (ItemUtils.isMace(heldItem)) {
+ if (!mcMMO.p.getSkillTools().canCombatSkillsTrigger(PrimarySkillType.MACES, target)) {
+ return;
+ }
+
+ if (mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.MACES)) {
+ processMacesCombat(target, player, event);
+ }
+ }
}
else if (entityType == EntityType.WOLF) {
diff --git a/src/main/java/com/gmail/nossr50/util/skills/SkillTools.java b/src/main/java/com/gmail/nossr50/util/skills/SkillTools.java
index 39ddfbd24..d9f25db2c 100644
--- a/src/main/java/com/gmail/nossr50/util/skills/SkillTools.java
+++ b/src/main/java/com/gmail/nossr50/util/skills/SkillTools.java
@@ -198,6 +198,7 @@ public class SkillTools {
case SUPER_SHOTGUN -> PrimarySkillType.CROSSBOWS;
case TRIDENTS_SUPER_ABILITY -> PrimarySkillType.TRIDENTS;
case EXPLOSIVE_SHOT -> PrimarySkillType.ARCHERY;
+ case MACES_SUPER_ABILITY -> PrimarySkillType.MACES;
};
}
diff --git a/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java b/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java
index b0d406ae6..17589c2fa 100644
--- a/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java
+++ b/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java
@@ -20,7 +20,6 @@ import com.gmail.nossr50.util.text.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
-import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
@@ -28,12 +27,13 @@ import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.ShapelessRecipe;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.potion.PotionEffect;
-import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Iterator;
+import static com.gmail.nossr50.util.PotionEffectMapper.getHaste;
+
public final class SkillUtils {
/**
* This is a static utility class, therefore we don't want any instances of
@@ -148,13 +148,8 @@ public final class SkillUtils {
return;
}
- int originalDigSpeed = heldItem.getEnchantmentLevel(Enchantment.DIG_SPEED);
-
- //Add dig speed
-
- //Lore no longer gets added, no point to it afaik
- //ItemUtils.addAbilityLore(heldItem); //lore can be a secondary failsafe for 1.13 and below
- ItemUtils.addDigSpeedToItem(heldItem, heldItem.getEnchantmentLevel(Enchantment.DIG_SPEED));
+ int originalDigSpeed = heldItem.getEnchantmentLevel(mcMMO.p.getEnchantmentMapper().getEfficiency());
+ ItemUtils.addDigSpeedToItem(heldItem, heldItem.getEnchantmentLevel(mcMMO.p.getEnchantmentMapper().getEfficiency()));
//1.13.2+ will have persistent metadata for this item
mcMMO.getMetadataService().getItemMetadataService().setSuperAbilityBoostedItem(heldItem, originalDigSpeed);
@@ -162,9 +157,9 @@ public final class SkillUtils {
int duration = 0;
int amplifier = 0;
- if (player.hasPotionEffect(PotionEffectType.FAST_DIGGING)) {
+ if (player.hasPotionEffect(getHaste())) {
for (PotionEffect effect : player.getActivePotionEffects()) {
- if (effect.getType() == PotionEffectType.FAST_DIGGING) {
+ if (effect.getType() == getHaste()) {
duration = effect.getDuration();
amplifier = effect.getAmplifier();
break;
@@ -194,7 +189,7 @@ public final class SkillUtils {
mcMMO.p.getSkillTools().getSuperAbilityMaxLength(mcMMO.p.getSkillTools().getSuperAbility(skill))) * Misc.TICK_CONVERSION_FACTOR;
}
- PotionEffect abilityBuff = new PotionEffect(PotionEffectType.FAST_DIGGING, duration + ticks, amplifier + 10);
+ PotionEffect abilityBuff = new PotionEffect(getHaste(), duration + ticks, amplifier + 10);
player.addPotionEffect(abilityBuff, true);
}
}
@@ -221,7 +216,7 @@ public final class SkillUtils {
if(itemMeta != null) {
// This is safe to call without prior checks.
- itemMeta.removeEnchant(Enchantment.DIG_SPEED);
+ itemMeta.removeEnchant(mcMMO.p.getEnchantmentMapper().getEfficiency());
itemStack.setItemMeta(itemMeta);
ItemUtils.removeAbilityLore(itemStack);
@@ -251,7 +246,7 @@ public final class SkillUtils {
Material type = itemStack.getType();
short maxDurability = mcMMO.getRepairableManager().isRepairable(type) ? mcMMO.getRepairableManager().getRepairable(type).getMaximumDurability() : type.getMaxDurability();
- durabilityModifier = (int) Math.min(durabilityModifier / (itemStack.getEnchantmentLevel(Enchantment.DURABILITY) + 1), maxDurability * maxDamageModifier);
+ durabilityModifier = (int) Math.min(durabilityModifier / (itemStack.getEnchantmentLevel(mcMMO.p.getEnchantmentMapper().getUnbreaking()) + 1), maxDurability * maxDamageModifier);
itemStack.setDurability((short) Math.min(itemStack.getDurability() + durabilityModifier, maxDurability));
}
@@ -281,7 +276,7 @@ public final class SkillUtils {
Material type = itemStack.getType();
short maxDurability = mcMMO.getRepairableManager().isRepairable(type) ? mcMMO.getRepairableManager().getRepairable(type).getMaximumDurability() : type.getMaxDurability();
- durabilityModifier = (int) Math.min(durabilityModifier * (0.6 + 0.4/ (itemStack.getEnchantmentLevel(Enchantment.DURABILITY) + 1)), maxDurability * maxDamageModifier);
+ durabilityModifier = (int) Math.min(durabilityModifier * (0.6 + 0.4/ (itemStack.getEnchantmentLevel(mcMMO.p.getEnchantmentMapper().getUnbreaking()) + 1)), maxDurability * maxDamageModifier);
itemStack.setDurability((short) Math.min(itemStack.getDurability() + durabilityModifier, maxDurability));
}
diff --git a/src/main/resources/experience.yml b/src/main/resources/experience.yml
index a41609521..a4838cd67 100644
--- a/src/main/resources/experience.yml
+++ b/src/main/resources/experience.yml
@@ -1,13 +1,3 @@
-#
-# Experience configuration
-# Last updated on ${project.version}-b${BUILD_NUMBER}
-#
-# Configure the experience formula and experience settings here.
-#
-#####
-
-
-
# https://hub.spigotmc.org/javadocs/spigot/org/bukkit/boss/BarColor.html
# These are the only valid colors for Experience Bars, use the exact name found here
# BLUE, GREEN, PINK, PURPLE, RED, WHITE, YELLOW (As of the time of this update these are the only Bar colors available, this could change in the future so check the BarColor enum to see if it has)
@@ -48,7 +38,7 @@ Fishing_ExploitFix_Options:
MoveRange: 3
OverFishLimit: 10
Experience_Bars:
- # Turn this to false if you wanna disable XP bars
+ # Turn this to false if you want to disable XP bars
Enable: true
Update:
# XP that you gained from your party but not yourself
@@ -98,6 +88,10 @@ Experience_Bars:
Enable: true
Color: YELLOW
BarStyle: SEGMENTED_6
+ Maces:
+ Enable: true
+ Color: BLUE
+ BarStyle: SEGMENTED_6
Repair:
Enable: true
Color: PURPLE
@@ -170,6 +164,7 @@ Experience_Formula:
# Experience gained will get multiplied by these values. 1.0 by default, 0.5 means half XP gained. This happens right before multiplying the XP by the global multiplier.
Skill_Multiplier:
+ Maces: 1.0
Crossbows: 1.0
Tridents: 1.0
Swords: 1.0
@@ -217,6 +212,9 @@ Diminished_Returns:
Repair: 20000
Fishing: 20000
Alchemy: 20000
+ Crossbows: 20000
+ Tridents: 20000
+ Maces: 20000
Time_Interval: 10
diff --git a/src/main/resources/locale/locale_en_US.properties b/src/main/resources/locale/locale_en_US.properties
index 11e550b20..f2fcc7a26 100644
--- a/src/main/resources/locale/locale_en_US.properties
+++ b/src/main/resources/locale/locale_en_US.properties
@@ -1,3 +1,4 @@
+Placeholder= This value is for any WIP locale entries that will not be displayed to users
JSON.Rank=Rank
JSON.DescriptionHeader=Description:
JSON.JWrapper.Header=Details
@@ -26,6 +27,7 @@ JSON.Salvage=Salvage
JSON.Swords=Swords
JSON.Taming=Taming
JSON.Tridents=Tridents
+JSON.Maces=Maces
JSON.Unarmed=Unarmed
JSON.Woodcutting=Woodcutting
JSON.URL.Website=The official mcMMO Website!
@@ -96,6 +98,7 @@ Overhaul.Name.Smelting=Smelting
Overhaul.Name.Swords=Swords
Overhaul.Name.Taming=Taming
Overhaul.Name.Tridents=Tridents
+Overhaul.Name.Maces=Maces
Overhaul.Name.Unarmed=Unarmed
Overhaul.Name.Woodcutting=Woodcutting
# /mcMMO Command Style Stuff
@@ -122,6 +125,7 @@ XPBar.Smelting=Smelting Lv.&6{0}
XPBar.Swords=Swords Lv.&6{0}
XPBar.Taming=Taming Lv.&6{0}
XPBar.Tridents=Tridents Lv.&6{0}
+XPBar.Maces=Maces Lv.&6{0}
XPBar.Unarmed=Unarmed Lv.&6{0}
XPBar.Woodcutting=Woodcutting Lv.&6{0}
#This is just a preset template that gets used if the 'ExtraDetails' setting is turned on in experience.yml (off by default), you can ignore this template and just edit the strings above
@@ -457,9 +461,6 @@ Tridents.Listener=Tridents:
Maces.SkillName=MACES
Maces.Ability.Lower=&7You lower your mace.
Maces.Ability.Ready=&3You &6ready&3 your Mace.
-Maces.Skills.MaceSmash.Refresh=&aYour &eGiga Smash &aability is refreshed!
-Maces.Skills.MaceSmash.Other.On=&a{0}&2 used &cGiga Smash!
-Maces.SubSkill.GigaSmash.Name=Giga Smash
Maces.SubSkill.MacesLimitBreak.Name=Maces Limit Break
Maces.SubSkill.MacesLimitBreak.Description=Breaking your limits. Increased damage against tough opponents. Intended for PVP, up to server settings for whether it will boost damage in PVE.
Maces.SubSkill.MacesLimitBreak.Stat=Limit Break Max DMG
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 198d465fc..457a7e54b 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -154,6 +154,9 @@ commands:
salvage:
description: Detailed mcMMO skill info
permission: mcmmo.commands.salvage
+ maces:
+ description: Detailed mcMMO skill info
+ permission: mcmmo.commands.maces
mmopower:
description: Shows skill mastery and power level info
permission: mcmmo.commands.mmopower
diff --git a/src/main/resources/skillranks.yml b/src/main/resources/skillranks.yml
index 590ddde11..2df17807a 100644
--- a/src/main/resources/skillranks.yml
+++ b/src/main/resources/skillranks.yml
@@ -443,6 +443,30 @@ Salvage:
Rank_6: 750
Rank_7: 850
Rank_8: 1000
+Maces:
+ TridentsLimitBreak:
+ Standard:
+ Rank_1: 10
+ Rank_2: 20
+ Rank_3: 30
+ Rank_4: 40
+ Rank_5: 50
+ Rank_6: 60
+ Rank_7: 70
+ Rank_8: 80
+ Rank_9: 90
+ Rank_10: 100
+ RetroMode:
+ Rank_1: 100
+ Rank_2: 200
+ Rank_3: 300
+ Rank_4: 400
+ Rank_5: 500
+ Rank_6: 600
+ Rank_7: 700
+ Rank_8: 800
+ Rank_9: 900
+ Rank_10: 1000
Mining:
MotherLode:
Standard:
diff --git a/src/test/java/com/gmail/nossr50/MMOTestEnvironment.java b/src/test/java/com/gmail/nossr50/MMOTestEnvironment.java
index d995ed569..47e2126aa 100644
--- a/src/test/java/com/gmail/nossr50/MMOTestEnvironment.java
+++ b/src/test/java/com/gmail/nossr50/MMOTestEnvironment.java
@@ -16,13 +16,12 @@ import com.gmail.nossr50.util.blockmeta.ChunkManager;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillTools;
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.Server;
-import org.bukkit.World;
+import org.bukkit.*;
import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemFactory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
+import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.PluginManager;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
@@ -31,9 +30,10 @@ import java.util.UUID;
import java.util.logging.Logger;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
public abstract class MMOTestEnvironment {
+ protected MockedStatic mockedBukkit;
protected MockedStatic mockedMcMMO;
protected MockedStatic mockedChatConfig;
protected MockedStatic experienceConfig;
@@ -63,26 +63,27 @@ public abstract class MMOTestEnvironment {
protected PlayerProfile playerProfile;
protected McMMOPlayer mmoPlayer;
protected String playerName = "testPlayer";
+ protected ItemFactory itemFactory;
protected ChunkManager chunkManager;
protected MaterialMapStore materialMapStore;
protected void mockBaseEnvironment(Logger logger) throws InvalidSkillException {
- mockedMcMMO = Mockito.mockStatic(mcMMO.class);
- mcMMO.p = Mockito.mock(mcMMO.class);
+ mockedMcMMO = mockStatic(mcMMO.class);
+ mcMMO.p = mock(mcMMO.class);
when(mcMMO.p.getLogger()).thenReturn(logger);
// place store
- chunkManager = Mockito.mock(ChunkManager.class);
+ chunkManager = mock(ChunkManager.class);
when(mcMMO.getPlaceStore()).thenReturn(chunkManager);
// shut off mod manager for woodcutting
- when(mcMMO.getModManager()).thenReturn(Mockito.mock(ModManager.class));
+ when(mcMMO.getModManager()).thenReturn(mock(ModManager.class));
when(mcMMO.getModManager().isCustomLog(any())).thenReturn(false);
// chat config
- mockedChatConfig = Mockito.mockStatic(ChatConfig.class);
- when(ChatConfig.getInstance()).thenReturn(Mockito.mock(ChatConfig.class));
+ mockedChatConfig = mockStatic(ChatConfig.class);
+ when(ChatConfig.getInstance()).thenReturn(mock(ChatConfig.class));
// general config
mockGeneralConfig();
@@ -108,29 +109,34 @@ public abstract class MMOTestEnvironment {
mockPermissions();
- mockedRankUtils = Mockito.mockStatic(RankUtils.class);
+ mockedRankUtils = mockStatic(RankUtils.class);
// wire server
- this.server = Mockito.mock(Server.class);
+ this.server = mock(Server.class);
when(mcMMO.p.getServer()).thenReturn(server);
+ mockedBukkit = mockStatic(Bukkit.class);
+ when(Bukkit.getItemFactory()).thenReturn(itemFactory);
+ itemFactory = mock(ItemFactory.class);
+ // when(itemFactory.getItemMeta(any())).thenReturn(mock(ItemMeta.class));
+
// wire plugin manager
- this.pluginManager = Mockito.mock(PluginManager.class);
+ this.pluginManager = mock(PluginManager.class);
when(server.getPluginManager()).thenReturn(pluginManager);
// wire world
- this.world = Mockito.mock(World.class);
+ this.world = mock(World.class);
// wire Misc
- this.mockedMisc = Mockito.mockStatic(Misc.class);
+ this.mockedMisc = mockStatic(Misc.class);
when(Misc.getBlockCenter(any())).thenReturn(new Location(world, 0, 0, 0));
// setup player and player related mocks after everything else
- this.player = Mockito.mock(Player.class);
+ this.player = mock(Player.class);
when(player.getUniqueId()).thenReturn(playerUUID);
// wire inventory
- this.playerInventory = Mockito.mock(PlayerInventory.class);
+ this.playerInventory = mock(PlayerInventory.class);
when(player.getInventory()).thenReturn(playerInventory);
// PlayerProfile and McMMOPlayer are partially mocked
@@ -138,7 +144,7 @@ public abstract class MMOTestEnvironment {
mmoPlayer = Mockito.spy(new McMMOPlayer(player, playerProfile));
// wire user manager
- this.mockedUserManager = Mockito.mockStatic(UserManager.class);
+ this.mockedUserManager = mockStatic(UserManager.class);
when(UserManager.getPlayer(player)).thenReturn(mmoPlayer);
this.materialMapStore = new MaterialMapStore();
@@ -146,7 +152,7 @@ public abstract class MMOTestEnvironment {
}
private void mockPermissions() {
- mockedPermissions = Mockito.mockStatic(Permissions.class);
+ mockedPermissions = mockStatic(Permissions.class);
when(Permissions.isSubSkillEnabled(any(Player.class), any(SubSkillType.class))).thenReturn(true);
when(Permissions.canUseSubSkill(any(Player.class), any(SubSkillType.class))).thenReturn(true);
when(Permissions.isSubSkillEnabled(any(Player.class), any(SubSkillType.class))).thenReturn(true);
@@ -155,16 +161,16 @@ public abstract class MMOTestEnvironment {
}
private void mockRankConfig() {
- rankConfig = Mockito.mock(RankConfig.class);
+ rankConfig = mock(RankConfig.class);
}
private void mockAdvancedConfig() {
- this.advancedConfig = Mockito.mock(AdvancedConfig.class);
+ this.advancedConfig = mock(AdvancedConfig.class);
when(mcMMO.p.getAdvancedConfig()).thenReturn(advancedConfig);
}
private void mockGeneralConfig() {
- generalConfig = Mockito.mock(GeneralConfig.class);
+ generalConfig = mock(GeneralConfig.class);
when(generalConfig.getTreeFellerThreshold()).thenReturn(100);
when(generalConfig.getDoubleDropsEnabled(PrimarySkillType.WOODCUTTING, Material.OAK_LOG)).thenReturn(true);
when(generalConfig.getLocale()).thenReturn("en_US");
@@ -172,15 +178,15 @@ public abstract class MMOTestEnvironment {
}
private void mockPartyConfig() {
- partyConfig = Mockito.mock(PartyConfig.class);
+ partyConfig = mock(PartyConfig.class);
when(partyConfig.isPartyEnabled()).thenReturn(false);
when(mcMMO.p.getPartyConfig()).thenReturn(partyConfig);
}
private void mockExperienceConfig() {
- experienceConfig = Mockito.mockStatic(ExperienceConfig.class);
+ experienceConfig = mockStatic(ExperienceConfig.class);
- when(ExperienceConfig.getInstance()).thenReturn(Mockito.mock(ExperienceConfig.class));
+ when(ExperienceConfig.getInstance()).thenReturn(mock(ExperienceConfig.class));
// Combat
when(ExperienceConfig.getInstance().getCombatXP("Cow")).thenReturn(1D);
@@ -212,5 +218,8 @@ public abstract class MMOTestEnvironment {
if (mockedEventUtils != null) {
mockedEventUtils.close();
}
+ if (mockedBukkit != null) {
+ mockedBukkit.close();
+ }
}
}
diff --git a/src/test/java/com/gmail/nossr50/config/skills/alchemy/PotionConfigTest.java b/src/test/java/com/gmail/nossr50/config/skills/alchemy/PotionConfigTest.java
new file mode 100644
index 000000000..b9b648046
--- /dev/null
+++ b/src/test/java/com/gmail/nossr50/config/skills/alchemy/PotionConfigTest.java
@@ -0,0 +1,69 @@
+//package com.gmail.nossr50.config.skills.alchemy;
+//
+//import com.gmail.nossr50.MMOTestEnvironment;
+//import org.bukkit.inventory.meta.ItemMeta;
+//import org.bukkit.inventory.meta.PotionMeta;
+//import org.junit.jupiter.api.AfterEach;
+//import org.junit.jupiter.api.BeforeEach;
+//import org.junit.jupiter.api.Test;
+//
+//import java.io.File;
+//import java.net.URL;
+//import java.util.logging.Logger;
+//
+//import static org.junit.jupiter.api.Assertions.assertNotNull;
+//import static org.mockito.ArgumentMatchers.any;
+//import static org.mockito.Mockito.mock;
+//import static org.mockito.Mockito.when;
+//
+//class PotionConfigTest extends MMOTestEnvironment {
+//
+// public static final String POTION_LEGACY_POTION_YML = "potion/legacy_potion.yml";
+// public static final String POTION_MODERN_YML = "potion/modern_potion.yml";
+// public static final Logger logger = Logger.getLogger(PotionConfigTest.class.getName());
+//
+// @BeforeEach
+// void setUp() {
+// mockBaseEnvironment(logger);
+// final PotionMeta potionMeta = mock(PotionMeta.class);
+// when(itemFactory.getItemMeta(any())).thenReturn(potionMeta);
+// }
+//
+// @AfterEach
+// void tearDown() {
+// cleanupBaseEnvironment();
+// }
+//
+// @Test
+// void testLoadLegacyConfig() {
+// final PotionConfig potionConfig = getPotionConfig(POTION_LEGACY_POTION_YML);
+// assertNotNull(potionConfig);
+//
+// potionConfig.loadConcoctions();
+// int loaded = potionConfig.loadPotionMap();
+// System.out.println("Loaded " + loaded + " potions");
+// }
+//
+// @Test
+// void testModernConfig() {
+// final PotionConfig potionConfig = getPotionConfig(POTION_MODERN_YML);
+// assertNotNull(potionConfig);
+//
+// potionConfig.loadConcoctions();
+// int loaded = potionConfig.loadPotionMap();
+// System.out.println("Loaded " + loaded + " potions");
+// }
+//
+// private PotionConfig getPotionConfig(String path) {
+// // Get the file URL using the class loader
+// final URL resource = getClass().getClassLoader().getResource(path);
+// if (resource == null) {
+// throw new IllegalArgumentException("file not found!");
+// } else {
+// // Convert URL to a File object
+// final File potionFile = new File(resource.getFile());
+// System.out.println("File path: " + potionFile.getAbsolutePath());
+// return new PotionConfig(potionFile);
+// }
+// }
+//}
\ No newline at end of file
diff --git a/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java b/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java
index 23463cbdb..8e6d04c2a 100644
--- a/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java
+++ b/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java
@@ -10,7 +10,6 @@ import com.gmail.nossr50.util.skills.SkillTools;
import com.google.common.io.Files;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
@@ -38,32 +37,30 @@ class FlatFileDatabaseManagerTest {
public static final @NotNull String BAD_DATA_FILE_LINE_TWENTY_THREE = "nossr51:baddata:::baddata:baddata:640:baddata:1000:1000:1000:baddata:baddata:baddata:baddata:16:0:500:20273:0:0:0:0::1000:0:0:baddata:1593543012:0:0:0:0::1000:0:0:baddata:IGNORED:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1:0:";
public static final @NotNull String DB_BADDATA = "baddatadb.users";
public static final @NotNull String DB_HEALTHY = "healthydb.users";
- public static final @NotNull String HEALTHY_DB_LINE_1 = "nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:IGNORED:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999:2020:140:14:150:15:1111:2222:3333";
public static final @NotNull String HEALTHY_DB_LINE_ONE_UUID_STR = "588fe472-1c82-4c4e-9aa1-7eefccb277e3";
public static final String DB_MISSING_LAST_LOGIN = "missinglastlogin.users";
- public static final String LINE_TWO_FROM_MISSING_DB = "nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:0:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999:";
private static File tempDir;
private final static @NotNull Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
private final long PURGE_TIME = 2630000000L;
- private static @Nullable FlatFileDatabaseManager db;
//Making them all unique makes it easier on us to edit this stuff later
int expectedLvlMining = 1, expectedLvlWoodcutting = 2, expectedLvlRepair = 3,
expectedLvlUnarmed = 4, expectedLvlHerbalism = 5, expectedLvlExcavation = 6,
expectedLvlArchery = 7, expectedLvlSwords = 8, expectedLvlAxes = 9, expectedLvlAcrobatics = 10,
expectedLvlTaming = 11, expectedLvlFishing = 12, expectedLvlAlchemy = 13, expectedLvlCrossbows = 14,
- expectedLvlTridents = 15;
+ expectedLvlTridents = 15, expectedLvlMaces = 16;
float expectedExpMining = 10, expectedExpWoodcutting = 20, expectedExpRepair = 30,
expectedExpUnarmed = 40, expectedExpHerbalism = 50, expectedExpExcavation = 60,
expectedExpArchery = 70, expectedExpSwords = 80, expectedExpAxes = 90, expectedExpAcrobatics = 100,
expectedExpTaming = 110, expectedExpFishing = 120, expectedExpAlchemy = 130, expectedExpCrossbows = 140,
- expectedExpTridents = 150;
+ expectedExpTridents = 150, expectedExpMaces = 160;
long expectedBerserkCd = 111, expectedGigaDrillBreakerCd = 222, expectedTreeFellerCd = 333,
expectedGreenTerraCd = 444, expectedSerratedStrikesCd = 555, expectedSkullSplitterCd = 666,
expectedSuperBreakerCd = 777, expectedBlastMiningCd = 888, expectedChimaeraWingCd = 999,
- expectedSuperShotgunCd = 1111, expectedTridentSuperCd = 2222, expectedExplosiveShotCd = 3333;
+ expectedSuperShotgunCd = 1111, expectedTridentSuperCd = 2222, expectedExplosiveShotCd = 3333,
+ expectedMacesSuperCd = 4444;
int expectedScoreboardTips = 1111;
Long expectedLastLogin = 2020L;
@@ -75,10 +72,8 @@ class FlatFileDatabaseManagerTest {
@BeforeEach
void init() {
- assertNull(db);
//noinspection UnstableApiUsage
tempDir = Files.createTempDir();
- db = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
}
private @NotNull String getTemporaryUserFilePath() {
@@ -88,7 +83,6 @@ class FlatFileDatabaseManagerTest {
@AfterEach
void tearDown() {
recursiveDelete(tempDir);
- db = null;
}
//Nothing wrong with this database
@@ -150,17 +144,19 @@ class FlatFileDatabaseManagerTest {
@Test
void testDefaultInit() {
- db = new FlatFileDatabaseManager(getTemporaryUserFilePath(), logger, PURGE_TIME, 0);
+ new FlatFileDatabaseManager(getTemporaryUserFilePath(), logger, PURGE_TIME, 0);
}
@Test
void testUpdateLeaderboards() {
- assertNotNull(db);
- assertEquals(LeaderboardStatus.UPDATED, db.updateLeaderboards());
+ FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
+ assertNotNull(flatFileDatabaseManager);
+ assertEquals(LeaderboardStatus.UPDATED, flatFileDatabaseManager.updateLeaderboards());
}
@Test
void testSaveUser() {
+ FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
//Make a Profile to save and check to see if it worked
UUID uuid = UUID.fromString("588fe472-1c82-4c4e-9aa1-7eefccb277e3");
String playerName = "nossr50";
@@ -168,15 +164,15 @@ class FlatFileDatabaseManagerTest {
//The above profile should be "zero" initialized
//Save the zero version and see if it looks correct
- assertNotNull(db);
- assertTrue(db.getUsersFile().exists()); //Users file should have been created from the above com.gmail.nossr50.database.FlatFileDatabaseManager.checkFileHealthAndStructure
- assertNotNull(db.getUsersFile());
+ assertNotNull(flatFileDatabaseManager);
+ assertTrue(flatFileDatabaseManager.getUsersFile().exists()); //Users file should have been created from the above com.gmail.nossr50.database.FlatFileDatabaseManager.checkFileHealthAndStructure
+ assertNotNull(flatFileDatabaseManager.getUsersFile());
- //The DB is empty at this point, add our user
- assertTrue(db.saveUser(testProfile)); //True means we saved the user
+ //The flatFileDatabaseManager is empty at this point, add our user
+ assertTrue(flatFileDatabaseManager.saveUser(testProfile)); //True means we saved the user
//Check for the empty profile
- PlayerProfile retrievedFromData = db.loadPlayerProfile(uuid);
+ PlayerProfile retrievedFromData = flatFileDatabaseManager.loadPlayerProfile(uuid);
assertTrue(retrievedFromData.isLoaded()); //PlayerProfile::isLoaded returns true if the data was created from the file, false if it wasn't found and a dummy profile was returned
assertEquals(uuid, retrievedFromData.getUniqueId());
assertEquals(playerName, retrievedFromData.getPlayerName());
@@ -187,9 +183,9 @@ class FlatFileDatabaseManagerTest {
String alteredName = "changedmyname";
PlayerProfile changedNameProfile = new PlayerProfile(alteredName, uuid, 0);
- assertTrue(db.saveUser(changedNameProfile)); //True means we saved the user
+ assertTrue(flatFileDatabaseManager.saveUser(changedNameProfile)); //True means we saved the user
- retrievedFromData = db.loadPlayerProfile(uuid);
+ retrievedFromData = flatFileDatabaseManager.loadPlayerProfile(uuid);
assertTrue(retrievedFromData.isLoaded()); //PlayerProfile::isLoaded returns true if the data was created from the file, false if it wasn't found and a dummy profile was returned
assertEquals(uuid, retrievedFromData.getUniqueId());
assertEquals(alteredName, retrievedFromData.getPlayerName());
@@ -198,49 +194,27 @@ class FlatFileDatabaseManagerTest {
@Test
void testAddedMissingLastLoginValues() {
File dbFile = prepareDatabaseTestResource(DB_MISSING_LAST_LOGIN);
-
- //This makes sure our private method is working before the tests run afterwards
- ArrayList dataFromFile = getSplitDataFromFile(dbFile);
- logger.info("File Path: "+ dbFile.getAbsolutePath());
- assertArrayEquals(LINE_TWO_FROM_MISSING_DB.split(":"), dataFromFile.get(1));
- assertEquals(dataFromFile.get(1)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR);
-
- db = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true);
- List flagsFound = db.checkFileHealthAndStructure();
+ FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true);
+ List flagsFound = flatFileDatabaseManager.checkFileHealthAndStructure();
assertNotNull(flagsFound);
assertTrue(flagsFound.contains(FlatFileDataFlag.LAST_LOGIN_SCHEMA_UPGRADE));
//Check for the fixed value
- PlayerProfile profile = db.loadPlayerProfile("nossr50");
+ PlayerProfile profile = flatFileDatabaseManager.loadPlayerProfile("nossr50");
assertEquals(-1, (long) profile.getLastLogin());
}
@Test
void testLoadByName() {
File healthyDB = prepareDatabaseTestResource(DB_HEALTHY);
-
- /*
- * We have established the files are in good order, so now for the actual testing
- */
-
- //This makes sure our private method is working before the tests run afterwards
- ArrayList dataFromFile = getSplitDataFromFile(healthyDB);
- logger.info("File Path: "+healthyDB.getAbsolutePath());
- assertArrayEquals(HEALTHY_DB_LINE_1.split(":"), dataFromFile.get(0));
- assertEquals(dataFromFile.get(0)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR);
-
- db = new FlatFileDatabaseManager(healthyDB, logger, PURGE_TIME, 0, true);
- List flagsFound = db.checkFileHealthAndStructure();
+ FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(healthyDB, logger, PURGE_TIME, 0, true);
+ List flagsFound = flatFileDatabaseManager.checkFileHealthAndStructure();
assertNull(flagsFound); //No flags should be found
- /*
- * Once the DB looks fine load the profile
- */
-
String playerName = "nossr50";
UUID uuid = UUID.fromString("588fe472-1c82-4c4e-9aa1-7eefccb277e3");
- PlayerProfile profile = db.loadPlayerProfile(playerName);
+ PlayerProfile profile = flatFileDatabaseManager.loadPlayerProfile(playerName);
testHealthyDataProfileValues(playerName, uuid, profile);
}
@@ -251,16 +225,16 @@ class FlatFileDatabaseManagerTest {
String playerName = "nossr50";
int newUserTestStartingLvl = 1337;
- db = new FlatFileDatabaseManager(new File(tempDir.getPath() + File.separator + TEST_FILE_NAME), logger, PURGE_TIME, newUserTestStartingLvl, true);
- db.checkFileHealthAndStructure();
+ var flatFileDatabaseManager = new FlatFileDatabaseManager(new File(tempDir.getPath() + File.separator + TEST_FILE_NAME), logger, PURGE_TIME, newUserTestStartingLvl, true);
+ flatFileDatabaseManager.checkFileHealthAndStructure();
- PlayerProfile playerProfile = db.newUser(playerName, uuid);
+ PlayerProfile playerProfile = flatFileDatabaseManager.newUser(playerName, uuid);
assertTrue(playerProfile.isLoaded());
assertEquals(playerName, playerProfile.getPlayerName());
assertEquals(uuid, playerProfile.getUniqueId());
- PlayerProfile retrievedFromDisk = db.loadPlayerProfile(uuid);
+ PlayerProfile retrievedFromDisk = flatFileDatabaseManager.loadPlayerProfile(uuid);
assertTrue(retrievedFromDisk.isLoaded());
assertEquals(playerName, retrievedFromDisk.getPlayerName());
assertEquals(uuid, retrievedFromDisk.getUniqueId());
@@ -270,11 +244,11 @@ class FlatFileDatabaseManagerTest {
checkNewUserValues(retrievedFromDisk, newUserTestStartingLvl);
//TODO: Should we do any dupe checking? Probably not needed as it would be caught on the next load
- db.newUser("disco", new UUID(3, 3));
- db.newUser("dingus", new UUID(3, 4));
- db.newUser("duped_dingus", new UUID(3, 4));
+ flatFileDatabaseManager.newUser("disco", new UUID(3, 3));
+ flatFileDatabaseManager.newUser("dingus", new UUID(3, 4));
+ flatFileDatabaseManager.newUser("duped_dingus", new UUID(3, 4));
- assertEquals(5, getSplitDataFromFile(db.getUsersFile()).size());
+ assertEquals(5, getSplitDataFromFile(flatFileDatabaseManager.getUsersFile()).size());
}
@Test
@@ -286,16 +260,16 @@ class FlatFileDatabaseManagerTest {
File file = prepareDatabaseTestResource(DB_HEALTHY); //Existing DB
int newUserTestStartingLvl = 1337;
- db = new FlatFileDatabaseManager(file, logger, PURGE_TIME, newUserTestStartingLvl, true);
- db.checkFileHealthAndStructure();
+ var flatFileDatabaseManager = new FlatFileDatabaseManager(file, logger, PURGE_TIME, newUserTestStartingLvl, true);
+ flatFileDatabaseManager.checkFileHealthAndStructure();
- PlayerProfile playerProfile = db.newUser(playerName, uuid);
+ PlayerProfile playerProfile = flatFileDatabaseManager.newUser(playerName, uuid);
assertTrue(playerProfile.isLoaded());
assertEquals(playerName, playerProfile.getPlayerName());
assertEquals(uuid, playerProfile.getUniqueId());
- PlayerProfile retrievedFromDisk = db.loadPlayerProfile(uuid);
+ PlayerProfile retrievedFromDisk = flatFileDatabaseManager.loadPlayerProfile(uuid);
assertTrue(retrievedFromDisk.isLoaded());
assertEquals(playerName, retrievedFromDisk.getPlayerName());
assertEquals(uuid, retrievedFromDisk.getUniqueId());
@@ -305,15 +279,15 @@ class FlatFileDatabaseManagerTest {
checkNewUserValues(retrievedFromDisk, newUserTestStartingLvl);
//TODO: Should we do any dupe checking? Probably not needed as it would be caught on the next load
- db.newUser("bidoof", new UUID(3, 3));
- db.newUser("derp", new UUID(3, 4));
- db.newUser("pizza", new UUID(3, 4));
+ flatFileDatabaseManager.newUser("bidoof", new UUID(3, 3));
+ flatFileDatabaseManager.newUser("derp", new UUID(3, 4));
+ flatFileDatabaseManager.newUser("pizza", new UUID(3, 4));
- assertEquals(7, getSplitDataFromFile(db.getUsersFile()).size());
+ assertEquals(7, getSplitDataFromFile(flatFileDatabaseManager.getUsersFile()).size());
- //Now we *fix* the DB and there should be one less
- db.checkFileHealthAndStructure();
- assertEquals(6, getSplitDataFromFile(db.getUsersFile()).size());
+ //Now we *fix* the flatFileDatabaseManager and there should be one less
+ flatFileDatabaseManager.checkFileHealthAndStructure();
+ assertEquals(6, getSplitDataFromFile(flatFileDatabaseManager.getUsersFile()).size());
}
private void checkNewUserValues(@NotNull PlayerProfile playerProfile, int startingLevel) {
@@ -338,71 +312,45 @@ class FlatFileDatabaseManagerTest {
@Test
void testLoadByUUID() {
File dbFile = prepareDatabaseTestResource(DB_HEALTHY);
-
- /*
- * We have established the files are in good order, so now for the actual testing
- */
-
- //This makes sure our private method is working before the tests run afterwards
- ArrayList dataFromFile = getSplitDataFromFile(dbFile);
- logger.info("File Path: " + dbFile.getAbsolutePath());
- assertArrayEquals(HEALTHY_DB_LINE_1.split(":"), dataFromFile.get(0));
- assertEquals(dataFromFile.get(0)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR);
-
- db = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true);
- List flagsFound = db.checkFileHealthAndStructure();
+ var flatFileDatabaseManager = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true);
+ List flagsFound = flatFileDatabaseManager.checkFileHealthAndStructure();
assertNull(flagsFound); //No flags should be found
/*
- * Once the DB looks fine load the profile
+ * Once the flatFileDatabaseManager looks fine load the profile
*/
String playerName = "nossr50";
UUID uuid = UUID.fromString("588fe472-1c82-4c4e-9aa1-7eefccb277e3");
- PlayerProfile profile1 = db.loadPlayerProfile(uuid);
+ PlayerProfile profile1 = flatFileDatabaseManager.loadPlayerProfile(uuid);
testHealthyDataProfileValues(playerName, uuid, profile1);
- assertFalse(db.loadPlayerProfile(new UUID(0, 1)).isLoaded()); //This profile should not exist and therefor will return unloaded
+ assertFalse(flatFileDatabaseManager.loadPlayerProfile(new UUID(0, 1)).isLoaded()); //This profile should not exist and therefor will return unloaded
}
@Test
void testLoadByUUIDAndName() {
File dbFile = prepareDatabaseTestResource(DB_HEALTHY);
-
- /*
- * We have established the files are in good order, so now for the actual testing
- */
-
- //This makes sure our private method is working before the tests run afterwards
- ArrayList dataFromFile = getSplitDataFromFile(dbFile);
- logger.info("File Path: " + dbFile.getAbsolutePath());
- assertArrayEquals(HEALTHY_DB_LINE_1.split(":"), dataFromFile.get(0));
- assertEquals(dataFromFile.get(0)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR);
-
- db = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true);
- List flagsFound = db.checkFileHealthAndStructure();
+ var flatFileDatabaseManager = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true);
+ List flagsFound = flatFileDatabaseManager.checkFileHealthAndStructure();
assertNull(flagsFound); //No flags should be found
- /*
- * Once the DB looks fine load the profile
- */
-
String playerName = "nossr50";
UUID uuid = UUID.fromString("588fe472-1c82-4c4e-9aa1-7eefccb277e3");
Player player = initMockPlayer(playerName, uuid);
- PlayerProfile profile1 = db.loadPlayerProfile(player);
+ PlayerProfile profile1 = flatFileDatabaseManager.loadPlayerProfile(player);
testHealthyDataProfileValues(playerName, uuid, profile1);
String updatedName = "updatedName";
Player updatedNamePlayer = initMockPlayer(updatedName, uuid);
- PlayerProfile updatedNameProfile = db.loadPlayerProfile(updatedNamePlayer);
+ PlayerProfile updatedNameProfile = flatFileDatabaseManager.loadPlayerProfile(updatedNamePlayer);
testHealthyDataProfileValues(updatedName, uuid, updatedNameProfile);
Player shouldNotExist = initMockPlayer("doesntexist", new UUID(0, 1));
- PlayerProfile profile3 = db.loadPlayerProfile(shouldNotExist);
+ PlayerProfile profile3 = flatFileDatabaseManager.loadPlayerProfile(shouldNotExist);
assertFalse(profile3.isLoaded());
}
@@ -484,6 +432,7 @@ class FlatFileDatabaseManagerTest {
case BLAST_MINING -> expectedBlastMiningCd;
case TRIDENTS_SUPER_ABILITY -> expectedTridentSuperCd;
case EXPLOSIVE_SHOT -> expectedExplosiveShotCd;
+ case MACES_SUPER_ABILITY -> expectedMacesSuperCd;
default -> throw new RuntimeException("Values not defined for super ability please add " +
"values for " + superAbilityType.toString() + " to the test");
};
@@ -491,165 +440,147 @@ class FlatFileDatabaseManagerTest {
}
private float getExpectedExperienceHealthyDBEntryOne(@NotNull PrimarySkillType primarySkillType) {
- switch(primarySkillType) {
- case ACROBATICS:
- return expectedExpAcrobatics;
- case ALCHEMY:
- return expectedExpAlchemy;
- case ARCHERY:
- return expectedExpArchery;
- case AXES:
- return expectedExpAxes;
- case CROSSBOWS:
- return expectedExpCrossbows;
- case EXCAVATION:
- return expectedExpExcavation;
- case FISHING:
- return expectedExpFishing;
- case HERBALISM:
- return expectedExpHerbalism;
- case MINING:
- return expectedExpMining;
- case REPAIR:
- return expectedExpRepair;
- case SALVAGE:
- case SMELTING:
- return 0;
- case SWORDS:
- return expectedExpSwords;
- case TAMING:
- return expectedExpTaming;
- case TRIDENTS:
- return expectedExpTridents;
- case UNARMED:
- return expectedExpUnarmed;
- case WOODCUTTING:
- return expectedExpWoodcutting;
- }
+ return switch (primarySkillType) {
+ case ACROBATICS -> expectedExpAcrobatics;
+ case ALCHEMY -> expectedExpAlchemy;
+ case ARCHERY -> expectedExpArchery;
+ case AXES -> expectedExpAxes;
+ case CROSSBOWS -> expectedExpCrossbows;
+ case EXCAVATION -> expectedExpExcavation;
+ case FISHING -> expectedExpFishing;
+ case HERBALISM -> expectedExpHerbalism;
+ case MINING -> expectedExpMining;
+ case REPAIR -> expectedExpRepair;
+ case SALVAGE, SMELTING -> 0;
+ case SWORDS -> expectedExpSwords;
+ case TAMING -> expectedExpTaming;
+ case TRIDENTS -> expectedExpTridents;
+ case UNARMED -> expectedExpUnarmed;
+ case WOODCUTTING -> expectedExpWoodcutting;
+ case MACES -> expectedExpMaces;
+ default ->
+ throw new RuntimeException("Values for skill not defined, please add values for " + primarySkillType.toString() + " to the test");
+ };
- throw new RuntimeException("Values for skill not defined, please add values for " + primarySkillType.toString() + " to the test");
}
private int getExpectedLevelHealthyDBEntryOne(@NotNull PrimarySkillType primarySkillType) {
- switch(primarySkillType) {
- case ACROBATICS:
- return expectedLvlAcrobatics;
- case ALCHEMY:
- return expectedLvlAlchemy;
- case ARCHERY:
- return expectedLvlArchery;
- case AXES:
- return expectedLvlAxes;
- case CROSSBOWS:
- return expectedLvlCrossbows;
- case EXCAVATION:
- return expectedLvlExcavation;
- case FISHING:
- return expectedLvlFishing;
- case HERBALISM:
- return expectedLvlHerbalism;
- case MINING:
- return expectedLvlMining;
- case REPAIR:
- return expectedLvlRepair;
- case SALVAGE:
- case SMELTING:
- return 0;
- case SWORDS:
- return expectedLvlSwords;
- case TAMING:
- return expectedLvlTaming;
- case TRIDENTS:
- return expectedLvlTridents;
- case UNARMED:
- return expectedLvlUnarmed;
- case WOODCUTTING:
- return expectedLvlWoodcutting;
- }
+ return switch (primarySkillType) {
+ case ACROBATICS -> expectedLvlAcrobatics;
+ case ALCHEMY -> expectedLvlAlchemy;
+ case ARCHERY -> expectedLvlArchery;
+ case AXES -> expectedLvlAxes;
+ case CROSSBOWS -> expectedLvlCrossbows;
+ case EXCAVATION -> expectedLvlExcavation;
+ case FISHING -> expectedLvlFishing;
+ case HERBALISM -> expectedLvlHerbalism;
+ case MINING -> expectedLvlMining;
+ case REPAIR -> expectedLvlRepair;
+ case SALVAGE, SMELTING -> 0;
+ case SWORDS -> expectedLvlSwords;
+ case TAMING -> expectedLvlTaming;
+ case TRIDENTS -> expectedLvlTridents;
+ case UNARMED -> expectedLvlUnarmed;
+ case WOODCUTTING -> expectedLvlWoodcutting;
+ case MACES -> expectedLvlMaces;
+ default ->
+ throw new RuntimeException("Values for skill not defined, please add values for " + primarySkillType.toString() + " to the test");
+ };
- throw new RuntimeException("Values for skill not defined, please add values for " + primarySkillType.toString() + " to the test");
}
@Test
void testOverwriteName() {
- overwriteDataAndCheckForFlag(db, duplicateNameDatabaseData, FlatFileDataFlag.DUPLICATE_NAME);
- ArrayList splitDataLines = getSplitDataFromFile(db.getUsersFile());
+ FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
+ overwriteDataAndCheckForFlag(flatFileDatabaseManager, duplicateNameDatabaseData, FlatFileDataFlag.DUPLICATE_NAME);
+ ArrayList splitDataLines = getSplitDataFromFile(flatFileDatabaseManager.getUsersFile());
assertNotEquals(splitDataLines.get(1)[0], splitDataLines.get(0)[0]); //Name comparison
}
@Test
void testDataNotFound() {
+ FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
//Save the zero version and see if it looks correct
- assertNotNull(db);
- assertTrue(db.getUsersFile().exists());
- assertNotNull(db.getUsersFile());
+ assertNotNull(flatFileDatabaseManager);
+ assertTrue(flatFileDatabaseManager.getUsersFile().exists());
+ assertNotNull(flatFileDatabaseManager.getUsersFile());
//Check for the "unloaded" profile
- PlayerProfile retrievedFromData = db.loadPlayerProfile("nossr50");
+ PlayerProfile retrievedFromData = flatFileDatabaseManager.loadPlayerProfile("nossr50");
assertFalse(retrievedFromData.isLoaded()); //PlayerProfile::isLoaded returns false if data doesn't exist for the user
}
@Test
void testPurgePowerlessUsers() {
- replaceDataInFile(db, normalDatabaseData);
- int purgeCount = db.purgePowerlessUsers();
+ FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
+ replaceDataInFile(flatFileDatabaseManager, normalDatabaseData);
+ int purgeCount = flatFileDatabaseManager.purgePowerlessUsers();
assertEquals(purgeCount, 1); //1 User should have been purged
}
@Test
void testCheckFileHealthAndStructure() {
- replaceDataInFile(db, badDatabaseData);
+ FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
+ replaceDataInFile(flatFileDatabaseManager, badDatabaseData);
- List dataFlags = db.checkFileHealthAndStructure();
+ List dataFlags = flatFileDatabaseManager.checkFileHealthAndStructure();
assertNotNull(dataFlags);
assertNotEquals(dataFlags.size(), 0);
}
@Test
void testFindFixableDuplicateNames() {
- overwriteDataAndCheckForFlag(db, duplicateNameDatabaseData, FlatFileDataFlag.DUPLICATE_NAME);
+ FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
+ overwriteDataAndCheckForFlag(flatFileDatabaseManager, duplicateNameDatabaseData, FlatFileDataFlag.DUPLICATE_NAME);
}
@Test
void testFindDuplicateUUIDs() {
- overwriteDataAndCheckForFlag(db, duplicateUUIDDatabaseData, FlatFileDataFlag.DUPLICATE_UUID);
+ FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
+ overwriteDataAndCheckForFlag(flatFileDatabaseManager, duplicateUUIDDatabaseData, FlatFileDataFlag.DUPLICATE_UUID);
}
@Test()
void findBadUUIDData() {
- overwriteDataAndCheckForFlag(db, badUUIDDatabaseData, FlatFileDataFlag.BAD_UUID_DATA);
+ FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
+ overwriteDataAndCheckForFlag(flatFileDatabaseManager, badUUIDDatabaseData, FlatFileDataFlag.BAD_UUID_DATA);
}
@Test
void testFindCorruptData() {
- overwriteDataAndCheckForFlag(db, corruptDatabaseData, FlatFileDataFlag.CORRUPTED_OR_UNRECOGNIZABLE);
+ FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
+ overwriteDataAndCheckForFlag(flatFileDatabaseManager, corruptDatabaseData, FlatFileDataFlag.CORRUPTED_OR_UNRECOGNIZABLE);
}
@Test
void testFindEmptyNames() {
- overwriteDataAndCheckForFlag(db, emptyNameDatabaseData, FlatFileDataFlag.MISSING_NAME);
+ FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
+ overwriteDataAndCheckForFlag(flatFileDatabaseManager, emptyNameDatabaseData, FlatFileDataFlag.MISSING_NAME);
}
@Test
void testFindBadValues() {
- overwriteDataAndCheckForFlag(db, badDatabaseData, FlatFileDataFlag.BAD_VALUES);
+ FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
+ overwriteDataAndCheckForFlag(flatFileDatabaseManager, badDatabaseData, FlatFileDataFlag.BAD_VALUES);
}
@Test
void testFindOutdatedData() {
- overwriteDataAndCheckForFlag(db, outdatedDatabaseData, FlatFileDataFlag.INCOMPLETE);
+ FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
+ overwriteDataAndCheckForFlag(flatFileDatabaseManager, outdatedDatabaseData, FlatFileDataFlag.INCOMPLETE);
}
@Test
void testGetDatabaseType() {
- assertNotNull(db);
- assertEquals(db.getDatabaseType(), DatabaseType.FLATFILE);
+ FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
+ assertNotNull(flatFileDatabaseManager);
+ assertEquals(flatFileDatabaseManager.getDatabaseType(), DatabaseType.FLATFILE);
}
@Test
void testReadRank() {
//This is an empty DB
- assertNotNull(db);
+ FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
String rankBoyName = "rankBoy";
UUID rankBoyUUID = new UUID(1337, 1337);
String rankGirlName = "rankGirl";
@@ -658,9 +589,9 @@ class FlatFileDatabaseManagerTest {
PlayerProfile rankGirlProfile = addPlayerProfileWithLevelsAndSave(rankGirlName, rankGirlUUID, 100); //Rank 1
PlayerProfile rankBoyProfile = addPlayerProfileWithLevelsAndSave(rankBoyName, rankBoyUUID, 10); //Rank 2
- assertEquals(LeaderboardStatus.UPDATED, db.updateLeaderboards());
- Map rankGirlPositions = db.readRank(rankGirlName);
- Map rankBoyPositions = db.readRank(rankBoyName);
+ assertEquals(LeaderboardStatus.UPDATED, flatFileDatabaseManager.updateLeaderboards());
+ Map rankGirlPositions = flatFileDatabaseManager.readRank(rankGirlName);
+ Map rankBoyPositions = flatFileDatabaseManager.readRank(rankBoyName);
for(PrimarySkillType primarySkillType : PrimarySkillType.values()) {
if(primarySkillType.isChildSkill()) {
@@ -672,8 +603,8 @@ class FlatFileDatabaseManagerTest {
}
}
- assertEquals(1, db.readRank(rankGirlName).get(null)); //Girl should be position 1
- assertEquals(2, db.readRank(rankBoyName).get(null)); //Boy should be position 2
+ assertEquals(1, flatFileDatabaseManager.readRank(rankGirlName).get(null)); //Girl should be position 1
+ assertEquals(2, flatFileDatabaseManager.readRank(rankBoyName).get(null)); //Boy should be position 2
}
@Test
@@ -741,11 +672,11 @@ class FlatFileDatabaseManagerTest {
}
private @NotNull PlayerProfile addPlayerProfileWithLevelsAndSave(String playerName, UUID uuid, int levels) {
- assertNotNull(db);
- assertFalse(db.loadPlayerProfile(uuid).isLoaded());
+ FlatFileDatabaseManager flatFileDatabaseManager = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
+ assertFalse(flatFileDatabaseManager.loadPlayerProfile(uuid).isLoaded());
- db.newUser(playerName, uuid);
- PlayerProfile leveledProfile = db.loadPlayerProfile(uuid);
+ flatFileDatabaseManager.newUser(playerName, uuid);
+ PlayerProfile leveledProfile = flatFileDatabaseManager.loadPlayerProfile(uuid);
assertTrue(leveledProfile.isLoaded());
assertEquals(playerName, leveledProfile.getPlayerName());
@@ -758,8 +689,8 @@ class FlatFileDatabaseManagerTest {
leveledProfile.modifySkill(primarySkillType, levels); //TODO: This method also resets XP, not cool
}
- db.saveUser(leveledProfile);
- leveledProfile = db.loadPlayerProfile(uuid);
+ flatFileDatabaseManager.saveUser(leveledProfile);
+ leveledProfile = flatFileDatabaseManager.loadPlayerProfile(uuid);
for(PrimarySkillType primarySkillType : PrimarySkillType.values()) {
if(SkillTools.isChildSkill(primarySkillType)) {
diff --git a/src/test/java/com/gmail/nossr50/util/PotionUtilTest.java b/src/test/java/com/gmail/nossr50/util/PotionUtilTest.java
new file mode 100644
index 000000000..8b01720f7
--- /dev/null
+++ b/src/test/java/com/gmail/nossr50/util/PotionUtilTest.java
@@ -0,0 +1,51 @@
+package com.gmail.nossr50.util;
+
+import org.bukkit.potion.PotionType;
+import org.junit.jupiter.api.Test;
+
+import static com.gmail.nossr50.util.PotionUtil.convertLegacyNames;
+import static com.gmail.nossr50.util.PotionUtil.matchPotionType;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class PotionUtilTest {
+
+ @Test
+ void testDisplay() {
+// System.out.println("\n");
+// System.out.println("\n");
+// System.out.println("\n");
+// System.out.println("\n");
+// for(var s : PotionType.values()) {
+// System.out.println("PotionType.getKey().getKey(): " + s.getKey().getKey());
+// System.out.println("PotionType.name(): " + s.name());
+// System.out.println("PotionType.toString():" + s.toString());
+// System.out.println("\n");
+// }
+ }
+
+ @Test
+ void testMatchPotionType() {
+ String potionTypeStr = "UNCRAFTABLE";
+ PotionType potionType = matchPotionType(potionTypeStr, false, false);
+ assertEquals(PotionType.WATER, potionType);
+
+ String potionTypeStr2 = "NIGHT_VISION";
+ PotionType potionType2 = matchPotionType(potionTypeStr2, false, false);
+ assertEquals(PotionType.NIGHT_VISION, potionType2);
+
+ String nightVisionLong = "NIGHT_VISION";
+ PotionType potionType3 = matchPotionType(nightVisionLong, false, true);
+ assertEquals(PotionType.LONG_NIGHT_VISION, potionType3);
+
+ nightVisionLong = "LONG_NIGHT_VISION";
+ potionType3 = matchPotionType(nightVisionLong, false, true);
+ assertEquals(PotionType.LONG_NIGHT_VISION, potionType3);
+ }
+
+ @Test
+ void testConvertLegacyNames() {
+ final String potionTypeStr = "UNCRAFTABLE";
+ final String converted = convertLegacyNames(potionTypeStr);
+ assertEquals("WATER", converted);
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/healthydb.users b/src/test/resources/healthydb.users
index 79a2c7e70..c2561b38d 100644
--- a/src/test/resources/healthydb.users
+++ b/src/test/resources/healthydb.users
@@ -1,3 +1,3 @@
-nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:IGNORED:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999:2020:140:14:150:15:1111:2222:3333:
-mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:3030:0:0:0:0:0:0:0:
-powerless:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:1337:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:5:1600906906:4040:0:0:0:0:0:0:0:
\ No newline at end of file
+nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:IGNORED:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999:2020:140:14:150:15:1111:2222:3333:160:16:4444:
+mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:3030:0:0:0:0:0:0:0:0:0:0:
+powerless:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:1337:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:5:1600906906:4040:0:0:0:0:0:0:0:0:0:0:
\ No newline at end of file