Skip to content

Commit

Permalink
Update banner pattern back compat after Spigot changes
Browse files Browse the repository at this point in the history
PatternType was changed to an interface, which would have broke backwards compatibility.
  • Loading branch information
PseudoKnight committed Jul 29, 2024
1 parent 1a9ad32 commit 3999722
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCEntityType;
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCEquipmentSlot;
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCLegacyMaterial;
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCPatternShape;
import com.laytonsmith.annotations.convert;
import com.laytonsmith.commandhelper.CommandHelperPlugin;
import com.laytonsmith.core.LogLevel;
Expand Down Expand Up @@ -125,6 +124,7 @@
import org.bukkit.block.Sign;
import org.bukkit.block.Skull;
import org.bukkit.block.banner.Pattern;
import org.bukkit.block.banner.PatternType;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
Expand Down Expand Up @@ -771,7 +771,7 @@ public MCColor GetColor(String colorName, Target t) throws CREFormatException {
@Override
public MCPattern GetPattern(MCDyeColor color, MCPatternShape shape) {
return new BukkitMCPattern(new Pattern(BukkitMCDyeColor.getConvertor().getConcreteEnum(color),
BukkitMCPatternShape.getConvertor().getConcreteEnum(shape)));
(PatternType) shape.getConcrete()));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public MCDyeColor getColor() {

@Override
public MCPatternShape getShape() {
return BukkitMCPatternShape.getConvertor().getAbstractedEnum(pattern.getPattern());
return BukkitMCPatternShape.valueOfConcrete(pattern.getPattern());
}

@Override
Expand Down
172 changes: 125 additions & 47 deletions src/main/java/com/laytonsmith/abstraction/enums/MCPatternShape.java
Original file line number Diff line number Diff line change
@@ -1,50 +1,128 @@
package com.laytonsmith.abstraction.enums;

import com.laytonsmith.annotations.MEnum;

@MEnum("com.commandhelper.PatternShape")
public enum MCPatternShape {
BASE,
BORDER,
BRICKS,
CIRCLE_MIDDLE,
CREEPER,
CROSS,
CURLY_BORDER,
DIAGONAL_LEFT,
DIAGONAL_LEFT_MIRROR,
DIAGONAL_RIGHT,
DIAGONAL_RIGHT_MIRROR,
FLOW,
FLOWER,
GLOBE,
GRADIENT,
GRADIENT_UP,
GUSTER,
HALF_HORIZONTAL,
HALF_HORIZONTAL_MIRROR,
HALF_VERTICAL,
HALF_VERTICAL_MIRROR,
MOJANG,
PIGLIN,
RHOMBUS_MIDDLE,
SKULL,
SQUARE_BOTTOM_LEFT,
SQUARE_BOTTOM_RIGHT,
SQUARE_TOP_LEFT,
SQUARE_TOP_RIGHT,
STRAIGHT_CROSS,
STRIPE_BOTTOM,
STRIPE_CENTER,
STRIPE_DOWNLEFT,
STRIPE_DOWNRIGHT,
STRIPE_LEFT,
STRIPE_MIDDLE,
STRIPE_RIGHT,
STRIPE_SMALL,
STRIPE_TOP,
TRIANGLE_BOTTOM,
TRIANGLE_TOP,
TRIANGLES_BOTTOM,
TRIANGLES_TOP
import com.laytonsmith.PureUtilities.ClassLoading.DynamicEnum;
import com.laytonsmith.annotations.MDynamicEnum;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

@MDynamicEnum("com.commandhelper.PatternShape")
public abstract class MCPatternShape<Concrete> extends DynamicEnum<MCPatternShape.MCVanillaPatternShape, Concrete> {

protected static final Map<String, MCPatternShape> MAP = new HashMap<>();

public MCPatternShape(MCVanillaPatternShape mcVanillaPatternShape, Concrete concrete) {
super(mcVanillaPatternShape, concrete);
}

public static MCPatternShape valueOf(String test) throws IllegalArgumentException {
MCPatternShape shape = MAP.get(test);
if(shape == null) {
throw new IllegalArgumentException("Unknown pattern shape: " + test);
}
return shape;
}

/**
* @return Names of available patterns
*/
public static Set<String> types() {
if(MAP.isEmpty()) { // docs mode
Set<String> dummy = new HashSet<>();
for(final MCVanillaPatternShape t : MCVanillaPatternShape.values()) {
if(t.existsIn(MCVersion.CURRENT)) {
dummy.add(t.name());
}
}
return dummy;
}
return MAP.keySet();
}

/**
* @return Our own MCPatternShape list
*/
public static List<MCPatternShape> values() {
if(MAP.isEmpty()) { // docs mode
ArrayList<MCPatternShape> dummy = new ArrayList<>();
for(final MCPatternShape.MCVanillaPatternShape p : MCPatternShape.MCVanillaPatternShape.values()) {
if(!p.existsIn(MCVersion.CURRENT)) {
continue;
}
dummy.add(new MCPatternShape<>(p, null) {
@Override
public String name() {
return p.name();
}
});
}
return dummy;
}
return new ArrayList<>(MAP.values());
}

public enum MCVanillaPatternShape {
BASE,
BORDER,
BRICKS,
CIRCLE_MIDDLE,
CREEPER,
CROSS,
CURLY_BORDER,
DIAGONAL_LEFT,
DIAGONAL_LEFT_MIRROR,
DIAGONAL_RIGHT,
DIAGONAL_RIGHT_MIRROR,
FLOW(MCVersion.MC1_21),
FLOWER,
GLOBE,
GRADIENT,
GRADIENT_UP,
GUSTER(MCVersion.MC1_21),
HALF_HORIZONTAL,
HALF_HORIZONTAL_MIRROR,
HALF_VERTICAL,
HALF_VERTICAL_MIRROR,
MOJANG,
PIGLIN,
RHOMBUS_MIDDLE,
SKULL,
SQUARE_BOTTOM_LEFT,
SQUARE_BOTTOM_RIGHT,
SQUARE_TOP_LEFT,
SQUARE_TOP_RIGHT,
STRAIGHT_CROSS,
STRIPE_BOTTOM,
STRIPE_CENTER,
STRIPE_DOWNLEFT,
STRIPE_DOWNRIGHT,
STRIPE_LEFT,
STRIPE_MIDDLE,
STRIPE_RIGHT,
STRIPE_SMALL,
STRIPE_TOP,
TRIANGLE_BOTTOM,
TRIANGLE_TOP,
TRIANGLES_BOTTOM,
TRIANGLES_TOP,
UNKNOWN(MCVersion.NEVER);

final MCVersion added;

MCVanillaPatternShape() {
this.added = MCVersion.MC1_8;
}

MCVanillaPatternShape(MCVersion version) {
this.added = version;
}

public boolean existsIn(MCVersion version) {
return version.gte(added);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,71 +1,110 @@
package com.laytonsmith.abstraction.enums.bukkit;

import com.laytonsmith.abstraction.Implementation;
import com.laytonsmith.abstraction.enums.EnumConvertor;
import com.laytonsmith.PureUtilities.Common.ReflectionUtils;
import com.laytonsmith.PureUtilities.Common.ReflectionUtils.ReflectionException;
import com.laytonsmith.abstraction.enums.MCPatternShape;
import com.laytonsmith.abstraction.enums.MCVersion;
import com.laytonsmith.annotations.abstractionenum;
import com.laytonsmith.core.MSLog;
import com.laytonsmith.core.Static;
import com.laytonsmith.core.constructs.Target;
import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.block.banner.PatternType;

@abstractionenum(
implementation = Implementation.Type.BUKKIT,
forAbstractEnum = MCPatternShape.class,
forConcreteEnum = PatternType.class
)
public class BukkitMCPatternShape extends EnumConvertor<MCPatternShape, PatternType> {
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

private static BukkitMCPatternShape instance;
public class BukkitMCPatternShape extends MCPatternShape<PatternType> {

public static BukkitMCPatternShape getConvertor() {
if(instance == null) {
instance = new BukkitMCPatternShape();
}
if(Static.getServer().getMinecraftVersion().gte(MCVersion.MC1_20_6)) {
// Spigot remaps PatternType.DIAGONAL_RIGHT_MIRROR to DIAGONAL_RIGHT, but that value is also remapped.
// Storing a reference to the pattern allows us to convert back and forth.
instance.diagonalRight = Registry.BANNER_PATTERN.get(NamespacedKey.minecraft("diagonal_right"));
private static final Map<PatternType, MCPatternShape> BUKKIT_MAP = new HashMap<>();

public BukkitMCPatternShape(MCVanillaPatternShape vanillaPatternShape, PatternType pattern) {
super(vanillaPatternShape, pattern);
}

@Override
public String name() {
if(getAbstracted() == MCVanillaPatternShape.UNKNOWN) {
// changed from enum to interface in 1.21, so cannot call methods from PatternType
try {
NamespacedKey key = ReflectionUtils.invokeMethod(Keyed.class, getConcrete(), "getKey");
return key.getKey().toUpperCase(Locale.ROOT);
} catch(ReflectionException ex) {
// probably before 1.20.4, so something went wrong
MSLog.GetLogger().e(MSLog.Tags.GENERAL, "Could not resolve unknown PatternType", Target.UNKNOWN);
}
}
return instance;
return getAbstracted().name();
}

private PatternType diagonalRight;
public static MCPatternShape valueOfConcrete(PatternType test) {
MCPatternShape type = BUKKIT_MAP.get(test);
if(type == null) {
MSLog.GetLogger().w(MSLog.Tags.GENERAL, "PatternType missing in BUKKIT_MAP: " + test, Target.UNKNOWN);
return new BukkitMCPatternShape(MCVanillaPatternShape.UNKNOWN, test);
}
return type;
}

@Override
protected MCPatternShape getAbstractedEnumCustom(PatternType concrete) {
if(Static.getServer().getMinecraftVersion().gte(MCVersion.MC1_20_6)) {
if(concrete == diagonalRight) {
return MCPatternShape.DIAGONAL_RIGHT_MIRROR;
public static void build() {
for(MCVanillaPatternShape v : MCVanillaPatternShape.values()) {
if(v.existsIn(Static.getServer().getMinecraftVersion())) {
PatternType type;
try {
type = getBukkitType(v);
} catch (IllegalArgumentException ex) {
MSLog.GetLogger().w(MSLog.Tags.GENERAL, "Could not find Bukkit PatternType for " + v.name(),
Target.UNKNOWN);
continue;
}
BukkitMCPatternShape wrapper = new BukkitMCPatternShape(v, type);
BUKKIT_MAP.put(type, wrapper);
MAP.put(v.name(), wrapper);
}
switch(concrete) {
case DIAGONAL_UP_RIGHT:
return MCPatternShape.DIAGONAL_RIGHT;
case SMALL_STRIPES:
return MCPatternShape.STRIPE_SMALL;
case DIAGONAL_UP_LEFT:
return MCPatternShape.DIAGONAL_LEFT_MIRROR;
case CIRCLE:
return MCPatternShape.CIRCLE_MIDDLE;
case RHOMBUS:
return MCPatternShape.RHOMBUS_MIDDLE;
case HALF_VERTICAL_RIGHT:
return MCPatternShape.HALF_VERTICAL_MIRROR;
case HALF_HORIZONTAL_BOTTOM:
return MCPatternShape.HALF_HORIZONTAL_MIRROR;
}
try {
for(PatternType type : Registry.BANNER_PATTERN) {
if(!BUKKIT_MAP.containsKey(type)) {
MAP.put(type.getKey().getKey().toUpperCase(Locale.ROOT),
new BukkitMCPatternShape(MCVanillaPatternShape.UNKNOWN, type));
BUKKIT_MAP.put(type, new BukkitMCPatternShape(MCVanillaPatternShape.UNKNOWN, type));
}
}
} catch (IncompatibleClassChangeError ignore) {
// probably before 1.20.4 so we do not have to check for new missing values
}
return super.getAbstractedEnumCustom(concrete);
}

@Override
protected PatternType getConcreteEnumCustom(MCPatternShape abstracted) {
if(Static.getServer().getMinecraftVersion().gte(MCVersion.MC1_20_6)) {
if(abstracted == MCPatternShape.DIAGONAL_RIGHT_MIRROR) {
return instance.diagonalRight;
private static PatternType getBukkitType(MCVanillaPatternShape v) throws IllegalArgumentException {
// changed from enum to interface in 1.21, so cannot call methods from PatternType
try {
String typeName = v.name();
typeName = switch(typeName) {
case "DIAGONAL_RIGHT_MIRROR" -> "diagonal_right";
case "DIAGONAL_RIGHT" -> "diagonal_up_right";
case "STRIPE_SMALL" -> "small_stripes";
case "DIAGONAL_LEFT_MIRROR" -> "diagonal_up_left";
case "CIRCLE_MIDDLE" -> "circle";
case "RHOMBUS_MIDDLE" -> "rhombus";
case "HALF_VERTICAL_MIRROR" -> "half_vertical_right";
case "HALF_HORIZONTAL_MIRROR" -> "half_horizontal_bottom";
default -> typeName.toLowerCase(Locale.ROOT);
};
PatternType t = Registry.BANNER_PATTERN.get(NamespacedKey.minecraft(typeName));
if(t == null) {
throw new IllegalArgumentException();
}
return t;
} catch(NoSuchFieldError ex) {
// probably before 1.20.4 when registry field was added
try {
Class cls = Class.forName("org.bukkit.block.banner.PatternType");
return ReflectionUtils.invokeMethod(cls, null, "valueOf",
new Class[]{String.class}, new Object[]{v.name()});
} catch (ClassNotFoundException exc) {
throw new IllegalArgumentException();
}
}
return PatternType.valueOf(abstracted.name());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCEntityType;
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCLegacyMaterial;
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCParticle;
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCPatternShape;
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCPotionEffectType;
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCPotionType;
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCProfession;
Expand Down Expand Up @@ -316,6 +317,7 @@ public void run() {
BukkitMCLegacyMaterial.build();
BukkitMCPotionType.build();
BukkitMCEnchantment.build();
BukkitMCPatternShape.build();
if(myServer.getMinecraftVersion().gte(MCVersion.MC1_20)) {
BukkitMCTrimMaterial.build();
BukkitMCTrimPattern.build();
Expand Down

0 comments on commit 3999722

Please sign in to comment.