Skip to content

Commit

Permalink
Implement CustomEffect utility
Browse files Browse the repository at this point in the history
Allows for easily specifying custom effects which can be read from a text file
  • Loading branch information
Redned235 committed Dec 9, 2024
1 parent 2180f54 commit 5c0c59a
Show file tree
Hide file tree
Showing 6 changed files with 539 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,14 @@ private static List<Object> parseList(@Nullable Path sourceFile, Object instance
List<Object> objectList = new ArrayList<>(list.size());

// Get the primitive type of the list
Class<?> listType = (Class<?>) ((ParameterizedType) genericType).getActualTypeArguments()[0];
Class<?> listType;
Type[] types = ((ParameterizedType) genericType).getActualTypeArguments();
if (types[0] instanceof ParameterizedType) {
listType = (Class<?>) ((ParameterizedType) types[0]).getRawType();
} else {
listType = (Class<?>) types[0];
}

if (OBJECT_PROVIDERS.containsKey(listType)) {
Parser<Object> objectProvider = OBJECT_PROVIDERS.get(listType);
for (Object object : list) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.battleplugins.arena.config;

import java.awt.Color;

public class ColorParser implements ArenaConfigParser.Parser<Color> {

@Override
public Color parse(Object object) throws ParseException {
if (!(object instanceof String value)) {
throw new ParseException("Color must be a string!")
.context("Provided color", object == null ? "null" : object.toString())
.cause(ParseException.Cause.INVALID_TYPE)
.type(this.getClass())
.userError();
}

return deserializeSingular(value);
}

public static org.bukkit.Color deserializeSingularBukkit(String contents) throws ParseException {
Color color = deserializeSingular(contents);
return org.bukkit.Color.fromRGB(color.getRed(), color.getGreen(), color.getBlue());
}

public static Color deserializeSingular(String contents) throws ParseException {
if (contents.startsWith("#")) {
return Color.decode(contents);
} else if (contents.contains(",")) {
String[] split = contents.split(",");
if (split.length != 3) {
throw new ParseException("Color must have 3 values!")
.context("Provided color", contents)
.context("Expected format", "r,g,b")
.cause(ParseException.Cause.INVALID_VALUE)
.userError();
}

return new Color(Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2]));
} else {
return Color.getColor(contents);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package org.battleplugins.arena.config;

import org.battleplugins.arena.util.CustomEffect;
import org.bukkit.configuration.ConfigurationSection;

import java.util.HashMap;
import java.util.Map;

public class CustomEffectParser<T extends CustomEffect<?>> implements ArenaConfigParser.Parser<T> {

@SuppressWarnings("unchecked")
@Override
public T parse(Object object) throws ParseException {
if (object instanceof String string) {
return (T) deserializeSingular(string);
}

if (object instanceof ConfigurationSection section) {
return (T) deserializeNode(section);
}

throw new ParseException("Invalid CustomEffect for object: " + object)
.cause(ParseException.Cause.INVALID_TYPE)
.type(this.getClass())
.userError();
}

public static CustomEffect<?> deserializeSingular(String contents) throws ParseException {
CustomEffect.EffectType<?> type;

SingularValueParser.ArgumentBuffer buffer = SingularValueParser.parseNamed(contents, SingularValueParser.BraceStyle.CURLY, ';');
if (!buffer.hasNext()) {
throw new ParseException("No data found for CustomEffect")
.cause(ParseException.Cause.INVALID_TYPE)
.type(CustomEffectParser.class)
.userError();
}

SingularValueParser.Argument root = buffer.pop();
if (root.key().equals("root")) {
type = CustomEffect.EffectType.get(root.value());
if (type == null) {
throw new ParseException("Invalid CustomEffect type: " + root.value())
.cause(ParseException.Cause.INVALID_TYPE)
.type(CustomEffectParser.class)
.userError();
}
} else {
throw new ParseException("Invalid CustomEffect root tag " + root.key())
.cause(ParseException.Cause.INTERNAL_ERROR)
.type(CustomEffectParser.class);
}

Map<String, String> data = new HashMap<>();
while (buffer.hasNext()) {
SingularValueParser.Argument argument = buffer.pop();
data.put(argument.key(), argument.value());
}

CustomEffect<?> customEffect = type.create(builder -> { });
customEffect.deserialize(data);
return customEffect;
}

private static CustomEffect<?> deserializeNode(ConfigurationSection section) throws ParseException {
String type = section.getString("type");
if (type == null) {
throw new ParseException("No type found for CustomEffect")
.cause(ParseException.Cause.INVALID_TYPE)
.type(CustomEffectParser.class)
.userError();
}

CustomEffect.EffectType<?> effectType = CustomEffect.EffectType.get(type);
if (effectType == null) {
throw new ParseException("Invalid CustomEffect type: " + type)
.cause(ParseException.Cause.INVALID_TYPE)
.type(CustomEffectParser.class)
.userError();
}

Map<String, String> data = new HashMap<>();
for (String key : section.getKeys(false)) {
if (key.equals("type")) {
continue;
}

data.put(key, section.getString(key));
}

CustomEffect<?> customEffect = effectType.create(builder -> { });
customEffect.deserialize(data);
return customEffect;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.battleplugins.arena.config.context.OptionContextProvider;
import org.battleplugins.arena.config.context.PhaseContextProvider;
import org.battleplugins.arena.config.context.VictoryConditionContextProvider;
import org.battleplugins.arena.util.CustomEffect;
import org.battleplugins.arena.util.IntRange;
import org.battleplugins.arena.util.PositionWithRotation;
import org.bukkit.Bukkit;
Expand Down Expand Up @@ -70,29 +71,7 @@ static void register() {
}
});

ArenaConfigParser.registerProvider(Color.class, configValue -> {
if (!(configValue instanceof String value)) {
return null;
}

if (value.startsWith("#")) {
return Color.decode(value);
} else if (value.contains(",")) {
String[] split = value.split(",");
if (split.length != 3) {
throw new ParseException("Color must have 3 values!")
.context("Provided color", value)
.context("Expected format", "r,g,b")
.cause(ParseException.Cause.INVALID_VALUE)
.userError();
}

return new Color(Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2]));
} else {
return Color.getColor(value);
}
});

ArenaConfigParser.registerProvider(Color.class, new ColorParser());
ArenaConfigParser.registerProvider(Component.class, configValue -> {
if (!(configValue instanceof String value)) {
return null;
Expand All @@ -102,6 +81,7 @@ static void register() {
});

ArenaConfigParser.registerProvider(BlockData.class, parseString(Bukkit::createBlockData));
ArenaConfigParser.registerProvider(CustomEffect.class, new CustomEffectParser<>());
}

private static <T> ArenaConfigParser.Parser<T> parseString(Function<String, T> parser) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionEffect;

import java.awt.Color;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -78,9 +77,9 @@ public static ItemStack deserializeSingular(String contents) throws ParseExcepti
switch (key) {
case "color" -> {
if (itemMeta instanceof ColorableArmorMeta colorMeta) {
colorMeta.setColor(org.bukkit.Color.fromRGB(Color.getColor(value).getRGB()));
colorMeta.setColor(ColorParser.deserializeSingularBukkit(value));
} else if (itemMeta instanceof PotionMeta potionMeta) {
potionMeta.setColor(org.bukkit.Color.fromRGB(Color.getColor(value).getRGB()));
potionMeta.setColor(ColorParser.deserializeSingularBukkit(value));
}
}
case "custom-model-data" -> {
Expand Down Expand Up @@ -169,9 +168,9 @@ private static ItemStack deserializeNode(ConfigurationSection section) throws Pa
switch (meta) {
case "color": {
if (itemMeta instanceof ColorableArmorMeta colorMeta) {
colorMeta.setColor(org.bukkit.Color.fromRGB(Color.getColor(section.getString(meta)).getRGB()));
colorMeta.setColor(ColorParser.deserializeSingularBukkit(section.getString(meta)));
} else if (itemMeta instanceof PotionMeta potionMeta) {
potionMeta.setColor(org.bukkit.Color.fromRGB(Color.getColor(section.getString(meta)).getRGB()));
potionMeta.setColor(ColorParser.deserializeSingularBukkit(section.getString(meta)));
}
}
case "custom-model-data": {
Expand Down
Loading

0 comments on commit 5c0c59a

Please sign in to comment.