diff --git a/src/main/java/net/knarcraft/knarlib/util/MaterialHelper.java b/src/main/java/net/knarcraft/knarlib/util/MaterialHelper.java new file mode 100644 index 0000000..3723e62 --- /dev/null +++ b/src/main/java/net/knarcraft/knarlib/util/MaterialHelper.java @@ -0,0 +1,98 @@ +package net.knarcraft.knarlib.util; + +import net.knarcraft.knarlib.formatting.StringFormatter; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.Tag; +import org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * A helper class for dealing with and parsing materials + */ +@SuppressWarnings("unused") +public final class MaterialHelper { + + private MaterialHelper() { + + } + + /** + * Loads the materials specified in the given list + * + * @param materials

The list of material strings to load

+ * @param logger

The logger to use for logging parsing errors

+ */ + public static @NotNull Set loadMaterialList(@NotNull List materials, @NotNull Logger logger) { + Set parsedMaterials = new HashSet<>(); + for (Object value : materials) { + if (!(value instanceof String string)) { + continue; + } + + parsedMaterials.addAll(loadMaterialString(string, logger)); + } + return parsedMaterials; + } + + /** + * Parses a string representing a material or a material tag + * + * @param materialString

The material string to parse

+ * @param logger

The logger to use for logging parsing errors

+ * @return

The materials defined by the material string, or an empty list if none were found

+ */ + public static @NotNull Set loadMaterialString(@NotNull String materialString, @NotNull Logger logger) { + Set parsedMaterials = new HashSet<>(); + // Try to parse a material tag first + if (parseMaterialTag(parsedMaterials, materialString, logger)) { + return parsedMaterials; + } + + // Try to parse a material name + Material matched = Material.matchMaterial(materialString); + if (matched != null) { + parsedMaterials.add(matched); + } else { + logger.log(Level.WARNING, StringFormatter.replacePlaceholder("Unable to parse material: {material}", + "{material}", materialString)); + } + return parsedMaterials; + } + + /** + * Tries to parse the material tag in the specified material name + * + * @param targetSet

The set all parsed materials should be added to

+ * @param materialName

The material name that might be a material tag

+ * @param logger

The logger to use for logging parsing errors

+ * @return

True if a tag was found

+ */ + private static boolean parseMaterialTag(@NotNull Set targetSet, @NotNull String materialName, + @NotNull Logger logger) { + Pattern pattern = Pattern.compile("^\\+([a-zA-Z_]+)"); + Matcher matcher = pattern.matcher(materialName); + if (matcher.find()) { + // The material is a material tag + Tag tag = Bukkit.getTag(Tag.REGISTRY_BLOCKS, NamespacedKey.minecraft( + matcher.group(1).toLowerCase()), Material.class); + if (tag != null) { + targetSet.addAll(tag.getValues()); + } else { + logger.log(Level.WARNING, StringFormatter.replacePlaceholder( + "Unable to parse material: {material}", "{material}", materialName)); + } + return true; + } + return false; + } + +}