Skip to content

Commit 5c0c59a

Browse files
committed
Implement CustomEffect utility
Allows for easily specifying custom effects which can be read from a text file
1 parent 2180f54 commit 5c0c59a

File tree

6 files changed

+539
-29
lines changed

6 files changed

+539
-29
lines changed

plugin/src/main/java/org/battleplugins/arena/config/ArenaConfigParser.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,14 @@ private static List<Object> parseList(@Nullable Path sourceFile, Object instance
414414
List<Object> objectList = new ArrayList<>(list.size());
415415

416416
// Get the primitive type of the list
417-
Class<?> listType = (Class<?>) ((ParameterizedType) genericType).getActualTypeArguments()[0];
417+
Class<?> listType;
418+
Type[] types = ((ParameterizedType) genericType).getActualTypeArguments();
419+
if (types[0] instanceof ParameterizedType) {
420+
listType = (Class<?>) ((ParameterizedType) types[0]).getRawType();
421+
} else {
422+
listType = (Class<?>) types[0];
423+
}
424+
418425
if (OBJECT_PROVIDERS.containsKey(listType)) {
419426
Parser<Object> objectProvider = OBJECT_PROVIDERS.get(listType);
420427
for (Object object : list) {
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package org.battleplugins.arena.config;
2+
3+
import java.awt.Color;
4+
5+
public class ColorParser implements ArenaConfigParser.Parser<Color> {
6+
7+
@Override
8+
public Color parse(Object object) throws ParseException {
9+
if (!(object instanceof String value)) {
10+
throw new ParseException("Color must be a string!")
11+
.context("Provided color", object == null ? "null" : object.toString())
12+
.cause(ParseException.Cause.INVALID_TYPE)
13+
.type(this.getClass())
14+
.userError();
15+
}
16+
17+
return deserializeSingular(value);
18+
}
19+
20+
public static org.bukkit.Color deserializeSingularBukkit(String contents) throws ParseException {
21+
Color color = deserializeSingular(contents);
22+
return org.bukkit.Color.fromRGB(color.getRed(), color.getGreen(), color.getBlue());
23+
}
24+
25+
public static Color deserializeSingular(String contents) throws ParseException {
26+
if (contents.startsWith("#")) {
27+
return Color.decode(contents);
28+
} else if (contents.contains(",")) {
29+
String[] split = contents.split(",");
30+
if (split.length != 3) {
31+
throw new ParseException("Color must have 3 values!")
32+
.context("Provided color", contents)
33+
.context("Expected format", "r,g,b")
34+
.cause(ParseException.Cause.INVALID_VALUE)
35+
.userError();
36+
}
37+
38+
return new Color(Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2]));
39+
} else {
40+
return Color.getColor(contents);
41+
}
42+
}
43+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package org.battleplugins.arena.config;
2+
3+
import org.battleplugins.arena.util.CustomEffect;
4+
import org.bukkit.configuration.ConfigurationSection;
5+
6+
import java.util.HashMap;
7+
import java.util.Map;
8+
9+
public class CustomEffectParser<T extends CustomEffect<?>> implements ArenaConfigParser.Parser<T> {
10+
11+
@SuppressWarnings("unchecked")
12+
@Override
13+
public T parse(Object object) throws ParseException {
14+
if (object instanceof String string) {
15+
return (T) deserializeSingular(string);
16+
}
17+
18+
if (object instanceof ConfigurationSection section) {
19+
return (T) deserializeNode(section);
20+
}
21+
22+
throw new ParseException("Invalid CustomEffect for object: " + object)
23+
.cause(ParseException.Cause.INVALID_TYPE)
24+
.type(this.getClass())
25+
.userError();
26+
}
27+
28+
public static CustomEffect<?> deserializeSingular(String contents) throws ParseException {
29+
CustomEffect.EffectType<?> type;
30+
31+
SingularValueParser.ArgumentBuffer buffer = SingularValueParser.parseNamed(contents, SingularValueParser.BraceStyle.CURLY, ';');
32+
if (!buffer.hasNext()) {
33+
throw new ParseException("No data found for CustomEffect")
34+
.cause(ParseException.Cause.INVALID_TYPE)
35+
.type(CustomEffectParser.class)
36+
.userError();
37+
}
38+
39+
SingularValueParser.Argument root = buffer.pop();
40+
if (root.key().equals("root")) {
41+
type = CustomEffect.EffectType.get(root.value());
42+
if (type == null) {
43+
throw new ParseException("Invalid CustomEffect type: " + root.value())
44+
.cause(ParseException.Cause.INVALID_TYPE)
45+
.type(CustomEffectParser.class)
46+
.userError();
47+
}
48+
} else {
49+
throw new ParseException("Invalid CustomEffect root tag " + root.key())
50+
.cause(ParseException.Cause.INTERNAL_ERROR)
51+
.type(CustomEffectParser.class);
52+
}
53+
54+
Map<String, String> data = new HashMap<>();
55+
while (buffer.hasNext()) {
56+
SingularValueParser.Argument argument = buffer.pop();
57+
data.put(argument.key(), argument.value());
58+
}
59+
60+
CustomEffect<?> customEffect = type.create(builder -> { });
61+
customEffect.deserialize(data);
62+
return customEffect;
63+
}
64+
65+
private static CustomEffect<?> deserializeNode(ConfigurationSection section) throws ParseException {
66+
String type = section.getString("type");
67+
if (type == null) {
68+
throw new ParseException("No type found for CustomEffect")
69+
.cause(ParseException.Cause.INVALID_TYPE)
70+
.type(CustomEffectParser.class)
71+
.userError();
72+
}
73+
74+
CustomEffect.EffectType<?> effectType = CustomEffect.EffectType.get(type);
75+
if (effectType == null) {
76+
throw new ParseException("Invalid CustomEffect type: " + type)
77+
.cause(ParseException.Cause.INVALID_TYPE)
78+
.type(CustomEffectParser.class)
79+
.userError();
80+
}
81+
82+
Map<String, String> data = new HashMap<>();
83+
for (String key : section.getKeys(false)) {
84+
if (key.equals("type")) {
85+
continue;
86+
}
87+
88+
data.put(key, section.getString(key));
89+
}
90+
91+
CustomEffect<?> customEffect = effectType.create(builder -> { });
92+
customEffect.deserialize(data);
93+
return customEffect;
94+
}
95+
}

plugin/src/main/java/org/battleplugins/arena/config/DefaultParsers.java

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.battleplugins.arena.config.context.OptionContextProvider;
1111
import org.battleplugins.arena.config.context.PhaseContextProvider;
1212
import org.battleplugins.arena.config.context.VictoryConditionContextProvider;
13+
import org.battleplugins.arena.util.CustomEffect;
1314
import org.battleplugins.arena.util.IntRange;
1415
import org.battleplugins.arena.util.PositionWithRotation;
1516
import org.bukkit.Bukkit;
@@ -70,29 +71,7 @@ static void register() {
7071
}
7172
});
7273

73-
ArenaConfigParser.registerProvider(Color.class, configValue -> {
74-
if (!(configValue instanceof String value)) {
75-
return null;
76-
}
77-
78-
if (value.startsWith("#")) {
79-
return Color.decode(value);
80-
} else if (value.contains(",")) {
81-
String[] split = value.split(",");
82-
if (split.length != 3) {
83-
throw new ParseException("Color must have 3 values!")
84-
.context("Provided color", value)
85-
.context("Expected format", "r,g,b")
86-
.cause(ParseException.Cause.INVALID_VALUE)
87-
.userError();
88-
}
89-
90-
return new Color(Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2]));
91-
} else {
92-
return Color.getColor(value);
93-
}
94-
});
95-
74+
ArenaConfigParser.registerProvider(Color.class, new ColorParser());
9675
ArenaConfigParser.registerProvider(Component.class, configValue -> {
9776
if (!(configValue instanceof String value)) {
9877
return null;
@@ -102,6 +81,7 @@ static void register() {
10281
});
10382

10483
ArenaConfigParser.registerProvider(BlockData.class, parseString(Bukkit::createBlockData));
84+
ArenaConfigParser.registerProvider(CustomEffect.class, new CustomEffectParser<>());
10585
}
10686

10787
private static <T> ArenaConfigParser.Parser<T> parseString(Function<String, T> parser) {

plugin/src/main/java/org/battleplugins/arena/config/ItemStackParser.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import org.bukkit.inventory.meta.PotionMeta;
1616
import org.bukkit.potion.PotionEffect;
1717

18-
import java.awt.Color;
1918
import java.util.Arrays;
2019
import java.util.HashSet;
2120
import java.util.List;
@@ -78,9 +77,9 @@ public static ItemStack deserializeSingular(String contents) throws ParseExcepti
7877
switch (key) {
7978
case "color" -> {
8079
if (itemMeta instanceof ColorableArmorMeta colorMeta) {
81-
colorMeta.setColor(org.bukkit.Color.fromRGB(Color.getColor(value).getRGB()));
80+
colorMeta.setColor(ColorParser.deserializeSingularBukkit(value));
8281
} else if (itemMeta instanceof PotionMeta potionMeta) {
83-
potionMeta.setColor(org.bukkit.Color.fromRGB(Color.getColor(value).getRGB()));
82+
potionMeta.setColor(ColorParser.deserializeSingularBukkit(value));
8483
}
8584
}
8685
case "custom-model-data" -> {
@@ -169,9 +168,9 @@ private static ItemStack deserializeNode(ConfigurationSection section) throws Pa
169168
switch (meta) {
170169
case "color": {
171170
if (itemMeta instanceof ColorableArmorMeta colorMeta) {
172-
colorMeta.setColor(org.bukkit.Color.fromRGB(Color.getColor(section.getString(meta)).getRGB()));
171+
colorMeta.setColor(ColorParser.deserializeSingularBukkit(section.getString(meta)));
173172
} else if (itemMeta instanceof PotionMeta potionMeta) {
174-
potionMeta.setColor(org.bukkit.Color.fromRGB(Color.getColor(section.getString(meta)).getRGB()));
173+
potionMeta.setColor(ColorParser.deserializeSingularBukkit(section.getString(meta)));
175174
}
176175
}
177176
case "custom-model-data": {

0 commit comments

Comments
 (0)