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.api.exceptions.TagMisconfigurationException;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
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> {
|
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,
|
SENSITIVE_MATERIALS,
|
||||||
|
|
||||||
// Expanding upon Minecraft's tags:
|
/**
|
||||||
|
* Minecraft ores.
|
||||||
|
*/
|
||||||
ORES,
|
ORES,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All terracotta variants, does not include glazed terracotta.
|
||||||
|
*/
|
||||||
TERRACOTTA,
|
TERRACOTTA,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All ice variants, normal, packed, blue and whatever else there is.
|
||||||
|
*/
|
||||||
ICE_VARIANTS,
|
ICE_VARIANTS,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All stone variants, normal, andesite, diorite, granite and whatever else may come.
|
||||||
|
*/
|
||||||
STONE_VARIANTS,
|
STONE_VARIANTS,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All variants of concrete powder.
|
||||||
|
* Can you believe there is no tag for this already?
|
||||||
|
*/
|
||||||
CONCRETE_POWDERS,
|
CONCRETE_POWDERS,
|
||||||
|
|
||||||
// Actual Slimefun tags:
|
/**
|
||||||
|
* All materials which the {@link ExplosiveShovel} can break.
|
||||||
|
*/
|
||||||
EXPLOSIVE_SHOVEL_BLOCKS,
|
EXPLOSIVE_SHOVEL_BLOCKS,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All materials (ores) which the {@link PickaxeOfTheSeeker} recognizes.
|
||||||
|
*/
|
||||||
PICKAXE_OF_VEIN_MINING_BLOCKS,
|
PICKAXE_OF_VEIN_MINING_BLOCKS,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All materials (crops) which the {@link CropGrowthAccelerator} will recognize.
|
||||||
|
*/
|
||||||
CROP_GROWTH_ACCELERATOR_BLOCKS,
|
CROP_GROWTH_ACCELERATOR_BLOCKS,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All materials which the {@link ClimbingPick} is able to climb.
|
||||||
|
*/
|
||||||
CLIMBING_PICK_SURFACES;
|
CLIMBING_PICK_SURFACES;
|
||||||
|
|
||||||
private final NamespacedKey key;
|
private final NamespacedKey key;
|
||||||
private final Set<Material> includedMaterials = new HashSet<>();
|
private final Set<Material> includedMaterials = new HashSet<>();
|
||||||
private final Set<Tag<Material>> additionalTags = 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() {
|
SlimefunTag() {
|
||||||
key = new NamespacedKey(SlimefunPlugin.instance(), name().toLowerCase(Locale.ROOT));
|
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
|
* This is thrown whenever a {@link SlimefunTag} could not be parsed properly
|
||||||
*/
|
*/
|
||||||
public void reload() throws TagMisconfigurationException {
|
public void reload() throws TagMisconfigurationException {
|
||||||
new TagParser(this).parse((materials, tags) -> {
|
new TagParser(this).parse(this, (materials, tags) -> {
|
||||||
this.includedMaterials.clear();
|
this.includedMaterials.clear();
|
||||||
this.includedMaterials.addAll(materials);
|
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
|
@Nonnull
|
||||||
public Set<Tag<Material>> getSubTags() {
|
public Set<Tag<Material>> getSubTags() {
|
||||||
return Collections.unmodifiableSet(additionalTags);
|
return Collections.unmodifiableSet(additionalTags);
|
||||||
|
@ -13,6 +13,7 @@ import java.util.stream.Collectors;
|
|||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Keyed;
|
import org.bukkit.Keyed;
|
||||||
import org.bukkit.Material;
|
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.implementation.SlimefunPlugin;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
|
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;
|
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 {
|
/**
|
||||||
Set<Material> materials = new HashSet<>();
|
* This constructs a new {@link TagParser} for the given {@link SlimefunTag}
|
||||||
Set<Tag<Material>> tags = new HashSet<>();
|
*
|
||||||
|
* @param tag
|
||||||
|
* The {@link SlimefunTag} to parse inputs for
|
||||||
|
*/
|
||||||
|
TagParser(@Nonnull SlimefunTag tag) {
|
||||||
|
this(tag.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
JsonParser parser = new JsonParser();
|
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("/tags/" + key.getKey() + ".json"), StandardCharsets.UTF_8))) {
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(SlimefunPlugin.class.getResourceAsStream(path), StandardCharsets.UTF_8))) {
|
||||||
JsonObject root = parser.parse(reader.lines().collect(Collectors.joining(""))).getAsJsonObject();
|
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();
|
||||||
|
JsonObject root = parser.parse(json).getAsJsonObject();
|
||||||
JsonElement child = root.get("values");
|
JsonElement child = root.get("values");
|
||||||
|
|
||||||
if (child instanceof JsonArray) {
|
if (child instanceof JsonArray) {
|
||||||
@ -53,9 +101,12 @@ class TagParser implements Keyed {
|
|||||||
|
|
||||||
for (JsonElement element : values) {
|
for (JsonElement element : values) {
|
||||||
if (element instanceof JsonPrimitive && ((JsonPrimitive) element).isString()) {
|
if (element instanceof JsonPrimitive && ((JsonPrimitive) element).isString()) {
|
||||||
|
// Strings will be parsed directly
|
||||||
parsePrimitiveValue(element.getAsString(), materials, tags);
|
parsePrimitiveValue(element.getAsString(), materials, tags);
|
||||||
}
|
}
|
||||||
else if (element instanceof JsonObject) {
|
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);
|
parseComplexValue(element.getAsJsonObject(), materials, tags);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -63,13 +114,15 @@ class TagParser implements Keyed {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run the callback with the filled-in materials and tags
|
||||||
callback.accept(materials, tags);
|
callback.accept(materials, tags);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// The JSON seems to be empty yet valid
|
||||||
throw new TagMisconfigurationException(key, "No values array specified");
|
throw new TagMisconfigurationException(key, "No values array specified");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException | IllegalStateException | JsonParseException x) {
|
catch (IllegalStateException | JsonParseException x) {
|
||||||
throw new TagMisconfigurationException(key, x.getMessage());
|
throw new TagMisconfigurationException(key, x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,6 +134,7 @@ class TagParser implements Keyed {
|
|||||||
Material material = Material.matchMaterial(value);
|
Material material = Material.matchMaterial(value);
|
||||||
|
|
||||||
if (material != null) {
|
if (material != null) {
|
||||||
|
// If the Material could be matched, simply add it to our Set
|
||||||
materials.add(material);
|
materials.add(material);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -88,23 +142,28 @@ class TagParser implements Keyed {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (PatternUtils.MINECRAFT_TAG.matcher(value).matches()) {
|
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];
|
String keyValue = PatternUtils.COLON.split(value)[1];
|
||||||
NamespacedKey namespacedKey = NamespacedKey.minecraft(keyValue);
|
NamespacedKey namespacedKey = NamespacedKey.minecraft(keyValue);
|
||||||
Tag<Material> itemsTag = Bukkit.getTag(Tag.REGISTRY_ITEMS, namespacedKey, Material.class);
|
Tag<Material> itemsTag = Bukkit.getTag(Tag.REGISTRY_ITEMS, namespacedKey, Material.class);
|
||||||
Tag<Material> blocksTag = Bukkit.getTag(Tag.REGISTRY_BLOCKS, namespacedKey, Material.class);
|
Tag<Material> blocksTag = Bukkit.getTag(Tag.REGISTRY_BLOCKS, namespacedKey, Material.class);
|
||||||
|
|
||||||
if (itemsTag != null) {
|
if (itemsTag != null) {
|
||||||
|
// We will prioritize the item tag
|
||||||
tags.add(itemsTag);
|
tags.add(itemsTag);
|
||||||
}
|
}
|
||||||
else if (blocksTag != null) {
|
else if (blocksTag != null) {
|
||||||
|
// If no item tag exists, fall back to the block tag
|
||||||
tags.add(blocksTag);
|
tags.add(blocksTag);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// If both fail, then the tag does not exist.
|
||||||
throw new TagMisconfigurationException(key, "There is no '" + value + "' tag in Minecraft.");
|
throw new TagMisconfigurationException(key, "There is no '" + value + "' tag in Minecraft.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (PatternUtils.SLIMEFUN_TAG.matcher(value).matches()) {
|
else if (PatternUtils.SLIMEFUN_TAG.matcher(value).matches()) {
|
||||||
try {
|
try {
|
||||||
|
// Get a SlimefunTag enum value for the given key
|
||||||
String keyValue = PatternUtils.COLON.split(value)[1].toUpperCase(Locale.ROOT);
|
String keyValue = PatternUtils.COLON.split(value)[1].toUpperCase(Locale.ROOT);
|
||||||
SlimefunTag tag = SlimefunTag.valueOf(keyValue);
|
SlimefunTag tag = SlimefunTag.valueOf(keyValue);
|
||||||
tags.add(tag);
|
tags.add(tag);
|
||||||
@ -114,6 +173,7 @@ class TagParser implements Keyed {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// If no RegEx pattern matched, it's malformed.
|
||||||
throw new TagMisconfigurationException(key, "Could not recognize value '" + value + "'");
|
throw new TagMisconfigurationException(key, "Could not recognize value '" + value + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,11 +183,14 @@ class TagParser implements Keyed {
|
|||||||
JsonElement id = entry.get("id");
|
JsonElement id = entry.get("id");
|
||||||
JsonElement required = entry.get("required");
|
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 (id instanceof JsonPrimitive && ((JsonPrimitive) id).isString() && required instanceof JsonPrimitive && ((JsonPrimitive) required).isBoolean()) {
|
||||||
if (required.getAsBoolean()) {
|
if (required.getAsBoolean()) {
|
||||||
|
// If this entry is required, parse it like normal
|
||||||
parsePrimitiveValue(id.getAsString(), materials, tags);
|
parsePrimitiveValue(id.getAsString(), materials, tags);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// If the entry is not required, validation will be optional
|
||||||
try {
|
try {
|
||||||
parsePrimitiveValue(id.getAsString(), materials, tags);
|
parsePrimitiveValue(id.getAsString(), materials, tags);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user