|
1 | 1 | package com.laytonsmith.abstraction.enums.bukkit; |
2 | 2 |
|
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; |
5 | 5 | 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; |
8 | 7 | import com.laytonsmith.core.Static; |
| 8 | +import com.laytonsmith.core.constructs.Target; |
| 9 | +import org.bukkit.Keyed; |
9 | 10 | import org.bukkit.NamespacedKey; |
10 | 11 | import org.bukkit.Registry; |
11 | 12 | import org.bukkit.block.banner.PatternType; |
12 | 13 |
|
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; |
19 | 17 |
|
20 | | - private static BukkitMCPatternShape instance; |
| 18 | +public class BukkitMCPatternShape extends MCPatternShape<PatternType> { |
21 | 19 |
|
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 | + } |
30 | 37 | } |
31 | | - return instance; |
| 38 | + return getAbstracted().name(); |
32 | 39 | } |
33 | 40 |
|
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 | + } |
35 | 49 |
|
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); |
41 | 64 | } |
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 | + } |
57 | 73 | } |
| 74 | + } catch (IncompatibleClassChangeError ignore) { |
| 75 | + // probably before 1.20.4 so we do not have to check for new missing values |
58 | 76 | } |
59 | | - return super.getAbstractedEnumCustom(concrete); |
60 | 77 | } |
61 | 78 |
|
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(); |
67 | 107 | } |
68 | 108 | } |
69 | | - return PatternType.valueOf(abstracted.name()); |
70 | 109 | } |
71 | 110 | } |
0 commit comments