From a6841366e130078c50a814937e43c75244dbb853 Mon Sep 17 00:00:00 2001 From: njsharpe Date: Tue, 8 Feb 2022 23:00:19 -0500 Subject: [PATCH] Refactor & expand utilities. Add fake enchantment for ItemBuilder --- .../fatcat/utilities/UtilitiesPlugin.java | 13 +- .../utilities/utility/DummyEnchantment.java | 82 ++++++++++++ .../fatcat/utilities/utility/ItemBuilder.java | 20 ++- .../fatcat/utilities/utility/NumberUtil.java | 69 ++++++++++ .../fatcat/utilities/utility/StringUtil.java | 125 ++++++++++++++++++ .../fatcat/utilities/utility/Utility.java | 70 ---------- 6 files changed, 297 insertions(+), 82 deletions(-) create mode 100644 src/main/java/memecat/fatcat/utilities/utility/DummyEnchantment.java create mode 100644 src/main/java/memecat/fatcat/utilities/utility/NumberUtil.java create mode 100644 src/main/java/memecat/fatcat/utilities/utility/StringUtil.java delete mode 100644 src/main/java/memecat/fatcat/utilities/utility/Utility.java diff --git a/src/main/java/memecat/fatcat/utilities/UtilitiesPlugin.java b/src/main/java/memecat/fatcat/utilities/UtilitiesPlugin.java index 3818279..8d9b486 100644 --- a/src/main/java/memecat/fatcat/utilities/UtilitiesPlugin.java +++ b/src/main/java/memecat/fatcat/utilities/UtilitiesPlugin.java @@ -2,10 +2,13 @@ import com.google.common.base.Preconditions; import memecat.fatcat.utilities.menu.MenuManager; +import memecat.fatcat.utilities.utility.DummyEnchantment; +import memecat.fatcat.utilities.utility.StringUtil; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import javax.annotation.Nonnull; +import java.util.ArrayList; import java.util.Optional; /** @@ -19,6 +22,7 @@ public class UtilitiesPlugin extends JavaPlugin { @Override public void onEnable() { instance = this; + DummyEnchantment.register(); } @Override @@ -59,11 +63,10 @@ public static Plugin checkProvider(@Nonnull Plugin provider) { */ @Nonnull public static MenuManager getMenuManager(@Nonnull Plugin provider) { - if (instance == null) { - return menuManager == null ? menuManager = new MenuManager(provider) : menuManager.provide(provider); - } - - return menuManager == null ? menuManager = new MenuManager(instance).provide(provider) : menuManager.provide(provider); + menuManager = (menuManager == null) + ? new MenuManager(instance == null ? provider : instance) + : menuManager.provide(provider); + return menuManager; } /** diff --git a/src/main/java/memecat/fatcat/utilities/utility/DummyEnchantment.java b/src/main/java/memecat/fatcat/utilities/utility/DummyEnchantment.java new file mode 100644 index 0000000..5705ab7 --- /dev/null +++ b/src/main/java/memecat/fatcat/utilities/utility/DummyEnchantment.java @@ -0,0 +1,82 @@ +package memecat.fatcat.utilities.utility; + +import com.google.common.base.Preconditions; +import memecat.fatcat.utilities.UtilitiesPlugin; +import org.bukkit.NamespacedKey; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.EnchantmentTarget; +import org.bukkit.inventory.ItemStack; + +import javax.annotation.Nonnull; +import java.lang.reflect.Field; +import java.util.Optional; + +public class DummyEnchantment extends Enchantment { + + public DummyEnchantment() { + super(new NamespacedKey(getPlugin(), "dummy")); + } + + @Override + @Nonnull + public String getName() { + return ""; + } + + @Override + public int getMaxLevel() { + return 0; + } + + @Override + public int getStartLevel() { + return 0; + } + + @Override + @Nonnull + public EnchantmentTarget getItemTarget() { + return null; + } + + @Override + public boolean isTreasure() { + return false; + } + + @Override + public boolean isCursed() { + return false; + } + + @Override + public boolean conflictsWith(@Nonnull Enchantment enchantment) { + return false; + } + + @Override + public boolean canEnchantItem(@Nonnull ItemStack itemStack) { + return true; + } + + public static void register() { + Resolver resolver = new Resolver(Enchantment.class); + Optional optional = resolver.resolveField("acceptingNew"); + try { + Preconditions.checkArgument(optional.isPresent(), "Cannot register new enchantment from invalid field."); + Field field = optional.get(); + field.set(null, true); + Enchantment.registerEnchantment(new DummyEnchantment()); + } catch (Exception ignore) { + } finally { + Enchantment.stopAcceptingRegistrations(); + } + } + + private static UtilitiesPlugin getPlugin() { + Optional instance = UtilitiesPlugin.getInstance(); + Preconditions.checkArgument(instance.isPresent(), "Cannot initialize enchantment with null plugin reference"); + return instance.get(); + } + +} diff --git a/src/main/java/memecat/fatcat/utilities/utility/ItemBuilder.java b/src/main/java/memecat/fatcat/utilities/utility/ItemBuilder.java index 6428da2..29e0db0 100644 --- a/src/main/java/memecat/fatcat/utilities/utility/ItemBuilder.java +++ b/src/main/java/memecat/fatcat/utilities/utility/ItemBuilder.java @@ -10,12 +10,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.Optional; +import java.util.*; import java.util.function.Consumer; /** @@ -178,6 +173,17 @@ public ItemBuilder removeEnchantments(@Nonnull Enchantment... enchantments) { return this; } + /** + * Adds a dummy enchantment to give the {@link ItemStack} an enchanted glow. + * + * @return This instance, useful for chaining + */ + @Nonnull + public ItemBuilder setEnchanted() { + this.itemStack.addUnsafeEnchantment(new DummyEnchantment(), 1); + return this; + } + /** * Appends new lines of lore at the given index of the {@link ItemStack}'s lore from a given list. * @@ -215,7 +221,7 @@ public ItemBuilder loreAt(@Nullable String line, int... indexes) { } List lore = this.getItemMeta().map(ItemMeta::getLore).orElse(null); - lore = lore == null || lore.isEmpty() ? new ArrayList<>(Utility.max(indexes) + 1) : lore; + lore = lore == null || lore.isEmpty() ? new ArrayList<>(NumberUtil.max(indexes) + 1) : lore; for (int index : indexes) { lore.set(index, line); diff --git a/src/main/java/memecat/fatcat/utilities/utility/NumberUtil.java b/src/main/java/memecat/fatcat/utilities/utility/NumberUtil.java new file mode 100644 index 0000000..b0e908e --- /dev/null +++ b/src/main/java/memecat/fatcat/utilities/utility/NumberUtil.java @@ -0,0 +1,69 @@ +package memecat.fatcat.utilities.utility; + +import javax.annotation.Nonnull; + +public class NumberUtil { + + /** + * Returns the greatest integer from a given {@link Iterable} object of {@link Integer}s by using simple code for + * performance reasons. + * + * @param numbers An {@link Iterable} object of {@link Integer}s + * @return Greatest integer from the given array + * @throws IllegalArgumentException If the numbers argument is null + */ + public static int max(@Nonnull Iterable numbers) { + int max = Integer.MIN_VALUE; + for(int number : numbers) { + max = Math.max(number, max); + } + return max; + } + + /** + * Returns the greatest integer from a given array of integers by using simple code for performance reasons. + * + * @param numbers Array of integers + * @return Greatest integer from the given array + * @throws IllegalArgumentException If the numbers argument is null + */ + public static int max(int... numbers) { + int max = Integer.MIN_VALUE; + for(int number : numbers) { + max = Math.max(number, max); + } + return max; + } + + /** + * Returns the smallest integer from a given {@link Iterable} object of {@link Integer}s by using simple code for + * performance reasons. + * + * @param numbers An {@link Iterable} object of {@link Integer}s + * @return Smallest integer from the given array + * @throws IllegalArgumentException If the numbers argument is null + */ + public static int min(@Nonnull Iterable numbers) { + int min = Integer.MAX_VALUE; + for(int number : numbers) { + min = Math.min(number, min); + } + return min; + } + + /** + * Returns the smallest integer from a given array of integers by using simple code for performance reasons. + * + * @param numbers Array of integers + * @return Smallest integer from the given array + * @throws IllegalArgumentException If the numbers argument is null + */ + public static int min(int... numbers) { + int min = Integer.MAX_VALUE; + for(int number : numbers) { + min = Math.min(number, min); + } + return min; + } + +} diff --git a/src/main/java/memecat/fatcat/utilities/utility/StringUtil.java b/src/main/java/memecat/fatcat/utilities/utility/StringUtil.java new file mode 100644 index 0000000..a72c937 --- /dev/null +++ b/src/main/java/memecat/fatcat/utilities/utility/StringUtil.java @@ -0,0 +1,125 @@ +package memecat.fatcat.utilities.utility; + +import org.bukkit.ChatColor; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.text.Format; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * A utility class that contains static helper methods for Strings. + */ +public class StringUtil { + + /** + * Returns the input {@link String} with its first letter capitalized + * + * @param input Nullable {@link String} to capitalize + * @return Input {@link String} argument with it's first letter capitalized + */ + @Nullable + public static String capitalize(@Nullable String input) { + return input == null || input.isEmpty() ? input : Character.toUpperCase(input.charAt(0)) + input.substring(1); + } + + /** + * Returns the possessive form of the input {@link String} + * + * @param input Nullable {@link String} to make possessive + * @param sCase {@link String} to append to the input in the case the input does not end in {@code s} + * @param noneCase {@link String} to append to the input in the case the input does end in {@code s} + * @return Input {@link String} argument's possessive form + */ + @Nullable + public static String possessive(@Nullable String input, @Nonnull String sCase, @Nonnull String noneCase) { + return input == null ? null : input.concat(input.endsWith("s") ? noneCase : sCase); + } + + /** + * Returns the possessive form of the input {@link String} + * + * @param input Nullable {@link String} to make possessive + * @return Input {@link String} argument's possessive form + */ + @Nullable + public static String possessive(@Nullable String input) { + return possessive(input, "'s", "'"); + } + + /** + * Returns the input {@link String} with each word's first letter capitalized + * + * @param input Nullable {@link String} to capitalize + * @return Input {@link String} argument with each first letter capitalized + */ + @Nullable + public static String toTitleCase(String input) { + final String delimiter = " "; + return input == null ? null : Arrays.stream(input.split(delimiter)) + .map(StringUtil::capitalize) + .collect(Collectors.joining(delimiter)); + } + + /** + * Returns a translated input {@link String} for use with {@code &} to represent colors + * + * @param input Nullable {@link String} to translate + * @return Translated input {@link String} argument + */ + @Nullable + public static String format(@Nullable String input) { + return input == null ? null : ChatColor.translateAlternateColorCodes('&', input); + } + + /** + * Returns a translated input {@link String} for use with {@code &} to represent colors + * + * @param input Nullable {@link String} to translate + * @param args Nullable {@link Object} array to format the input {@link String} + * @return Translated input {@link String} argument + */ + @Nullable + public static String format(@Nullable String input, @Nullable Object... args) { + // To satisfy String.format(...) the input must not be null. + return input == null ? null : format(String.format(input, args)); + } + + /** + * Returns a translated {@link List} for use with {@code &} to represent colors + * + * @param input Nullable {@link List} to translate + * @return Translated input {@link List} argument + */ + @Nullable + public static List format(@Nullable List input) { + return input == null ? null : input.stream().map(StringUtil::format).collect(Collectors.toList()); + } + + /** + * Returns a {@link List} from the input {@link String} using the delimiter provided + * + * @param input Nullable {@link String} to transform + * @param delimiter {@link Character} to split on + * @return {@link List} from the input {@link String} argument + */ + @Nullable + public static List toList(@Nullable String input, char delimiter) { + return toList(input, String.valueOf(delimiter)); + } + + /** + * Returns a {@link List} from the input {@link String} using the delimiter provided + * + * @param input Nullable {@link String} to transform + * @param delimiter {@link String} to split on + * @return {@link List} from the input {@link String} argument + */ + @Nullable + public static List toList(@Nullable String input, String delimiter) { + return input == null ? null : Arrays.stream(input.split(delimiter)).collect(Collectors.toList()); + } + +} \ No newline at end of file diff --git a/src/main/java/memecat/fatcat/utilities/utility/Utility.java b/src/main/java/memecat/fatcat/utilities/utility/Utility.java deleted file mode 100644 index 07f327c..0000000 --- a/src/main/java/memecat/fatcat/utilities/utility/Utility.java +++ /dev/null @@ -1,70 +0,0 @@ -package memecat.fatcat.utilities.utility; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -/** - * An utility class that contains static methods. - */ -public class Utility { - - /** - * Returns the greatest integer from a given {@link Iterable} object of {@link Integer}s by using simple code for - * performance reasons. - * - * @param numbers An {@link Iterable} object of {@link Integer}s - * @return Greatest integer from the given array - * @throws IllegalArgumentException If the numbers argument is null - */ - public static int max(@Nonnull Iterable numbers) { - int max = Integer.MIN_VALUE; - - for (int number : numbers) { - if (number > max) { - max = number; - } - } - - return max; - } - - /** - * Returns the input {@link String} with it's first letter capitalized. - * - * @param input Nullable {@link String} to capitalize - * @return Input {@link String} argument with it's first letter capitalized - */ - @Nullable - public static String capitalize(@Nullable String input) { - return input == null || input.isEmpty() ? input : Character.toUpperCase(input.charAt(0)) + input.substring(1); - } - - @Nullable - public static String possessive(@Nullable String input, @Nonnull String sCase, @Nonnull String noneCase) { - return input == null ? null : input.concat(input.endsWith("s") ? noneCase : sCase); - } - - @Nullable - public static String possessive(@Nullable String input) { - return possessive(input, "'s", "'"); - } - - /** - * Returns the greatest integer from a given array of integers by using simple code for performance reasons. - * - * @param numbers Array of integers - * @return Greatest integer from the given array - * @throws IllegalArgumentException If the numbers argument is null - */ - public static int max(int... numbers) { - int max = Integer.MIN_VALUE; - - for (int number : numbers) { - if (number > max) { - max = number; - } - } - - return max; - } -} \ No newline at end of file