Search code examples
javapluginsversionminecraft

Minecraft plugin adaptation of WHITE_STAINED_GLASS_PANE to versions after 1.13 and before 1.12


I'm making a plugin of Minecraft.

public final static ItemStack WHITE_STAINED_GLASS_PANE = (IS_LEGACY ? new ItemStack(Material.valueOf("STAINED_GLASS_PANE"), 1, (short) 0) : new ItemStack(Material.WHITE_STAINED_GLASS_PANE));

I have adapted the version. But when I run the plugin, an error occurs:

Fatal error trying to convert ***.class
org.bukkit.plugin.AuthorNagException: No legacy enum constant for WHITE_STAINED_GLASS_PANE. Did you forget to define a modern (1.13+) api-version in your plugin.yml?

My code can run smoothly, but I want to remove this error message, what code should I insert?


I'm using maven to compile.
These are code snippets that I think are relevant to this issue:

// the main class snippet
public static ItemStack createItem(String name, String legacy, short color) {
   return IS_LEGACY ? new ItemStack(Material.valueOf(legacy), 1, color) : new ItemStack(Material.valueOf(name));
}
public final static ItemStack WHITE_STAINED_GLASS_PANE = createItem("WHITE_STAINED_GLASS_PANE", "STAINED_GLASS_PANE"), (short) 0);
# src/main/resources/plugin.yml
name: name
author: autext
description: A plugin of Minecraft
main: me.autext.abcde.ABCDE
version: ${project.version}

the definition of IS_LEGACY:

class VersionString {

    private final int major;
    private final int minor;
    private final int patch;

    public VersionString(String version) {
        String[] parts = version.split("\\.");
        this.major = Integer.parseInt(parts[0]);
        this.minor = Integer.parseInt(parts[1]);
        this.patch = parts.length > 2 ? Integer.parseInt(parts[2]) : 0;
    }

    public boolean isLowerThan(String otherVersion) {
        VersionString other = new VersionString(otherVersion);
        if (this.major < other.major) {
            return true;
        }
        if (this.major > other.major) {
            return false;
        }
        if (this.minor < other.minor) {
            return true;
        }
        if (this.minor > other.minor) {
            return false;
        }
        return this.patch < other.patch;
    }
}
private final static Boolean IS_LEGACY = new VersionString(Bukkit.getVersion().replaceAll("[^0-9.]", "")).isLowerThan("1.13");

Solution

  • You made a Java issue. When using constant as X.A, even if they are not used, they are intepreted by the code. It means Java will try to get the variable (in your case, get the enum constant WHITE_STAINED_GLASS_PANE.

    To fix it, you can simply use Material.valueOf("WHITE_STAINED_GLASS_PANE") as you did for the legacy.


    Another way is to made an utils method that will chose it, for example:

    public static ItemStack createItem(String name, String legacy, short color) {
       return IS_LEGACY ? new ItemStack(Material.valueOf(legacy), 1, color) : new ItemStack(Material.valueOf(name));
    }
    

    Then use it like:

    public final static ItemStack WHITE_STAINED_GLASS_PANE = createItem("WHITE_STAINED_GLASS_PANE", "STAINED_GLASS_PANE"), (short) 0);
    

    This will make it easier for you if you want to have multiple colored glass pane.


    About the updated IS_LEGACY variable

    I tested your code, and on some version, Bukkit.getVersion() return something like this: git-paper-123456 (MC: 1.12). I think you should check for "*MC: *" value. As I'm personnally getting version "16181.12.2" got "git-Paper-1618 (MC: 1.12.2)".

    You can use this regex: MC: (\\d+\\.\\d+(\\.\\d+)?).

    With this code it works fine for me:

    private final static Boolean IS_LEGACY;
    public static final String REGEX = "MC: (\\d+\\.\\d+(\\.\\d+)?)", VERSION;
    static {
        Pattern pattern = java.util.regex.Pattern.compile(REGEX);
        Matcher matcher = pattern.matcher(Bukkit.getVersion());
    
        if (matcher.find()) {
            VERSION = matcher.group(1);
            IS_LEGACY = new VersionString(matcher.group(1)).isLowerThan("1.13");
        } else {
            VERSION = "Unknown";
            IS_LEGACY = true;
        }
    }
    

    You can learn more about the static {} keyword here.

    You should also changed your plugin.yml. You have to set api-version: 1.13 to fix it. This doesn't break for 1.12 and lower.

    Here would be the final file:

    name: name
    author: autext
    description: A plugin of Minecraft
    main: me.autext.abcde.ABCDE
    version: ${project.version}
    api-version: 1.13