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 org.jetbrains.annotations.Nullable; 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 tagPrefix

The prefix differentiating a tag from a material

* @param logger

The logger to use for logging parsing errors

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

The material string to parse

* @param tagPrefix

The prefix differentiating a tag from a material

* @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 String tagPrefix, @NotNull Logger logger) { Set parsedMaterials = new HashSet<>(); // Try to parse a material tag first if (parseMaterialTag(parsedMaterials, materialString, tagPrefix, logger)) { return parsedMaterials; } // Try to parse a material name Material matched = loadMaterialString(materialString, logger); if (matched != null) { parsedMaterials.add(matched); } return parsedMaterials; } /** * Parses a string representing a material * * @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 @Nullable Material loadMaterialString(@NotNull String materialString, @NotNull Logger logger) { // Try to parse a material name Material matched = Material.matchMaterial(materialString.replace("-", "_")); if (matched != null) { return matched; } else { logger.log(Level.WARNING, StringFormatter.replacePlaceholder("Unable to parse material: {material}", "{material}", materialString)); return null; } } /** * 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 tagPrefix

The prefix differentiating a tag from a material

* @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 String tagPrefix, @NotNull Logger logger) { Pattern pattern = Pattern.compile("^" + Pattern.quote(tagPrefix) + "([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; } }