Skip to content

Commit 3999722

Browse files
committed
Update banner pattern back compat after Spigot changes
PatternType was changed to an interface, which would have broke backwards compatibility.
1 parent 1a9ad32 commit 3999722

File tree

5 files changed

+217
-98
lines changed

5 files changed

+217
-98
lines changed

src/main/java/com/laytonsmith/abstraction/bukkit/BukkitConvertor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@
8989
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCEntityType;
9090
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCEquipmentSlot;
9191
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCLegacyMaterial;
92-
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCPatternShape;
9392
import com.laytonsmith.annotations.convert;
9493
import com.laytonsmith.commandhelper.CommandHelperPlugin;
9594
import com.laytonsmith.core.LogLevel;
@@ -125,6 +124,7 @@
125124
import org.bukkit.block.Sign;
126125
import org.bukkit.block.Skull;
127126
import org.bukkit.block.banner.Pattern;
127+
import org.bukkit.block.banner.PatternType;
128128
import org.bukkit.command.BlockCommandSender;
129129
import org.bukkit.command.CommandSender;
130130
import org.bukkit.command.ConsoleCommandSender;
@@ -771,7 +771,7 @@ public MCColor GetColor(String colorName, Target t) throws CREFormatException {
771771
@Override
772772
public MCPattern GetPattern(MCDyeColor color, MCPatternShape shape) {
773773
return new BukkitMCPattern(new Pattern(BukkitMCDyeColor.getConvertor().getConcreteEnum(color),
774-
BukkitMCPatternShape.getConvertor().getConcreteEnum(shape)));
774+
(PatternType) shape.getConcrete()));
775775
}
776776

777777
@Override

src/main/java/com/laytonsmith/abstraction/bukkit/BukkitMCPattern.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public MCDyeColor getColor() {
2727

2828
@Override
2929
public MCPatternShape getShape() {
30-
return BukkitMCPatternShape.getConvertor().getAbstractedEnum(pattern.getPattern());
30+
return BukkitMCPatternShape.valueOfConcrete(pattern.getPattern());
3131
}
3232

3333
@Override
Lines changed: 125 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,128 @@
11
package com.laytonsmith.abstraction.enums;
22

3-
import com.laytonsmith.annotations.MEnum;
4-
5-
@MEnum("com.commandhelper.PatternShape")
6-
public enum MCPatternShape {
7-
BASE,
8-
BORDER,
9-
BRICKS,
10-
CIRCLE_MIDDLE,
11-
CREEPER,
12-
CROSS,
13-
CURLY_BORDER,
14-
DIAGONAL_LEFT,
15-
DIAGONAL_LEFT_MIRROR,
16-
DIAGONAL_RIGHT,
17-
DIAGONAL_RIGHT_MIRROR,
18-
FLOW,
19-
FLOWER,
20-
GLOBE,
21-
GRADIENT,
22-
GRADIENT_UP,
23-
GUSTER,
24-
HALF_HORIZONTAL,
25-
HALF_HORIZONTAL_MIRROR,
26-
HALF_VERTICAL,
27-
HALF_VERTICAL_MIRROR,
28-
MOJANG,
29-
PIGLIN,
30-
RHOMBUS_MIDDLE,
31-
SKULL,
32-
SQUARE_BOTTOM_LEFT,
33-
SQUARE_BOTTOM_RIGHT,
34-
SQUARE_TOP_LEFT,
35-
SQUARE_TOP_RIGHT,
36-
STRAIGHT_CROSS,
37-
STRIPE_BOTTOM,
38-
STRIPE_CENTER,
39-
STRIPE_DOWNLEFT,
40-
STRIPE_DOWNRIGHT,
41-
STRIPE_LEFT,
42-
STRIPE_MIDDLE,
43-
STRIPE_RIGHT,
44-
STRIPE_SMALL,
45-
STRIPE_TOP,
46-
TRIANGLE_BOTTOM,
47-
TRIANGLE_TOP,
48-
TRIANGLES_BOTTOM,
49-
TRIANGLES_TOP
3+
import com.laytonsmith.PureUtilities.ClassLoading.DynamicEnum;
4+
import com.laytonsmith.annotations.MDynamicEnum;
5+
6+
import java.util.ArrayList;
7+
import java.util.HashMap;
8+
import java.util.HashSet;
9+
import java.util.List;
10+
import java.util.Map;
11+
import java.util.Set;
12+
13+
@MDynamicEnum("com.commandhelper.PatternShape")
14+
public abstract class MCPatternShape<Concrete> extends DynamicEnum<MCPatternShape.MCVanillaPatternShape, Concrete> {
15+
16+
protected static final Map<String, MCPatternShape> MAP = new HashMap<>();
17+
18+
public MCPatternShape(MCVanillaPatternShape mcVanillaPatternShape, Concrete concrete) {
19+
super(mcVanillaPatternShape, concrete);
20+
}
21+
22+
public static MCPatternShape valueOf(String test) throws IllegalArgumentException {
23+
MCPatternShape shape = MAP.get(test);
24+
if(shape == null) {
25+
throw new IllegalArgumentException("Unknown pattern shape: " + test);
26+
}
27+
return shape;
28+
}
29+
30+
/**
31+
* @return Names of available patterns
32+
*/
33+
public static Set<String> types() {
34+
if(MAP.isEmpty()) { // docs mode
35+
Set<String> dummy = new HashSet<>();
36+
for(final MCVanillaPatternShape t : MCVanillaPatternShape.values()) {
37+
if(t.existsIn(MCVersion.CURRENT)) {
38+
dummy.add(t.name());
39+
}
40+
}
41+
return dummy;
42+
}
43+
return MAP.keySet();
44+
}
45+
46+
/**
47+
* @return Our own MCPatternShape list
48+
*/
49+
public static List<MCPatternShape> values() {
50+
if(MAP.isEmpty()) { // docs mode
51+
ArrayList<MCPatternShape> dummy = new ArrayList<>();
52+
for(final MCPatternShape.MCVanillaPatternShape p : MCPatternShape.MCVanillaPatternShape.values()) {
53+
if(!p.existsIn(MCVersion.CURRENT)) {
54+
continue;
55+
}
56+
dummy.add(new MCPatternShape<>(p, null) {
57+
@Override
58+
public String name() {
59+
return p.name();
60+
}
61+
});
62+
}
63+
return dummy;
64+
}
65+
return new ArrayList<>(MAP.values());
66+
}
67+
68+
public enum MCVanillaPatternShape {
69+
BASE,
70+
BORDER,
71+
BRICKS,
72+
CIRCLE_MIDDLE,
73+
CREEPER,
74+
CROSS,
75+
CURLY_BORDER,
76+
DIAGONAL_LEFT,
77+
DIAGONAL_LEFT_MIRROR,
78+
DIAGONAL_RIGHT,
79+
DIAGONAL_RIGHT_MIRROR,
80+
FLOW(MCVersion.MC1_21),
81+
FLOWER,
82+
GLOBE,
83+
GRADIENT,
84+
GRADIENT_UP,
85+
GUSTER(MCVersion.MC1_21),
86+
HALF_HORIZONTAL,
87+
HALF_HORIZONTAL_MIRROR,
88+
HALF_VERTICAL,
89+
HALF_VERTICAL_MIRROR,
90+
MOJANG,
91+
PIGLIN,
92+
RHOMBUS_MIDDLE,
93+
SKULL,
94+
SQUARE_BOTTOM_LEFT,
95+
SQUARE_BOTTOM_RIGHT,
96+
SQUARE_TOP_LEFT,
97+
SQUARE_TOP_RIGHT,
98+
STRAIGHT_CROSS,
99+
STRIPE_BOTTOM,
100+
STRIPE_CENTER,
101+
STRIPE_DOWNLEFT,
102+
STRIPE_DOWNRIGHT,
103+
STRIPE_LEFT,
104+
STRIPE_MIDDLE,
105+
STRIPE_RIGHT,
106+
STRIPE_SMALL,
107+
STRIPE_TOP,
108+
TRIANGLE_BOTTOM,
109+
TRIANGLE_TOP,
110+
TRIANGLES_BOTTOM,
111+
TRIANGLES_TOP,
112+
UNKNOWN(MCVersion.NEVER);
113+
114+
final MCVersion added;
115+
116+
MCVanillaPatternShape() {
117+
this.added = MCVersion.MC1_8;
118+
}
119+
120+
MCVanillaPatternShape(MCVersion version) {
121+
this.added = version;
122+
}
123+
124+
public boolean existsIn(MCVersion version) {
125+
return version.gte(added);
126+
}
127+
}
50128
}
Lines changed: 87 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,110 @@
11
package com.laytonsmith.abstraction.enums.bukkit;
22

3-
import com.laytonsmith.abstraction.Implementation;
4-
import com.laytonsmith.abstraction.enums.EnumConvertor;
3+
import com.laytonsmith.PureUtilities.Common.ReflectionUtils;
4+
import com.laytonsmith.PureUtilities.Common.ReflectionUtils.ReflectionException;
55
import com.laytonsmith.abstraction.enums.MCPatternShape;
6-
import com.laytonsmith.abstraction.enums.MCVersion;
7-
import com.laytonsmith.annotations.abstractionenum;
6+
import com.laytonsmith.core.MSLog;
87
import com.laytonsmith.core.Static;
8+
import com.laytonsmith.core.constructs.Target;
9+
import org.bukkit.Keyed;
910
import org.bukkit.NamespacedKey;
1011
import org.bukkit.Registry;
1112
import org.bukkit.block.banner.PatternType;
1213

13-
@abstractionenum(
14-
implementation = Implementation.Type.BUKKIT,
15-
forAbstractEnum = MCPatternShape.class,
16-
forConcreteEnum = PatternType.class
17-
)
18-
public class BukkitMCPatternShape extends EnumConvertor<MCPatternShape, PatternType> {
14+
import java.util.HashMap;
15+
import java.util.Locale;
16+
import java.util.Map;
1917

20-
private static BukkitMCPatternShape instance;
18+
public class BukkitMCPatternShape extends MCPatternShape<PatternType> {
2119

22-
public static BukkitMCPatternShape getConvertor() {
23-
if(instance == null) {
24-
instance = new BukkitMCPatternShape();
25-
}
26-
if(Static.getServer().getMinecraftVersion().gte(MCVersion.MC1_20_6)) {
27-
// Spigot remaps PatternType.DIAGONAL_RIGHT_MIRROR to DIAGONAL_RIGHT, but that value is also remapped.
28-
// Storing a reference to the pattern allows us to convert back and forth.
29-
instance.diagonalRight = Registry.BANNER_PATTERN.get(NamespacedKey.minecraft("diagonal_right"));
20+
private static final Map<PatternType, MCPatternShape> BUKKIT_MAP = new HashMap<>();
21+
22+
public BukkitMCPatternShape(MCVanillaPatternShape vanillaPatternShape, PatternType pattern) {
23+
super(vanillaPatternShape, pattern);
24+
}
25+
26+
@Override
27+
public String name() {
28+
if(getAbstracted() == MCVanillaPatternShape.UNKNOWN) {
29+
// changed from enum to interface in 1.21, so cannot call methods from PatternType
30+
try {
31+
NamespacedKey key = ReflectionUtils.invokeMethod(Keyed.class, getConcrete(), "getKey");
32+
return key.getKey().toUpperCase(Locale.ROOT);
33+
} catch(ReflectionException ex) {
34+
// probably before 1.20.4, so something went wrong
35+
MSLog.GetLogger().e(MSLog.Tags.GENERAL, "Could not resolve unknown PatternType", Target.UNKNOWN);
36+
}
3037
}
31-
return instance;
38+
return getAbstracted().name();
3239
}
3340

34-
private PatternType diagonalRight;
41+
public static MCPatternShape valueOfConcrete(PatternType test) {
42+
MCPatternShape type = BUKKIT_MAP.get(test);
43+
if(type == null) {
44+
MSLog.GetLogger().w(MSLog.Tags.GENERAL, "PatternType missing in BUKKIT_MAP: " + test, Target.UNKNOWN);
45+
return new BukkitMCPatternShape(MCVanillaPatternShape.UNKNOWN, test);
46+
}
47+
return type;
48+
}
3549

36-
@Override
37-
protected MCPatternShape getAbstractedEnumCustom(PatternType concrete) {
38-
if(Static.getServer().getMinecraftVersion().gte(MCVersion.MC1_20_6)) {
39-
if(concrete == diagonalRight) {
40-
return MCPatternShape.DIAGONAL_RIGHT_MIRROR;
50+
public static void build() {
51+
for(MCVanillaPatternShape v : MCVanillaPatternShape.values()) {
52+
if(v.existsIn(Static.getServer().getMinecraftVersion())) {
53+
PatternType type;
54+
try {
55+
type = getBukkitType(v);
56+
} catch (IllegalArgumentException ex) {
57+
MSLog.GetLogger().w(MSLog.Tags.GENERAL, "Could not find Bukkit PatternType for " + v.name(),
58+
Target.UNKNOWN);
59+
continue;
60+
}
61+
BukkitMCPatternShape wrapper = new BukkitMCPatternShape(v, type);
62+
BUKKIT_MAP.put(type, wrapper);
63+
MAP.put(v.name(), wrapper);
4164
}
42-
switch(concrete) {
43-
case DIAGONAL_UP_RIGHT:
44-
return MCPatternShape.DIAGONAL_RIGHT;
45-
case SMALL_STRIPES:
46-
return MCPatternShape.STRIPE_SMALL;
47-
case DIAGONAL_UP_LEFT:
48-
return MCPatternShape.DIAGONAL_LEFT_MIRROR;
49-
case CIRCLE:
50-
return MCPatternShape.CIRCLE_MIDDLE;
51-
case RHOMBUS:
52-
return MCPatternShape.RHOMBUS_MIDDLE;
53-
case HALF_VERTICAL_RIGHT:
54-
return MCPatternShape.HALF_VERTICAL_MIRROR;
55-
case HALF_HORIZONTAL_BOTTOM:
56-
return MCPatternShape.HALF_HORIZONTAL_MIRROR;
65+
}
66+
try {
67+
for(PatternType type : Registry.BANNER_PATTERN) {
68+
if(!BUKKIT_MAP.containsKey(type)) {
69+
MAP.put(type.getKey().getKey().toUpperCase(Locale.ROOT),
70+
new BukkitMCPatternShape(MCVanillaPatternShape.UNKNOWN, type));
71+
BUKKIT_MAP.put(type, new BukkitMCPatternShape(MCVanillaPatternShape.UNKNOWN, type));
72+
}
5773
}
74+
} catch (IncompatibleClassChangeError ignore) {
75+
// probably before 1.20.4 so we do not have to check for new missing values
5876
}
59-
return super.getAbstractedEnumCustom(concrete);
6077
}
6178

62-
@Override
63-
protected PatternType getConcreteEnumCustom(MCPatternShape abstracted) {
64-
if(Static.getServer().getMinecraftVersion().gte(MCVersion.MC1_20_6)) {
65-
if(abstracted == MCPatternShape.DIAGONAL_RIGHT_MIRROR) {
66-
return instance.diagonalRight;
79+
private static PatternType getBukkitType(MCVanillaPatternShape v) throws IllegalArgumentException {
80+
// changed from enum to interface in 1.21, so cannot call methods from PatternType
81+
try {
82+
String typeName = v.name();
83+
typeName = switch(typeName) {
84+
case "DIAGONAL_RIGHT_MIRROR" -> "diagonal_right";
85+
case "DIAGONAL_RIGHT" -> "diagonal_up_right";
86+
case "STRIPE_SMALL" -> "small_stripes";
87+
case "DIAGONAL_LEFT_MIRROR" -> "diagonal_up_left";
88+
case "CIRCLE_MIDDLE" -> "circle";
89+
case "RHOMBUS_MIDDLE" -> "rhombus";
90+
case "HALF_VERTICAL_MIRROR" -> "half_vertical_right";
91+
case "HALF_HORIZONTAL_MIRROR" -> "half_horizontal_bottom";
92+
default -> typeName.toLowerCase(Locale.ROOT);
93+
};
94+
PatternType t = Registry.BANNER_PATTERN.get(NamespacedKey.minecraft(typeName));
95+
if(t == null) {
96+
throw new IllegalArgumentException();
97+
}
98+
return t;
99+
} catch(NoSuchFieldError ex) {
100+
// probably before 1.20.4 when registry field was added
101+
try {
102+
Class cls = Class.forName("org.bukkit.block.banner.PatternType");
103+
return ReflectionUtils.invokeMethod(cls, null, "valueOf",
104+
new Class[]{String.class}, new Object[]{v.name()});
105+
} catch (ClassNotFoundException exc) {
106+
throw new IllegalArgumentException();
67107
}
68108
}
69-
return PatternType.valueOf(abstracted.name());
70109
}
71110
}

src/main/java/com/laytonsmith/commandhelper/CommandHelperPlugin.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCEntityType;
4848
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCLegacyMaterial;
4949
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCParticle;
50+
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCPatternShape;
5051
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCPotionEffectType;
5152
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCPotionType;
5253
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCProfession;
@@ -316,6 +317,7 @@ public void run() {
316317
BukkitMCLegacyMaterial.build();
317318
BukkitMCPotionType.build();
318319
BukkitMCEnchantment.build();
320+
BukkitMCPatternShape.build();
319321
if(myServer.getMinecraftVersion().gte(MCVersion.MC1_20)) {
320322
BukkitMCTrimMaterial.build();
321323
BukkitMCTrimPattern.build();

0 commit comments

Comments
 (0)