v1.6.4: Added support for 1.20.5, 1.20.6 and 1.21 #30

Merged
stijnb1234 merged 9 commits from development into master 2024-06-30 22:46:01 +02:00
8 changed files with 104 additions and 146 deletions
Showing only changes of commit 445dc1d2e9 - Show all commits

3
.idea/misc.xml generated
View file

@ -29,9 +29,8 @@
<option value="$PROJECT_DIR$/NMS-v1_19_R1/pom.xml" />
</set>
</option>
<option name="workspaceImportForciblyTurnedOn" value="true" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="temurin-11" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="temurin-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

2
.idea/vcs.xml generated
View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="" vcs="Git" />
</component>
</project>

27
pom.xml
View file

@ -24,7 +24,7 @@
<groupId>tech.sbdevelopment</groupId>
<artifactId>MapReflectionAPI</artifactId>
<version>1.6.3</version>
<version>1.6.4</version>
<packaging>jar</packaging>
<name>MapReflectionAPI</name>
@ -48,14 +48,14 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<version>3.13.0</version>
<configuration>
<release>11</release>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<version>1.18.34</version>
</path>
</annotationProcessorPaths>
</configuration>
@ -63,7 +63,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<version>3.6.0</version>
<executions>
<execution>
<phase>package</phase>
@ -103,12 +103,19 @@
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.4.0</version>
<version>3.7.0</version>
<configuration>
<release>11</release>
<sourcepath>${maven.lombok.delombok-target}</sourcepath>
@ -161,13 +168,13 @@
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.20.4-R0.1-SNAPSHOT</version>
<version>1.21-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<version>1.18.34</version>
<scope>provided</scope>
</dependency>
@ -178,17 +185,17 @@
<scope>compile</scope>
</dependency>
<!-- Libraries below are provided by Spigot -->
<!-- Libraries below are provided by CraftBukkit -->
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations-java5</artifactId>
<version>23.0.0</version>
<version>24.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport</artifactId>
<version>4.1.77.Final</version>
<version>4.1.97.Final</version>
<scope>provided</scope>
</dependency>
</dependencies>

View file

@ -86,6 +86,7 @@ public class MapSender {
private static final Class<?> packetPlayOutMapClass = getNMSClass("network.protocol.game", "PacketPlayOutMap");
private static final Class<?> worldMapData = supports(17) ? getNMSClass("world.level.saveddata.maps", "WorldMap$b") : null;
private static final Class<?> mapId = supports(21) ? getNMSClass("world.level.saveddata.maps", "MapId") : null;
/**
* Send a map to a player
@ -110,7 +111,6 @@ public class MapSender {
return;
}
final int id = -id0;
Object packet;
if (supports(17)) { //1.17+
Object updateData = ReflectionUtil.callConstructor(worldMapData,
@ -121,16 +121,26 @@ public class MapSender {
content.array //Data
);
if (supports(21)) { //1.21+
packet = ReflectionUtil.callConstructor(packetPlayOutMapClass,
id, //ID
ReflectionUtil.callConstructor(mapId, -id0), //ID
(byte) 0, //Scale, 0 = 1 block per pixel
false, //Show icons
new ReflectionUtil.CollectionParam<>(), //Icons
updateData
);
} else {
packet = ReflectionUtil.callConstructor(packetPlayOutMapClass,
-id0, //ID
(byte) 0, //Scale, 0 = 1 block per pixel
false, //Show icons
new ReflectionUtil.CollectionParam<>(), //Icons
updateData
);
}
} else if (supports(14)) { //1.16-1.14
packet = ReflectionUtil.callConstructor(packetPlayOutMapClass,
id, //ID
-id0, //ID
(byte) 0, //Scale, 0 = 1 block per pixel
false, //Tracking position
false, //Locked
@ -143,7 +153,7 @@ public class MapSender {
);
} else { //1.13-
packet = ReflectionUtil.callConstructor(packetPlayOutMapClass,
id, //ID
-id0, //ID
(byte) 0, //Scale, 0 = 1 block per pixel
false, //???
new ReflectionUtil.CollectionParam<>(), //Icons

View file

@ -67,6 +67,8 @@ public class MapWrapper extends AbstractMapWrapper {
private static final Class<?> entityMetadataPacketClass = getNMSClass("network.protocol.game", "PacketPlayOutEntityMetadata");
private static final Class<?> entityItemFrameClass = getNMSClass("world.entity.decoration", "EntityItemFrame");
private static final Class<?> dataWatcherItemClass = getNMSClass("network.syncher", "DataWatcher$Item");
private static final Class<?> minecraftKeyClass = getNMSClass("resources", "MinecraftKey");
private static final Class<?> builtInRegistriesClass = getNMSClass("core.registries", "BuiltInRegistries");
protected MapController controller = new MapController() {
private final Map<UUID, Integer> viewers = new HashMap<>();
@ -164,7 +166,10 @@ public class MapWrapper extends AbstractMapWrapper {
}
String inventoryMenuName;
if (supports(20)) {
if (supports(21)) {
//1.21 = cc
inventoryMenuName = "cc";
} else if (supports(20)) {
//>= 1.20.2 = bR, 1.20(.1) = bQ
inventoryMenuName = supports(20, 2) ? "bR" : "bQ";
} else if (supports(19)) {
@ -286,7 +291,14 @@ public class MapWrapper extends AbstractMapWrapper {
Object nmsStack = ReflectionUtil.callMethod(craftStackClass, "asNMSCopy", stack);
if (supports(13)) {
if (supports(21)) { //1.21 method
Object minecraftKey = ReflectionUtil.callDeclaredMethod(minecraftKeyClass, "a", "minecraft:map_id");
Object dataComponentTypeRegistery = ReflectionUtil.getDeclaredField(builtInRegistriesClass, "aq");
Object dataComponentType = ReflectionUtil.callMethod(dataComponentTypeRegistery, "a", minecraftKey);
Object dataComponentMap = ReflectionUtil.callMethod(nmsStack, "a");
ReflectionUtil.callMethod(dataComponentMap, "a", dataComponentType, mapId);
} else if (supports(13)) { //1.13 - 1.20 method
String nbtObjectName;
if (supports(20)) { //1.20
nbtObjectName = "w";
@ -307,7 +319,9 @@ public class MapWrapper extends AbstractMapWrapper {
Object nmsStack = createCraftItemStack(stack, mapId);
String dataWatcherObjectName;
if (supports(19, 3)) { //1.19.3 and 1.20(.1)
if (supports(21)) { //1.21
dataWatcherObjectName = "f";
} else if (supports(19, 3)) { //1.19.3 and 1.20(.1)
dataWatcherObjectName = "g";
} else if (supports(19)) { //1.19-1.19.2
dataWatcherObjectName = "ao";
@ -328,7 +342,7 @@ public class MapWrapper extends AbstractMapWrapper {
Object packet;
if (supports(19, 3)) { //1.19.3
Class<?> dataWatcherRecordClass = getNMSClass("network.syncher", "DataWatcher$b");
Class<?> dataWatcherRecordClass = getNMSClass("network.syncher", "DataWatcher$" + (supports(21) ? "c" : "b"));
// Sadly not possible to use ReflectionUtil (in its current state), because of the Object parameter
Object dataWatcherItem;
try {

View file

@ -140,8 +140,8 @@ public class PacketListener implements Listener {
} else if (packet.getClass().isAssignableFrom(packetPlayInSetCreativeSlotClass)) {
Object packetPlayInSetCreativeSlot = packetPlayInSetCreativeSlotClass.cast(packet);
int slot = (int) ReflectionUtil.callDeclaredMethod(packetPlayInSetCreativeSlot, supports(19, 4) ? "a" : supports(13) ? "b" : "a"); //1.19.4 = a, 1.19.3 - 1.13 = b, 1.12 = a
Object nmsStack = ReflectionUtil.callDeclaredMethod(packetPlayInSetCreativeSlot, supports(20, 2) ? "d" : supports(18) ? "c" : "getItemStack"); //1.20.2 = d, >= 1.18 = c, 1.17 = getItemStack
int slot = (int) ReflectionUtil.callDeclaredMethod(packetPlayInSetCreativeSlot, supports(21) ? "b" : supports(19, 4) ? "a" : supports(13) ? "b" : "a"); //1.21 = b, 1.19.4 = a, 1.19.3 - 1.13 = b, 1.12 = a
Object nmsStack = ReflectionUtil.callDeclaredMethod(packetPlayInSetCreativeSlot, supports(21) ? "e" : supports(20, 2) ? "d" : supports(18) ? "c" : "getItemStack"); //1.21 = e, 1.20.2 = d, >= 1.18 = c, 1.17 = getItemStack
ItemStack craftStack = (ItemStack) ReflectionUtil.callMethod(craftStackClass, "asBukkitCopy", nmsStack);
boolean async = !MapReflectionAPI.getInstance().getServer().isPrimaryThread();

View file

@ -18,6 +18,9 @@
package tech.sbdevelopment.mapreflectionapi.utils;
import java.util.Map;
import java.util.function.Supplier;
public class MainUtil {
private MainUtil() {
}

View file

@ -2,7 +2,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2018 Hex_27
* Copyright (c) 2023 Crypto Morin
* Copyright (c) 2024 Crypto Morin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -30,7 +30,7 @@ import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SpawnEggMeta;
import org.bukkit.potion.Potion;
import org.jetbrains.annotations.ApiStatus;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -38,7 +38,6 @@ import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.stream.Collectors;
/**
@ -61,11 +60,11 @@ import java.util.stream.Collectors;
* <b>/give @p minecraft:dirt 1 10</b> where 1 is the item amount, and 10 is the data value. The material {@link #DIRT} with a data value of {@code 10} doesn't exist.
*
* @author Crypto Morin
* @version 11.5.0
* @version 12.0.0
* @see Material
* @see ItemStack
*/
public enum XMaterial {
public enum XMaterial /* implements com.cryptomorin.xseries.abstractions.Material*/ {
ACACIA_BOAT("BOAT_ACACIA"),
ACACIA_BUTTON("WOOD_BUTTON"),
ACACIA_CHEST_BOAT,
@ -108,6 +107,8 @@ public enum XMaterial {
ANVIL,
APPLE,
ARCHER_POTTERY_SHERD,
ARMADILLO_SCUTE,
ARMADILLO_SPAWN_EGG,
ARMOR_STAND,
ARMS_UP_POTTERY_SHERD,
ARROW,
@ -223,6 +224,8 @@ public enum XMaterial {
BLUE_TERRACOTTA(11, "STAINED_CLAY"),
BLUE_WALL_BANNER(4, "WALL_BANNER"),
BLUE_WOOL(11, "WOOL"),
BOGGED_SPAWN_EGG,
BOLT_ARMOR_TRIM_SMITHING_TEMPLATE,
BONE,
BONE_BLOCK,
BONE_MEAL(15, "INK_SACK"),
@ -235,6 +238,7 @@ public enum XMaterial {
BRAIN_CORAL_FAN,
BRAIN_CORAL_WALL_FAN,
BREAD,
BREEZE_ROD,
BREEZE_SPAWN_EGG,
BREWER_POTTERY_SHERD,
BREWING_STAND("BREWING_STAND", "BREWING_STAND_ITEM"),
@ -591,7 +595,7 @@ public enum XMaterial {
FERMENTED_SPIDER_EYE,
FERN(2, "LONG_GRASS"),
/**
* For some reasons filled map items are really special.
* For some reason, filled map items are really special.
* Their data value starts from 0 and every time a player
* creates a new map that maps data value increases.
* <a href="https://github.com/CryptoMorin/XSeries/issues/91">GitHub Issue</a>
@ -613,6 +617,9 @@ public enum XMaterial {
FLOWERING_AZALEA_LEAVES,
FLOWER_BANNER_PATTERN,
FLOWER_POT("FLOWER_POT", "FLOWER_POT_ITEM"),
FLOW_ARMOR_TRIM_SMITHING_TEMPLATE,
FLOW_BANNER_PATTERN,
FLOW_POTTERY_SHERD,
FOX_SPAWN_EGG,
FRIEND_POTTERY_SHERD,
FROGSPAWN,
@ -699,11 +706,14 @@ public enum XMaterial {
GRINDSTONE,
GUARDIAN_SPAWN_EGG(68, "MONSTER_EGG"),
GUNPOWDER("SULPHUR"),
GUSTER_BANNER_PATTERN,
GUSTER_POTTERY_SHERD,
HANGING_ROOTS,
HAY_BLOCK,
HEARTBREAK_POTTERY_SHERD,
HEART_OF_THE_SEA,
HEART_POTTERY_SHERD,
HEAVY_CORE,
HEAVY_WEIGHTED_PRESSURE_PLATE("IRON_PLATE"),
HOGLIN_SPAWN_EGG("MONSTER_EGG"),
HONEYCOMB,
@ -856,6 +866,7 @@ public enum XMaterial {
LLAMA_SPAWN_EGG(103, "MONSTER_EGG"),
LODESTONE,
LOOM,
MACE,
MAGENTA_BANNER(13, "STANDING_BANNER", "BANNER"),
MAGENTA_BED(supports(12) ? 2 : 0, "BED_BLOCK", "BED"),
MAGENTA_CANDLE,
@ -939,11 +950,14 @@ public enum XMaterial {
MUSIC_DISC_BLOCKS("RECORD_3"),
MUSIC_DISC_CAT("GREEN_RECORD"),
MUSIC_DISC_CHIRP("RECORD_4"),
MUSIC_DISC_CREATOR,
MUSIC_DISC_CREATOR_MUSIC_BOX,
MUSIC_DISC_FAR("RECORD_5"),
MUSIC_DISC_MALL("RECORD_6"),
MUSIC_DISC_MELLOHI("RECORD_7"),
MUSIC_DISC_OTHERSIDE,
MUSIC_DISC_PIGSTEP,
MUSIC_DISC_PRECIPICE,
MUSIC_DISC_RELIC,
MUSIC_DISC_STAL("RECORD_8"),
MUSIC_DISC_STRAD("RECORD_9"),
@ -1009,6 +1023,8 @@ public enum XMaterial {
OBSIDIAN,
OCELOT_SPAWN_EGG(98, "MONSTER_EGG"),
OCHRE_FROGLIGHT,
OMINOUS_BOTTLE,
OMINOUS_TRIAL_KEY,
ORANGE_BANNER(14, "STANDING_BANNER", "BANNER"),
ORANGE_BED(supports(12) ? 1 : 0, "BED_BLOCK", "BED"),
ORANGE_CANDLE,
@ -1285,6 +1301,7 @@ public enum XMaterial {
SANDSTONE_STAIRS,
SANDSTONE_WALL,
SCAFFOLDING,
SCRAPE_POTTERY_SHERD,
SCULK,
SCULK_CATALYST,
SCULK_SENSOR,
@ -1479,9 +1496,11 @@ public enum XMaterial {
TUFF_WALL,
TURTLE_EGG,
TURTLE_HELMET,
TURTLE_SCUTE,
TURTLE_SPAWN_EGG,
TWISTING_VINES,
TWISTING_VINES_PLANT,
VAULT,
VERDANT_FROGLIGHT,
VEX_ARMOR_TRIM_SMITHING_TEMPLATE,
VEX_SPAWN_EGG(35, "MONSTER_EGG"),
@ -1598,12 +1617,14 @@ public enum XMaterial {
WHITE_WALL_BANNER(15, "WALL_BANNER"),
WHITE_WOOL("WOOL"),
WILD_ARMOR_TRIM_SMITHING_TEMPLATE,
WIND_CHARGE,
WITCH_SPAWN_EGG(66, "MONSTER_EGG"),
WITHER_ROSE,
WITHER_SKELETON_SKULL(1, "SKULL", "SKULL_ITEM"),
WITHER_SKELETON_SPAWN_EGG(5, "MONSTER_EGG"),
WITHER_SKELETON_WALL_SKULL(1, "SKULL", "SKULL_ITEM"),
WITHER_SPAWN_EGG,
WOLF_ARMOR,
WOLF_SPAWN_EGG(95, "MONSTER_EGG"),
WOODEN_AXE("WOOD_AXE"),
WOODEN_HOE("WOOD_HOE"),
@ -1664,14 +1685,6 @@ public enum XMaterial {
private static final Cache<String, XMaterial> NAME_CACHE = CacheBuilder.newBuilder()
.expireAfterAccess(1, TimeUnit.HOURS)
.build();
/**
* This is used for {@link #isOneOf(Collection)}
*
* @since 3.4.0
*/
private static final Cache<String, Pattern> CACHED_REGEX = CacheBuilder.newBuilder()
.expireAfterAccess(3, TimeUnit.HOURS)
.build();
/**
* The maximum data value in the pre-flattening update which belongs to {@link #VILLAGER_SPAWN_EGG}<br>
* <a href="https://minecraftitemids.com/types/spawn-egg">Spawn Eggs</a>
@ -1910,9 +1923,10 @@ public enum XMaterial {
// Potions used the items data value to store
// information about the type of potion in 1.8
if (!supports(9) && material.endsWith("ION")) {
// There's also 16000+ data value technique, but this is more reliable.
return Potion.fromItemStack(item).isSplash() ? SPLASH_POTION : POTION;
if (!supports(9) && material.equals("POTION")) {
// Source: v1.8.8 org.bukkit.potion.Potion.fromDamage(int damage)
int damage = item.getDurability();
return ((damage & 16384) > 0) ? SPLASH_POTION : POTION;
}
// Refer to the enum for info.
@ -1921,9 +1935,14 @@ public enum XMaterial {
// If this happens to more materials in the future, I might have to change the system.
if (supports(13) && !supports(14)) {
// https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/diff/src/main/java/org/bukkit/Material.java?until=67d908a9830c71267ee740f5bddd728ce9c64cc7
if (material.equals("CACTUS_GREEN")) return GREEN_DYE;
if (material.equals("ROSE_RED")) return RED_DYE;
if (material.equals("DANDELION_YELLOW")) return YELLOW_DYE;
switch (material) {
case "CACTUS_GREEN":
return GREEN_DYE;
case "ROSE_RED":
return RED_DYE;
case "DANDELION_YELLOW":
return YELLOW_DYE;
}
}
// Check FILLED_MAP enum for more info.
@ -1935,29 +1954,6 @@ public enum XMaterial {
throw new IllegalArgumentException("Unsupported material from item: " + material + " (" + data + ')');
}
/**
* Gets the XMaterial based on the material's ID (Magic Value) and data value.<br>
* You should avoid using this for performance issues.
*
* @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} 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<XMaterial> 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);
}
return Optional.empty();
}
/**
* The main method that parses the given material name and data value as an XMaterial.
* All the values passed to this method will not be null or empty and are formatted correctly.
@ -1966,7 +1962,6 @@ public enum XMaterial {
* @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)
* @see #matchXMaterial(ItemStack)
* @since 3.0.0
*/
@ -2053,12 +2048,14 @@ public enum XMaterial {
}
/**
* This is an internal API. Use {@link com.cryptomorin.xseries.reflection.XReflection#supports(int)} instead.
* 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
*/
@ApiStatus.Internal
public static boolean supports(int version) {
return Data.VERSION >= version;
}
@ -2067,78 +2064,6 @@ public enum XMaterial {
return this.legacy;
}
/**
* Checks if the list of given material names matches the given base material.
* Mostly used for configs.
* <p>
* Supports {@link String#contains} {@code CONTAINS:NAME} and Regular Expression {@code REGEX:PATTERN} formats.
* <p>
* <b>Example:</b>
* <blockquote><pre>
* XMaterial material = {@link #matchXMaterial(ItemStack)};
* if (material.isOneOf(plugin.getConfig().getStringList("disabled-items")) return;
* </pre></blockquote>
* <br>
* <b>{@code CONTAINS} Examples:</b>
* <pre>
* {@code "CONTAINS:CHEST" -> CHEST, ENDERCHEST, TRAPPED_CHEST -> true}
* {@code "cOnTaINS:dYe" -> GREEN_DYE, YELLOW_DYE, BLUE_DYE, INK_SACK -> true}
* </pre>
* <p>
* <b>{@code REGEX} Examples</b>
* <pre>
* {@code "REGEX:^.+_.+_.+$" -> Every Material with 3 underlines or more: SHULKER_SPAWN_EGG, SILVERFISH_SPAWN_EGG, SKELETON_HORSE_SPAWN_EGG}
* {@code "REGEX:^.{1,3}$" -> Material names that have 3 letters only: BED, MAP, AIR}
* </pre>
* <p>
* The reason that there are tags for {@code CONTAINS} and {@code REGEX} is for the performance.
* Although RegEx patterns are cached in this method,
* please avoid using the {@code REGEX} tag if you can use the {@code CONTAINS} tag instead.
* It'll have a huge impact on performance.
* Please avoid using {@code (capturing groups)} there's no use for them in this case.
* If you want to use groups, use {@code (?: non-capturing groups)}. It's faster.
* <p>
* Want to learn RegEx? You can mess around in <a href="https://regexr.com/">RegExr</a> 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
* @deprecated Use XTag.stringMatcher() instead.
*/
@Deprecated
public boolean isOneOf(@Nullable Collection<String> materials) {
if (materials == null || materials.isEmpty()) return false;
String name = this.name();
for (String comp : materials) {
String checker = comp.toUpperCase(Locale.ENGLISH);
if (checker.startsWith("CONTAINS:")) {
comp = format(checker.substring(9));
if (name.contains(comp)) return true;
continue;
}
if (checker.startsWith("REGEX:")) {
comp = comp.substring(6);
Pattern pattern = CACHED_REGEX.getIfPresent(comp);
if (pattern == null) {
try {
pattern = Pattern.compile(comp);
CACHED_REGEX.put(comp, pattern);
} catch (PatternSyntaxException ex) {
ex.printStackTrace();
}
}
if (pattern != null && pattern.matcher(name).matches()) return true;
continue;
}
// Direct Object Equals
Optional<XMaterial> xMat = matchXMaterial(comp);
if (xMat.isPresent() && xMat.get() == this) return true;
}
return false;
}
/**
* Sets the {@link Material} (and data value on older versions) of an item.
* Damageable materials will not have their durability changed.
@ -2209,7 +2134,6 @@ public enum XMaterial {
* Spigot added material ID support back in 1.16+
*
* @return the ID of the material or <b>-1</b> if it's not a legacy material or the server doesn't support the material.
* @see #matchXMaterial(int, byte)
* @since 2.2.0
*/
@SuppressWarnings("deprecation")
@ -2379,6 +2303,7 @@ public enum XMaterial {
*
* @since 9.0.0
*/
@ApiStatus.Internal
private static final class Data {
/**
* The current version of the server in the form of a major version.