KnarLib/src/main/java/net/knarcraft/knarlib/util/MaterialHelper.java
EpicKnarvik97 5c3c3045eb
All checks were successful
EpicKnarvik97/KnarLib/pipeline/head This commit looks good
KnarCraft/KnarLib/pipeline/head This commit looks good
Adds method for parsing a material without tag support
2023-07-10 13:15:23 +02:00

122 lines
4.7 KiB
Java

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 <p>The list of material strings to load</p>
* @param tagPrefix <p>The prefix differentiating a tag from a material</p>
* @param logger <p>The logger to use for logging parsing errors</p>
*/
public static @NotNull Set<Material> loadMaterialList(@NotNull List<?> materials, @NotNull String tagPrefix,
@NotNull Logger logger) {
Set<Material> 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 <p>The material string to parse</p>
* @param tagPrefix <p>The prefix differentiating a tag from a material</p>
* @param logger <p>The logger to use for logging parsing errors</p>
* @return <p>The materials defined by the material string, or an empty list if none were found</p>
*/
public static @NotNull Set<Material> loadMaterialString(@NotNull String materialString, @NotNull String tagPrefix,
@NotNull Logger logger) {
Set<Material> 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 <p>The material string to parse</p>
* @param logger <p>The logger to use for logging parsing errors</p>
* @return <p>The materials defined by the material string, or an empty list if none were found</p>
*/
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 <p>The set all parsed materials should be added to</p>
* @param materialName <p>The material name that might be a material tag</p>
* @param tagPrefix <p>The prefix differentiating a tag from a material</p>
* @param logger <p>The logger to use for logging parsing errors</p>
* @return <p>True if a tag was found</p>
*/
private static boolean parseMaterialTag(@NotNull Set<Material> 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<Material> 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;
}
}