NAMES = new HashMap<>();
- /**
- * XMaterial Paradox (Duplication Check)
- *
- * A map of duplicated material names in 1.13 and 1.12 that will conflict with the legacy names.
- * Values are the new material names. This map also contains illegal elements. Check the static initializer for more info.
- *
- * Duplicates are normally only checked by keys, not values.
- *
- * @since 3.0.0
- */
- private static final Map DUPLICATED = new EnumMap<>(XMaterial.class);
/**
* Guava (Google Core Libraries for Java)'s cache for performance and timed caches.
* For strings that match a certain XMaterial. Mostly cached for configs.
@@ -1270,15 +1256,6 @@ public enum XMaterial {
private static final Cache NAME_CACHE = CacheBuilder.newBuilder()
.expireAfterAccess(1, TimeUnit.HOURS)
.build();
- /**
- * Guava (Google Core Libraries for Java)'s cache for performance and timed caches.
- * For XMaterials that are already parsed once.
- *
- * @since 3.0.0
- */
- private static final Cache> PARSED_CACHE = CacheBuilder.newBuilder()
- .expireAfterAccess(30, TimeUnit.MINUTES)
- .build();
/**
* This is used for {@link #isOneOf(Collection)}
@@ -1298,19 +1275,6 @@ public enum XMaterial {
}
}
});
- /**
- * The current version of the server in the a form of a major version.
- * If the static initialization for this fails, you know something's wrong with the server software.
- *
- * @since 1.0.0
- */
- private static final int VERSION = Integer.parseInt(getMajorVersion(Bukkit.getVersion()).substring(2));
- /**
- * Cached result if the server version is after the v1.13 flattening update.
- *
- * @since 3.0.0
- */
- private static final boolean ISFLAT = supports(13);
/**
* The maximum data value in the pre-flattening update which belongs to {@link #VILLAGER_SPAWN_EGG}
* https://minecraftitemids.com/types/spawn-egg
@@ -1332,37 +1296,38 @@ public enum XMaterial {
* @since 8.1.0
*/
private static final short MAX_ID = 2267;
-
- static {
- DUPLICATED.put(MELON, MELON_SLICE);
- DUPLICATED.put(CARROT, CARROTS);
- DUPLICATED.put(POTATO, POTATOES);
- DUPLICATED.put(BEETROOT, BEETROOTS);
- DUPLICATED.put(BROWN_MUSHROOM, BROWN_MUSHROOM_BLOCK);
- DUPLICATED.put(BRICK, BRICKS);
- DUPLICATED.put(NETHER_BRICK, NETHER_BRICKS);
-
- // Illegal Elements
- // Since both 1.12 and 1.13 have _DOOR XMaterial will use it
- // for 1.12 to parse the material, but it needs _DOOR_ITEM.
- // We'll trick XMaterial into thinking this needs to be parsed
- // using the old methods.
- // Some of these materials have their enum name added to the legacy list as well.
- DUPLICATED.put(DARK_OAK_DOOR, DARK_OAK_DOOR);
- DUPLICATED.put(ACACIA_DOOR, ACACIA_DOOR);
- DUPLICATED.put(BIRCH_DOOR, BIRCH_DOOR);
- DUPLICATED.put(JUNGLE_DOOR, JUNGLE_DOOR);
- DUPLICATED.put(SPRUCE_DOOR, SPRUCE_DOOR);
-
- DUPLICATED.put(CAULDRON, CAULDRON);
- DUPLICATED.put(BREWING_STAND, BREWING_STAND);
- DUPLICATED.put(FLOWER_POT, FLOWER_POT);
- }
+ /**
+ * XMaterial Paradox (Duplication Check)
+ *
+ * A set of duplicated material names in 1.13 and 1.12 that will conflict with the legacy names.
+ * Values are the new material names. This map also contains illegal elements. Check the static initializer for more info.
+ *
+ * Duplications are not useful at all in versions above the flattening update {@link Data#ISFLAT}
+ * This set is only used for matching materials, for parsing refer to {@link #isDuplicated()}
+ *
+ * @since 3.0.0
+ */
+ private static final Set DUPLICATED;
static {
for (XMaterial material : VALUES) NAMES.put(material.name(), material);
}
+ static {
+ if (Data.ISFLAT) {
+ // It's not needed at all if it's the newer version. We can save some memory.
+ DUPLICATED = null;
+ } else {
+ // MELON_SLICE, CARROTS, POTATOES, BEETROOTS, GRASS_BLOCK, BRICKS, NETHER_BRICKS, BROWN_MUSHROOM
+ // Using the constructor to add elements will decide to allocate more size which we don't need.
+ DUPLICATED = new HashSet<>(4);
+ DUPLICATED.add(GRASS.name());
+ DUPLICATED.add(MELON.name());
+ DUPLICATED.add(BRICK.name());
+ DUPLICATED.add(NETHER_BRICK.name());
+ }
+ }
+
/**
* The data value of this material https://minecraft.gamepedia.com/Java_Edition_data_values/Pre-flattening
* It's never a negative number.
@@ -1373,6 +1338,7 @@ public enum XMaterial {
/**
* The version that this material was added in, otherwise 0 if the version is not recorded.
*
+ * @see #getMaterialVersion()
* @since 7.0.0
*/
private final byte version;
@@ -1383,11 +1349,28 @@ public enum XMaterial {
*/
@Nonnull
private final String[] legacy;
+ /**
+ * The cached Bukkit parsed material.
+ *
+ * @see #parseMaterial()
+ * @since 9.0.0
+ */
+ @Nullable
+ private final Material material;
XMaterial(int data, int version, @Nonnull String... legacy) {
this.data = (byte) data;
this.version = (byte) version;
this.legacy = legacy;
+
+ Material mat = null;
+ if ((!Data.ISFLAT && this.isDuplicated()) || (mat = Material.getMaterial(this.name())) == null) {
+ for (int i = legacy.length - 1; i >= 0; i--) {
+ mat = Material.getMaterial(legacy[i]);
+ if (mat != null) break;
+ }
+ }
+ this.material = mat;
}
XMaterial(int data, @Nonnull String... legacy) {
@@ -1420,11 +1403,11 @@ public enum XMaterial {
* @since 1.0.0
*/
public static boolean isNewVersion() {
- return ISFLAT;
+ return Data.ISFLAT;
}
/**
- * This is just an extra method that method that can be used for many cases.
+ * This is just an extra method that can be used for many cases.
* It can be used in {@link org.bukkit.event.player.PlayerInteractEvent}
* or when accessing {@link org.bukkit.entity.Player#getMainHand()},
* or other compatibility related methods.
@@ -1442,9 +1425,11 @@ public enum XMaterial {
}
/**
- * Gets the {@link XMaterial} with this name without throwing an exception.
+ * Gets the XMaterial with this name similar to {@link #valueOf(String)}
+ * without throwing an exception.
*
* @param name the name of the material.
+ *
* @return an optional that can be empty.
* @since 5.1.0
*/
@@ -1461,7 +1446,7 @@ public enum XMaterial {
* @since 2.0.0
*/
public static int getVersion() {
- return VERSION;
+ return Data.VERSION;
}
/**
@@ -1489,9 +1474,11 @@ public enum XMaterial {
}
/**
- * Parses the given material name as an XMaterial with unspecified data value.
+ * Parses the given material name as an XMaterial with a given data
+ * value in the string if attached. Check {@link #matchXMaterialWithData(String)} for more info.
*
* @see #matchXMaterialWithData(String)
+ * @see #matchDefinedXMaterial(String, byte)
* @since 2.0.0
*/
@Nonnull
@@ -1513,6 +1500,7 @@ public enum XMaterial {
*
*
* @param name the material string that consists of the material name, data and separator character.
+ *
* @return the parsed XMaterial.
* @see #matchXMaterial(String)
* @since 3.0.0
@@ -1522,7 +1510,6 @@ public enum XMaterial {
int index = name.indexOf(':');
if (index != -1) {
String mat = format(name.substring(0, index));
-
try {
// We don't use Byte.parseByte because we have our own range check.
byte data = (byte) Integer.parseInt(StringUtils.deleteWhitespace(name.substring(index + 1)));
@@ -1551,9 +1538,11 @@ public enum XMaterial {
}
/**
- * Parses the given item as an XMaterial using its material and data value (durability).
+ * Parses the given item as an XMaterial using its material and data value (durability)
+ * if not a damageable item {@link ItemStack#getDurability()}.
*
* @param item the ItemStack to match.
+ *
* @return an XMaterial if matched any.
* @throws IllegalArgumentException may be thrown as an unexpected exception.
* @see #matchXMaterial(Material)
@@ -1564,10 +1553,13 @@ public enum XMaterial {
public static XMaterial matchXMaterial(@Nonnull ItemStack item) {
Objects.requireNonNull(item, "Cannot match null ItemStack");
String material = item.getType().name();
- byte data = (byte) (ISFLAT || item.getType().getMaxDurability() > 0 ? 0 : item.getDurability());
+ byte data = (byte) (Data.ISFLAT || item.getType().getMaxDurability() > 0 ? 0 : item.getDurability());
+
+ // Check FILLED_MAP enum for more info.
+ //if (!Data.ISFLAT && item.hasItemMeta() && item.getItemMeta() instanceof org.bukkit.inventory.meta.MapMeta) return FILLED_MAP;
return matchDefinedXMaterial(material, data)
- .orElseThrow(() -> new IllegalArgumentException("Unsupported material: " + material + " (" + data + ')'));
+ .orElseThrow(() -> new IllegalArgumentException("Unsupported material from item: " + material + " (" + data + ')'));
}
/**
@@ -1575,7 +1567,8 @@ public enum XMaterial {
* All the values passed to this method will not be null or empty and are formatted correctly.
*
* @param name the formatted name of the material.
- * @param data the data value of the material.
+ * @param data the data value of the material. Is always 0 or {@link #UNKNOWN_DATA_VALUE} when {@link Data#ISFLAT}
+ *
* @return an XMaterial (with the same data value if specified)
* @see #matchXMaterial(Material)
* @see #matchXMaterial(int, byte)
@@ -1583,32 +1576,25 @@ public enum XMaterial {
* @since 3.0.0
*/
@Nonnull
- private static Optional matchDefinedXMaterial(@Nonnull String name, byte data) {
+ protected static Optional matchDefinedXMaterial(@Nonnull String name, byte data) {
// if (!Boolean.valueOf(Boolean.getBoolean(Boolean.TRUE.toString())).equals(Boolean.FALSE.booleanValue())) return null;
Boolean duplicated = null;
+ boolean isAMap = name.equalsIgnoreCase("MAP");
// Do basic number and boolean checks before accessing more complex enum stuff.
- if (data <= 0 && (ISFLAT || !(duplicated = isDuplicated(name)))) {
+ if (Data.ISFLAT || (!isAMap && data <= 0 && !(duplicated = isDuplicated(name)))) {
Optional xMaterial = getIfPresent(name);
if (xMaterial.isPresent()) return xMaterial;
}
+ // Usually flat versions wouldn't pass this point, but some special materials do.
- // XMaterial Paradox (Duplication Check)
- // I've concluded that this is just an infinite loop that keeps
- // going around the Singular Form and the Plural Form materials. A waste of brain cells and a waste of time.
- // This solution works just fine anyway.
XMaterial oldXMaterial = requestOldXMaterial(name, data);
if (oldXMaterial == null) {
// Special case. Refer to FILLED_MAP for more info.
- return data > 0 && name.endsWith("MAP") ? Optional.of(FILLED_MAP) : Optional.empty();
+ return (data >= 0 && isAMap) ? Optional.of(FILLED_MAP) : Optional.empty();
}
- if (!ISFLAT && oldXMaterial.isPlural() && (duplicated == null ? isDuplicated(name) : duplicated)) {
- // A solution for XMaterial Paradox.
- // Manually parses the duplicated materials to find the exact material based on the server version.
- // If ends with "S" -> Plural Form Material
- return getIfPresent(name);
- }
+ if (!Data.ISFLAT && oldXMaterial.isPlural() && (duplicated == null ? isDuplicated(name) : duplicated)) return getIfPresent(name);
return Optional.of(oldXMaterial);
}
@@ -1620,16 +1606,13 @@ public enum XMaterial {
* {@code MELON, CARROT, POTATO, BEETROOT -> true}
*
* @param name the name of the material to check.
+ *
* @return true if there's a duplicated material for this material, otherwise false.
- * @see #isDuplicated()
* @since 2.0.0
*/
private static boolean isDuplicated(@Nonnull String name) {
// Don't use matchXMaterial() since this method is being called from matchXMaterial() itself and will cause a StackOverflowError.
- for (XMaterial duplicated : DUPLICATED.keySet()) {
- if (duplicated.name().equals(name) || duplicated.anyMatchLegacy(name)) return true;
- }
- return false;
+ return DUPLICATED.contains(name);
}
/**
@@ -1638,17 +1621,18 @@ public enum XMaterial {
*
* @param id the ID (Magic value) of the material.
* @param data the data value of the material.
+ *
* @return a parsed XMaterial with the same ID and data value.
* @see #matchXMaterial(ItemStack)
* @since 2.0.0
* @deprecated this method loops through all the available materials and matches their ID using {@link #getId()}
- * which takes a really long time. Plugins should no longer support IDs. If you want, you can make a {@link Map} yourself.
+ * which takes a really long time. Plugins should no longer support IDs. If you want, you can make a {@link Map} cache yourself.
+ * This method obviously doesn't work for 1.13+ and will not be supported. This is only here for debugging purposes.
*/
@Nonnull
@Deprecated
public static Optional matchXMaterial(int id, byte data) {
if (id < 0 || id > MAX_ID || data < 0) return Optional.empty();
-
for (XMaterial materials : VALUES) {
if (materials.data == data && materials.getId() == id) return Optional.of(materials);
}
@@ -1662,6 +1646,7 @@ public enum XMaterial {
* the normal RegEx + String Methods approach for both formatted and unformatted material names.
*
* @param name the material name to modify.
+ *
* @return an enum name.
* @since 2.0.0
*/
@@ -1675,7 +1660,8 @@ public enum XMaterial {
for (int i = 0; i < len; i++) {
char ch = name.charAt(i);
- if (!appendUnderline && count != 0 && (ch == '-' || ch == ' ' || ch == '_') && chs[count] != '_') appendUnderline = true;
+ if (!appendUnderline && count != 0 && (ch == '-' || ch == ' ' || ch == '_') && chs[count] != '_')
+ appendUnderline = true;
else {
boolean number = false;
// Old materials have numbers in them.
@@ -1698,11 +1684,12 @@ public enum XMaterial {
* Checks if the specified version is the same version or higher than the current server version.
*
* @param version the major version to be checked. "1." is ignored. E.g. 1.12 = 12 | 1.9 = 9
+ *
* @return true of the version is equal or higher than the current version.
* @since 2.0.0
*/
public static boolean supports(int version) {
- return VERSION >= version;
+ return Data.VERSION >= version;
}
/**
@@ -1710,6 +1697,7 @@ public enum XMaterial {
* In most cases, you shouldn't be using this method.
*
* @param version Supports {@link Bukkit#getVersion()}, {@link Bukkit#getBukkitVersion()} and normal formats such as "1.14"
+ *
* @return the exact major version.
* @see #supports(int)
* @see #getVersion()
@@ -1737,16 +1725,29 @@ public enum XMaterial {
return version;
}
+ public String[] getLegacy() {
+ return this.legacy;
+ }
+
/**
+ * XMaterial Paradox (Duplication Check)
+ * I've concluded that this is just an infinite loop that keeps
+ * going around the Singular Form and the Plural Form materials. A waste of brain cells and a waste of time.
+ * This solution works just fine anyway.
+ *
* A solution for XMaterial Paradox.
* Manually parses the duplicated materials to find the exact material based on the server version.
* If the name ends with "S" -> Plural Form Material.
+ * Plural methods are only plural if they're also {@link #DUPLICATED}
+ *
+ * The only special exceptions are {@link #BRICKS} and {@link #NETHER_BRICKS}
*
* @return true if this material is a plural form material, otherwise false.
* @since 8.0.0
*/
private boolean isPlural() {
- return this.name().charAt(this.name().length() - 1) == 'S';
+ // this.name().charAt(this.name().length() - 1) == 'S'
+ return this == CARROTS || this == POTATOES;
}
/**
@@ -1783,6 +1784,7 @@ public enum XMaterial {
* Want to learn RegEx? You can mess around in RegExr website.
*
* @param materials the material names to check base material on.
+ *
* @return true if one of the given material names is similar to the base material.
* @since 3.1.1
*/
@@ -1818,6 +1820,7 @@ public enum XMaterial {
* Use {@link #parseItem()} instead when creating new ItemStacks.
*
* @param item the item to change its type.
+ *
* @see #parseItem()
* @since 3.0.0
*/
@@ -1829,7 +1832,7 @@ public enum XMaterial {
Objects.requireNonNull(material, () -> "Unsupported material: " + this.name());
item.setType(material);
- if (!ISFLAT && material.getMaxDurability() <= 0) item.setDurability(this.data);
+ if (!Data.ISFLAT && material.getMaxDurability() <= 0) item.setDurability(this.data);
return item;
}
@@ -1838,13 +1841,13 @@ public enum XMaterial {
* All the values passed to this method will not be null or empty and are formatted correctly.
*
* @param name the material name to check.
+ *
* @return true if it's one of the legacy names, otherwise false.
* @since 2.0.0
*/
private boolean anyMatchLegacy(@Nonnull String name) {
- for (String legacy : this.legacy) {
- if (legacy == null) return false; // Left-side suggestion list
- if (name.equals(legacy)) return true;
+ for (int i = this.legacy.length - 1; i >= 0; i--) {
+ if (name.equals(this.legacy[i])) return true;
}
return false;
}
@@ -1882,21 +1885,10 @@ public enum XMaterial {
if (this.data != 0 || this.version >= 13) return -1;
Material material = this.parseMaterial();
if (material == null) return -1;
- if (ISFLAT && !material.isLegacy()) return -1;
+ if (Data.ISFLAT && !material.isLegacy()) return -1;
return material.getId();
}
- /**
- * Checks if the material has any duplicates.
- *
- * @return true if there is a duplicated name for this material, otherwise false.
- * @see #isDuplicated(String)
- * @since 2.0.0
- */
- private boolean isDuplicated() {
- return DUPLICATED.containsKey(this);
- }
-
/**
* The data value of this material pre-flattening.
*
@@ -1911,117 +1903,38 @@ public enum XMaterial {
return data;
}
- /**
- * Get a list of materials names that was previously used by older versions.
- * Note that this array may contain null, which is an indicator for the suggestion list.
- *
- * @return a list of legacy material names and the first element as the version the material was added in if new.
- * @since 1.0.0
- */
- @Nonnull
- public String[] getLegacy() {
- return legacy;
- }
-
/**
* Parses an item from this XMaterial.
* Uses data values on older versions.
*
* @return an ItemStack with the same material (and data value if in older versions.)
- * @see #parseItem(boolean)
- * @see #setType(ItemStack)
- * @since 1.0.0
- */
- @Nullable
- public ItemStack parseItem() {
- return parseItem(false);
- }
-
- /**
- * Parses an item from this XMaterial.
- * Uses data values on older versions.
- *
- * @param suggest if true {@link #parseMaterial(boolean)} true will be used.
- * @return an ItemStack with the same material (and data value if in older versions.)
* @see #setType(ItemStack)
* @since 2.0.0
*/
@Nullable
@SuppressWarnings("deprecation")
- public ItemStack parseItem(boolean suggest) {
- Material material = this.parseMaterial(suggest);
+ public ItemStack parseItem() {
+ Material material = this.parseMaterial();
if (material == null) return null;
- return ISFLAT ? new ItemStack(material) : new ItemStack(material, 1, this.data);
+ return Data.ISFLAT ? new ItemStack(material) : new ItemStack(material, 1, this.data);
}
/**
* Parses the material of this XMaterial.
*
* @return the material related to this XMaterial based on the server version.
- * @see #parseMaterial(boolean)
* @since 1.0.0
*/
@Nullable
public Material parseMaterial() {
- return parseMaterial(false);
- }
-
- /**
- * Parses the material of this XMaterial and accepts suggestions.
- *
- * @param suggest use a suggested material (from older materials) if the material is added in a later version of Minecraft.
- * @return the material related to this XMaterial based on the server version.
- * @since 2.0.0
- */
- @SuppressWarnings("OptionalAssignedToNull")
- @Nullable
- public Material parseMaterial(boolean suggest) {
- Optional cache = PARSED_CACHE.getIfPresent(this);
- if (cache != null) return cache.orElse(null);
- Material mat;
-
- if (!ISFLAT && this.isDuplicated()) mat = requestOldMaterial(suggest);
- else {
- mat = Material.getMaterial(this.name());
- if (mat == null) mat = requestOldMaterial(suggest);
- }
-
- PARSED_CACHE.put(this, Optional.ofNullable(mat));
- return mat;
- }
-
- /**
- * Parses a material for older versions of Minecraft.
- * Accepts suggestions if specified.
- *
- * @param suggest if true suggested materials will be considered for old versions.
- * @return a parsed material suitable for the current Minecraft version.
- * @see #parseMaterial(boolean)
- * @since 2.0.0
- */
- @Nullable
- private Material requestOldMaterial(boolean suggest) {
- for (int i = this.legacy.length - 1; i >= 0; i--) {
- String legacy = this.legacy[i];
-
- // According to the suggestion list format, all the other names continuing
- // from here are considered as a "suggestion"
- // The null string is an indicator for suggestion list on the left side.
- if (legacy == null) {
- if (suggest) continue;
- break;
- }
-
- Material material = Material.getMaterial(legacy);
- if (material != null) return material;
- }
- return null;
+ return this.material;
}
/**
* Checks if an item has the same material (and data value on older versions).
*
* @param item item to check.
+ *
* @return true if the material is the same as the item's material (and data value if on older versions), otherwise false.
* @since 1.0.0
*/
@@ -2029,26 +1942,7 @@ public enum XMaterial {
public boolean isSimilar(@Nonnull ItemStack item) {
Objects.requireNonNull(item, "Cannot compare with null ItemStack");
if (item.getType() != this.parseMaterial()) return false;
- return ISFLAT || item.getDurability() == this.data || item.getType().getMaxDurability() <= 0;
- }
-
- /**
- * Gets the suggested material names that can be used
- * if the material is not supported in the current version.
- *
- * @return a list of suggested material names.
- * @see #parseMaterial(boolean)
- * @since 2.0.0
- */
- @Nonnull
- public List getSuggestions() {
- if (this.legacy.length == 0 || this.version == 0) return new ArrayList<>();
- List suggestions = new ArrayList<>(this.legacy.length);
- for (String legacy : this.legacy) {
- if (legacy == null) break;
- suggestions.add(legacy);
- }
- return suggestions;
+ return Data.ISFLAT || item.getDurability() == this.data || item.getType().getMaxDurability() <= 0;
}
/**
@@ -2062,8 +1956,7 @@ public enum XMaterial {
* @since 2.0.0
*/
public boolean isSupported() {
- if (this.version != 0) return supports(this.version);
- return Material.getMaterial(this.name()) != null || requestOldMaterial(false) != null;
+ return this.material != null;
}
/**
@@ -2076,4 +1969,65 @@ public enum XMaterial {
public byte getMaterialVersion() {
return version;
}
+
+ /**
+ * This method is needed due to Java enum initialization limitations.
+ * It's really inefficient yes, but it's only used for initialization.
+ *
+ * Yes there are many other ways like comparing the hardcoded ordinal or using a boolean in the enum constructor,
+ * but it's not really a big deal.
+ *
+ * This method should not be called if the version is after the flattening update {@link Data#ISFLAT}
+ * and is only used for parsing materials, not matching, for matching check {@link #DUPLICATED}
+ */
+ private boolean isDuplicated() {
+ switch (this.name()) {
+ case "MELON":
+ case "CARROT":
+ case "POTATO":
+ case "GRASS":
+ case "BRICK":
+ case "NETHER_BRICK":
+
+ // Illegal Elements
+ // Since both 1.12 and 1.13 have _DOOR XMaterial will use it
+ // for 1.12 to parse the material, but it needs _DOOR_ITEM.
+ // We'll trick XMaterial into thinking this needs to be parsed
+ // using the old methods.
+ // Some of these materials have their enum name added to the legacy list as well.
+ case "DARK_OAK_DOOR":
+ case "ACACIA_DOOR":
+ case "BIRCH_DOOR":
+ case "JUNGLE_DOOR":
+ case "SPRUCE_DOOR":
+ case "MAP":
+ case "CAULDRON":
+ case "BREWING_STAND":
+ case "FLOWER_POT":
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Used for datas that need to be accessed during enum initilization.
+ *
+ * @since 9.0.0
+ */
+ private static final class Data {
+ /**
+ * The current version of the server in the a form of a major version.
+ * If the static initialization for this fails, you know something's wrong with the server software.
+ *
+ * @since 1.0.0
+ */
+ private static final int VERSION = Integer.parseInt(getMajorVersion(Bukkit.getVersion()).substring(2));
+ /**
+ * Cached result if the server version is after the v1.13 flattening update.
+ *
+ * @since 3.0.0
+ */
+ private static final boolean ISFLAT = supports(13);
+ }
}
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 539753a..d73ac3e 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,9 +1,8 @@
-name: HeadDB
-description: Database with thousands of heads
+name: ${project.name}
+description: ${project.description}
main: tsp.headdb.HeadDB
-version: 2.1
-api-version: 1.16
+version: ${project.version}
author: Silent
commands: