mirror of
https://github.com/StarWishsama/Slimefun4.git
synced 2024-09-20 11:45:51 +00:00
Added documentation
This commit is contained in:
parent
06498e3f63
commit
b09c4af900
@ -13,30 +13,85 @@ import org.bukkit.Tag;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationException;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.CropGrowthAccelerator;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.ClimbingPick;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.ExplosiveShovel;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.PickaxeOfTheSeeker;
|
||||
|
||||
/**
|
||||
* This enum contains various implementations of the {@link Tag} interface.
|
||||
* Most of them serve some purpose within Slimefun's implementation, some are just pure
|
||||
* extensions of the default Minecraft tags.
|
||||
* The actual tag files are located in the {@literal /src/main/resources/tags} directory
|
||||
* and follow Minecraft's tags.json format.
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
*
|
||||
*/
|
||||
public enum SlimefunTag implements Tag<Material> {
|
||||
|
||||
/**
|
||||
* Materials which are sensitive to break.
|
||||
* Things like Saplings or Pressure plates which break as well when you break
|
||||
* the block beneath them.
|
||||
*/
|
||||
SENSITIVE_MATERIALS,
|
||||
|
||||
// Expanding upon Minecraft's tags:
|
||||
|
||||
/**
|
||||
* Minecraft ores.
|
||||
*/
|
||||
ORES,
|
||||
|
||||
/**
|
||||
* All terracotta variants, does not include glazed terracotta.
|
||||
*/
|
||||
TERRACOTTA,
|
||||
|
||||
/**
|
||||
* All ice variants, normal, packed, blue and whatever else there is.
|
||||
*/
|
||||
ICE_VARIANTS,
|
||||
|
||||
/**
|
||||
* All stone variants, normal, andesite, diorite, granite and whatever else may come.
|
||||
*/
|
||||
STONE_VARIANTS,
|
||||
|
||||
/**
|
||||
* All variants of concrete powder.
|
||||
* Can you believe there is no tag for this already?
|
||||
*/
|
||||
CONCRETE_POWDERS,
|
||||
|
||||
// Actual Slimefun tags:
|
||||
|
||||
/**
|
||||
* All materials which the {@link ExplosiveShovel} can break.
|
||||
*/
|
||||
EXPLOSIVE_SHOVEL_BLOCKS,
|
||||
|
||||
/**
|
||||
* All materials (ores) which the {@link PickaxeOfTheSeeker} recognizes.
|
||||
*/
|
||||
PICKAXE_OF_VEIN_MINING_BLOCKS,
|
||||
|
||||
/**
|
||||
* All materials (crops) which the {@link CropGrowthAccelerator} will recognize.
|
||||
*/
|
||||
CROP_GROWTH_ACCELERATOR_BLOCKS,
|
||||
|
||||
/**
|
||||
* All materials which the {@link ClimbingPick} is able to climb.
|
||||
*/
|
||||
CLIMBING_PICK_SURFACES;
|
||||
|
||||
private final NamespacedKey key;
|
||||
private final Set<Material> includedMaterials = new HashSet<>();
|
||||
private final Set<Tag<Material>> additionalTags = new HashSet<>();
|
||||
|
||||
/**
|
||||
* This constructs a new {@link SlimefunTag}.
|
||||
* The {@link NamespacedKey} will be automatically inferred using
|
||||
* {@link SlimefunPlugin} and {@link #name()}.
|
||||
*/
|
||||
SlimefunTag() {
|
||||
key = new NamespacedKey(SlimefunPlugin.instance(), name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
@ -48,7 +103,7 @@ public enum SlimefunTag implements Tag<Material> {
|
||||
* This is thrown whenever a {@link SlimefunTag} could not be parsed properly
|
||||
*/
|
||||
public void reload() throws TagMisconfigurationException {
|
||||
new TagParser(this).parse((materials, tags) -> {
|
||||
new TagParser(this).parse(this, (materials, tags) -> {
|
||||
this.includedMaterials.clear();
|
||||
this.includedMaterials.addAll(materials);
|
||||
|
||||
@ -98,6 +153,14 @@ public enum SlimefunTag implements Tag<Material> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns a {@link Set} of {@link Tag Tags} which are children of this {@link SlimefunTag},
|
||||
* these can be other {@link SlimefunTag SlimefunTags} or regular {@link Tag Tags}.
|
||||
*
|
||||
* <strong>The returned {@link Set} is immutable</strong>
|
||||
*
|
||||
* @return An immutable {@link Set} of all sub tags.
|
||||
*/
|
||||
@Nonnull
|
||||
public Set<Tag<Material>> getSubTags() {
|
||||
return Collections.unmodifiableSet(additionalTags);
|
||||
|
@ -13,6 +13,7 @@ import java.util.stream.Collectors;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.Material;
|
||||
@ -30,22 +31,69 @@ import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationExce
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
|
||||
|
||||
class TagParser implements Keyed {
|
||||
/**
|
||||
* The {@link TagParser} is responsible for parsing a JSON input into a {@link SlimefunTag}.
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
*
|
||||
*/
|
||||
public class TagParser implements Keyed {
|
||||
|
||||
private final NamespacedKey key;
|
||||
|
||||
TagParser(@Nonnull SlimefunTag tag) {
|
||||
this.key = tag.getKey();
|
||||
/**
|
||||
* This constructs a new {@link TagParser}.
|
||||
*
|
||||
* @param key
|
||||
* The {@link NamespacedKey} of the resulting {@link SlimefunTag}
|
||||
*/
|
||||
public TagParser(@Nonnull NamespacedKey key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
void parse(@Nonnull BiConsumer<Set<Material>, Set<Tag<Material>>> callback) throws TagMisconfigurationException {
|
||||
/**
|
||||
* This constructs a new {@link TagParser} for the given {@link SlimefunTag}
|
||||
*
|
||||
* @param tag
|
||||
* The {@link SlimefunTag} to parse inputs for
|
||||
*/
|
||||
TagParser(@Nonnull SlimefunTag tag) {
|
||||
this(tag.getKey());
|
||||
}
|
||||
|
||||
void parse(@Nonnull SlimefunTag tag, @Nonnull BiConsumer<Set<Material>, Set<Tag<Material>>> callback) throws TagMisconfigurationException {
|
||||
String path = "/tags/" + tag.getKey().getKey() + ".json";
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(SlimefunPlugin.class.getResourceAsStream(path), StandardCharsets.UTF_8))) {
|
||||
parse(reader.lines().collect(Collectors.joining("")), callback);
|
||||
}
|
||||
catch (IOException x) {
|
||||
throw new TagMisconfigurationException(key, x.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This will parse the given JSON {@link String} and run the provided callback with {@link Set Sets} of
|
||||
* matched {@link Material Materials} and {@link Tag Tags}.
|
||||
*
|
||||
* @param json
|
||||
* The JSON {@link String} to parse
|
||||
* @param callback
|
||||
* A callback to run after successfully parsing the input
|
||||
*
|
||||
* @throws TagMisconfigurationException
|
||||
* This is thrown whenever the given input is malformed or no adequate
|
||||
* {@link Material} or {@link Tag} could be found
|
||||
*/
|
||||
public void parse(@Nonnull String json, @Nonnull BiConsumer<Set<Material>, Set<Tag<Material>>> callback) throws TagMisconfigurationException {
|
||||
Validate.notNull(json, "Cannot parse a null String");
|
||||
|
||||
try {
|
||||
Set<Material> materials = new HashSet<>();
|
||||
Set<Tag<Material>> tags = new HashSet<>();
|
||||
|
||||
JsonParser parser = new JsonParser();
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(SlimefunPlugin.class.getResourceAsStream("/tags/" + key.getKey() + ".json"), StandardCharsets.UTF_8))) {
|
||||
JsonObject root = parser.parse(reader.lines().collect(Collectors.joining(""))).getAsJsonObject();
|
||||
JsonObject root = parser.parse(json).getAsJsonObject();
|
||||
JsonElement child = root.get("values");
|
||||
|
||||
if (child instanceof JsonArray) {
|
||||
@ -53,9 +101,12 @@ class TagParser implements Keyed {
|
||||
|
||||
for (JsonElement element : values) {
|
||||
if (element instanceof JsonPrimitive && ((JsonPrimitive) element).isString()) {
|
||||
// Strings will be parsed directly
|
||||
parsePrimitiveValue(element.getAsString(), materials, tags);
|
||||
}
|
||||
else if (element instanceof JsonObject) {
|
||||
// JSONObjects can have a "required" property which can make
|
||||
// it optional to resolve the underlying value
|
||||
parseComplexValue(element.getAsJsonObject(), materials, tags);
|
||||
}
|
||||
else {
|
||||
@ -63,13 +114,15 @@ class TagParser implements Keyed {
|
||||
}
|
||||
}
|
||||
|
||||
// Run the callback with the filled-in materials and tags
|
||||
callback.accept(materials, tags);
|
||||
}
|
||||
else {
|
||||
// The JSON seems to be empty yet valid
|
||||
throw new TagMisconfigurationException(key, "No values array specified");
|
||||
}
|
||||
}
|
||||
catch (IOException | IllegalStateException | JsonParseException x) {
|
||||
catch (IllegalStateException | JsonParseException x) {
|
||||
throw new TagMisconfigurationException(key, x.getMessage());
|
||||
}
|
||||
}
|
||||
@ -81,6 +134,7 @@ class TagParser implements Keyed {
|
||||
Material material = Material.matchMaterial(value);
|
||||
|
||||
if (material != null) {
|
||||
// If the Material could be matched, simply add it to our Set
|
||||
materials.add(material);
|
||||
}
|
||||
else {
|
||||
@ -88,23 +142,28 @@ class TagParser implements Keyed {
|
||||
}
|
||||
}
|
||||
else if (PatternUtils.MINECRAFT_TAG.matcher(value).matches()) {
|
||||
// Get the actual Key portion and match it to item and block tags.
|
||||
String keyValue = PatternUtils.COLON.split(value)[1];
|
||||
NamespacedKey namespacedKey = NamespacedKey.minecraft(keyValue);
|
||||
Tag<Material> itemsTag = Bukkit.getTag(Tag.REGISTRY_ITEMS, namespacedKey, Material.class);
|
||||
Tag<Material> blocksTag = Bukkit.getTag(Tag.REGISTRY_BLOCKS, namespacedKey, Material.class);
|
||||
|
||||
if (itemsTag != null) {
|
||||
// We will prioritize the item tag
|
||||
tags.add(itemsTag);
|
||||
}
|
||||
else if (blocksTag != null) {
|
||||
// If no item tag exists, fall back to the block tag
|
||||
tags.add(blocksTag);
|
||||
}
|
||||
else {
|
||||
// If both fail, then the tag does not exist.
|
||||
throw new TagMisconfigurationException(key, "There is no '" + value + "' tag in Minecraft.");
|
||||
}
|
||||
}
|
||||
else if (PatternUtils.SLIMEFUN_TAG.matcher(value).matches()) {
|
||||
try {
|
||||
// Get a SlimefunTag enum value for the given key
|
||||
String keyValue = PatternUtils.COLON.split(value)[1].toUpperCase(Locale.ROOT);
|
||||
SlimefunTag tag = SlimefunTag.valueOf(keyValue);
|
||||
tags.add(tag);
|
||||
@ -114,6 +173,7 @@ class TagParser implements Keyed {
|
||||
}
|
||||
}
|
||||
else {
|
||||
// If no RegEx pattern matched, it's malformed.
|
||||
throw new TagMisconfigurationException(key, "Could not recognize value '" + value + "'");
|
||||
}
|
||||
}
|
||||
@ -123,11 +183,14 @@ class TagParser implements Keyed {
|
||||
JsonElement id = entry.get("id");
|
||||
JsonElement required = entry.get("required");
|
||||
|
||||
// Check if the entry contains elements of the correct type
|
||||
if (id instanceof JsonPrimitive && ((JsonPrimitive) id).isString() && required instanceof JsonPrimitive && ((JsonPrimitive) required).isBoolean()) {
|
||||
if (required.getAsBoolean()) {
|
||||
// If this entry is required, parse it like normal
|
||||
parsePrimitiveValue(id.getAsString(), materials, tags);
|
||||
}
|
||||
else {
|
||||
// If the entry is not required, validation will be optional
|
||||
try {
|
||||
parsePrimitiveValue(id.getAsString(), materials, tags);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user