Skip to content

Commit 04ec9ef

Browse files
committed
Fix enum back compat after Spigot changes
Villager professions, cat types, and frog types were changed from enums to interfaces. If built against these changes, they break backwards binary compatibility when invoking their methods. So reflection was needed. Used Registry where possible, but until 1.20.4 Cat.Type didn't extend Keyed and wasn't added to the Registry.
1 parent f95e5af commit 04ec9ef

File tree

3 files changed

+61
-10
lines changed

3 files changed

+61
-10
lines changed

src/main/java/com/laytonsmith/abstraction/bukkit/entities/BukkitMCCat.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
package com.laytonsmith.abstraction.bukkit.entities;
22

3+
import com.laytonsmith.PureUtilities.Common.ReflectionUtils;
4+
import com.laytonsmith.PureUtilities.Common.ReflectionUtils.ReflectionException;
35
import com.laytonsmith.abstraction.entities.MCCat;
46
import com.laytonsmith.abstraction.enums.MCCatType;
57
import com.laytonsmith.abstraction.enums.MCDyeColor;
68
import org.bukkit.DyeColor;
9+
import org.bukkit.Keyed;
10+
import org.bukkit.NamespacedKey;
11+
import org.bukkit.Registry;
712
import org.bukkit.entity.Cat;
813
import org.bukkit.entity.Entity;
914

15+
import java.util.Locale;
16+
1017
public class BukkitMCCat extends BukkitMCTameable implements MCCat {
1118

1219
Cat c;
@@ -38,11 +45,33 @@ public void setSitting(boolean sitting) {
3845

3946
@Override
4047
public MCCatType getCatType() {
41-
return MCCatType.valueOf(c.getCatType().name());
48+
// changed from enum to interface in 1.21
49+
try {
50+
NamespacedKey key = ReflectionUtils.invokeMethod(Keyed.class, c.getCatType(), "getKey");
51+
return MCCatType.valueOf(key.getKey().toUpperCase(Locale.ROOT));
52+
} catch(ReflectionException ex) {
53+
// probably before 1.20.4
54+
return MCCatType.valueOf(ReflectionUtils.invokeMethod(Enum.class, c.getCatType(), "name"));
55+
}
4256
}
4357

4458
@Override
4559
public void setCatType(MCCatType type) {
46-
c.setCatType(Cat.Type.valueOf(type.name()));
60+
try {
61+
Cat.Type t = Registry.CAT_VARIANT.get(NamespacedKey.minecraft(type.name().toLowerCase(Locale.ROOT)));
62+
if(t == null) {
63+
return;
64+
}
65+
c.setCatType(t);
66+
} catch(NoSuchFieldError ex) {
67+
// probably before 1.20.4
68+
try {
69+
Class cls = Class.forName("org.bukkit.entity.Cat$Type");
70+
c.setCatType(ReflectionUtils.invokeMethod(cls, null, "valueOf",
71+
new Class[]{String.class}, new Object[]{type.name()}));
72+
} catch (ClassNotFoundException exc) {
73+
throw new RuntimeException(exc);
74+
}
75+
}
4776
}
4877
}

src/main/java/com/laytonsmith/abstraction/bukkit/entities/BukkitMCFrog.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package com.laytonsmith.abstraction.bukkit.entities;
22

3+
import com.laytonsmith.PureUtilities.Common.ReflectionUtils;
34
import com.laytonsmith.abstraction.MCEntity;
45
import com.laytonsmith.abstraction.bukkit.BukkitConvertor;
56
import com.laytonsmith.abstraction.entities.MCFrog;
7+
import org.bukkit.Keyed;
8+
import org.bukkit.NamespacedKey;
9+
import org.bukkit.Registry;
610
import org.bukkit.entity.Entity;
711
import org.bukkit.entity.Frog;
8-
import org.bukkit.entity.Frog.Variant;
12+
13+
import java.util.Locale;
914

1015
public class BukkitMCFrog extends BukkitMCAnimal implements MCFrog {
1116

@@ -23,12 +28,17 @@ public Frog getHandle() {
2328

2429
@Override
2530
public MCFrogType getFrogType() {
26-
return MCFrogType.valueOf(f.getVariant().name());
31+
// changed from enum to interface in 1.21
32+
NamespacedKey key = ReflectionUtils.invokeMethod(Keyed.class, f.getVariant(), "getKey");
33+
return MCFrogType.valueOf(key.getKey().toUpperCase(Locale.ROOT));
2734
}
2835

2936
@Override
3037
public void setFrogType(MCFrogType type) {
31-
f.setVariant(Variant.valueOf(type.name()));
38+
Frog.Variant v = Registry.FROG_VARIANT.get(NamespacedKey.minecraft(type.name().toLowerCase(Locale.ROOT)));
39+
if(v != null) {
40+
f.setVariant(v);
41+
}
3242
}
3343

3444
@Override

src/main/java/com/laytonsmith/abstraction/enums/bukkit/BukkitMCProfession.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
package com.laytonsmith.abstraction.enums.bukkit;
22

3+
import com.laytonsmith.PureUtilities.Common.ReflectionUtils;
34
import com.laytonsmith.abstraction.enums.MCProfession;
45
import com.laytonsmith.core.MSLog;
56
import com.laytonsmith.core.Static;
67
import com.laytonsmith.core.constructs.Target;
8+
import org.bukkit.Keyed;
9+
import org.bukkit.NamespacedKey;
10+
import org.bukkit.Registry;
711
import org.bukkit.entity.Villager;
812

913
import java.util.HashMap;
14+
import java.util.Locale;
1015
import java.util.Map;
1116

1217
public class BukkitMCProfession extends MCProfession<Villager.Profession> {
@@ -19,14 +24,20 @@ public BukkitMCProfession(MCVanillaProfession vanillaProfession, Villager.Profes
1924

2025
@Override
2126
public String name() {
22-
return getAbstracted() == MCVanillaProfession.NONE ? getConcrete().name() : getAbstracted().name();
27+
if(getAbstracted() == MCVanillaProfession.UNKNOWN) {
28+
// changed from enum to interface in 1.21
29+
NamespacedKey key = ReflectionUtils.invokeMethod(Keyed.class, getConcrete(), "getKey");
30+
return key.getKey().toUpperCase(Locale.ROOT);
31+
}
32+
return getAbstracted().name();
2333
}
2434

2535
public static MCProfession valueOfConcrete(Villager.Profession test) {
2636
MCProfession profession = BUKKIT_MAP.get(test);
2737
if(profession == null) {
38+
NamespacedKey key = ReflectionUtils.invokeMethod(Keyed.class, test, "getKey");
2839
MSLog.GetLogger().e(MSLog.Tags.GENERAL, "Bukkit Villager Profession missing in BUKKIT_MAP: "
29-
+ test.name(), Target.UNKNOWN);
40+
+ key.getKey().toUpperCase(Locale.ROOT), Target.UNKNOWN);
3041
return new BukkitMCProfession(MCVanillaProfession.UNKNOWN, test);
3142
}
3243
return profession;
@@ -48,15 +59,16 @@ public static void build() {
4859
BUKKIT_MAP.put(profession, wrapper);
4960
}
5061
}
51-
for(Villager.Profession pr : Villager.Profession.values()) {
62+
for(Villager.Profession pr : Registry.VILLAGER_PROFESSION) {
5263
if(pr != null && !BUKKIT_MAP.containsKey(pr)) {
53-
MAP.put(pr.name(), new BukkitMCProfession(MCVanillaProfession.UNKNOWN, pr));
64+
NamespacedKey key = ReflectionUtils.invokeMethod(Keyed.class, pr, "getKey");
65+
MAP.put(key.getKey().toUpperCase(Locale.ROOT), new BukkitMCProfession(MCVanillaProfession.UNKNOWN, pr));
5466
BUKKIT_MAP.put(pr, new BukkitMCProfession(MCVanillaProfession.UNKNOWN, pr));
5567
}
5668
}
5769
}
5870

5971
private static Villager.Profession getBukkitType(MCVanillaProfession v) {
60-
return Villager.Profession.valueOf(v.name());
72+
return Registry.VILLAGER_PROFESSION.get(NamespacedKey.minecraft(v.name().toLowerCase(Locale.ROOT)));
6173
}
6274
}

0 commit comments

Comments
 (0)