From f112225d63e28e30348f498b0929fe6391473ee4 Mon Sep 17 00:00:00 2001 From: Crypto Morin Date: Mon, 28 Feb 2022 21:01:21 -0800 Subject: [PATCH] v8.6.2 Titles You can now construct an object with this class that holds all title related information. Added a transformer function parameter to parseTitle for placeholder and other purposes. XMaterial Fixed Terracotta/clay/stained_clay/Hardened_clay related issues. Fixed an issue with pork/cooked XItemStack Added "glow" option which adds a random enchantment to the item for GUI aesthetics. "flag" option now only accepts "ALL" option as a string, not in the list. --- pom.xml | 2 +- .../com/cryptomorin/xseries/XItemStack.java | 19 +++--- .../com/cryptomorin/xseries/XMaterial.java | 10 +-- .../java/com/cryptomorin/xseries/XTag.java | 21 ++++-- .../cryptomorin/xseries/messages/Titles.java | 66 +++++++++++++++++-- .../xseries/particles/ParticleDisplay.java | 12 ++-- 6 files changed, 97 insertions(+), 33 deletions(-) diff --git a/pom.xml b/pom.xml index 2557610f..4628ea32 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.cryptomorin XSeries - 8.6.1 + 8.6.2 XSeries A set of utilities for Minecraft plugins diff --git a/src/main/java/com/cryptomorin/xseries/XItemStack.java b/src/main/java/com/cryptomorin/xseries/XItemStack.java index 80961c39..65590ecd 100644 --- a/src/main/java/com/cryptomorin/xseries/XItemStack.java +++ b/src/main/java/com/cryptomorin/xseries/XItemStack.java @@ -718,6 +718,8 @@ public static ItemStack deserialize(@Nonnull ConfigurationSection config) { Optional enchant = XEnchantment.matchXEnchantment(ench); enchant.ifPresent(xEnchantment -> meta.addEnchant(xEnchantment.getEnchant(), enchants.getInt(ench), true)); } + } else { + if (config.getBoolean("glow")) meta.addEnchant(XEnchantment.DURABILITY.getEnchant(), 1, false); } // Enchanted Books @@ -732,15 +734,16 @@ public static ItemStack deserialize(@Nonnull ConfigurationSection config) { // Flags List flags = config.getStringList("flags"); - for (String flag : flags) { - flag = flag.toUpperCase(Locale.ENGLISH); - if (flag.equals("ALL")) { - meta.addItemFlags(ItemFlag.values()); - break; + if (!flags.isEmpty()) { + for (String flag : flags) { + flag = flag.toUpperCase(Locale.ENGLISH); + ItemFlag itemFlag = Enums.getIfPresent(ItemFlag.class, flag).orNull(); + if (itemFlag != null) meta.addItemFlags(itemFlag); } - - ItemFlag itemFlag = Enums.getIfPresent(ItemFlag.class, flag).orNull(); - if (itemFlag != null) meta.addItemFlags(itemFlag); + } else { + String allFlags = config.getString("flags"); + if (!Strings.isNullOrEmpty(allFlags) && allFlags.equalsIgnoreCase("ALL")) + meta.addItemFlags(ItemFlag.values()); } // Atrributes - https://minecraft.gamepedia.com/Attribute diff --git a/src/main/java/com/cryptomorin/xseries/XMaterial.java b/src/main/java/com/cryptomorin/xseries/XMaterial.java index 99b97838..c064267c 100644 --- a/src/main/java/com/cryptomorin/xseries/XMaterial.java +++ b/src/main/java/com/cryptomorin/xseries/XMaterial.java @@ -281,7 +281,7 @@ public enum XMaterial { CHORUS_FLOWER, CHORUS_FRUIT, CHORUS_PLANT, - CLAY("HARD_CLAY"), + CLAY, CLAY_BALL, CLOCK("WATCH"), COAL, @@ -319,7 +319,7 @@ public enum XMaterial { COOKED_CHICKEN, COOKED_COD("COOKED_FISH"), COOKED_MUTTON, - COOKED_PORKCHOP("PORK", "GRILLED_PORK"), + COOKED_PORKCHOP("GRILLED_PORK"), COOKED_RABBIT, COOKED_SALMON(1, "COOKED_FISH"), COOKIE, @@ -729,7 +729,7 @@ public enum XMaterial { * Renamed to SILVER_GLAZED_TERRACOTTA in 1.12 * Renamed to LIGHT_GRAY_GLAZED_TERRACOTTA in 1.14 */ - LIGHT_GRAY_GLAZED_TERRACOTTA("STAINED_CLAY", "LIGHT_GRAY_TERRACOTTA", "SILVER_GLAZED_TERRACOTTA"), + LIGHT_GRAY_GLAZED_TERRACOTTA(8, "STAINED_CLAY", "SILVER_GLAZED_TERRACOTTA"), LIGHT_GRAY_SHULKER_BOX("SILVER_SHULKER_BOX"), LIGHT_GRAY_STAINED_GLASS(8, "STAINED_GLASS"), LIGHT_GRAY_STAINED_GLASS_PANE(8, "THIN_GLASS", "STAINED_GLASS_PANE"), @@ -1245,7 +1245,7 @@ public enum XMaterial { TALL_GRASS(2, "DOUBLE_PLANT"), TALL_SEAGRASS, TARGET, - TERRACOTTA("STAINED_CLAY"), + TERRACOTTA("HARD_CLAY"), TINTED_GLASS, TIPPED_ARROW, TNT, @@ -1349,7 +1349,7 @@ public enum XMaterial { WHITE_SHULKER_BOX, WHITE_STAINED_GLASS("STAINED_GLASS"), WHITE_STAINED_GLASS_PANE("THIN_GLASS", "STAINED_GLASS_PANE"), - WHITE_TERRACOTTA("STAINED_CLAY", "TERRACOTTA"), + WHITE_TERRACOTTA("STAINED_CLAY"), WHITE_TULIP(6, "RED_ROSE"), WHITE_WALL_BANNER(15, "WALL_BANNER"), WHITE_WOOL("WOOL"), diff --git a/src/main/java/com/cryptomorin/xseries/XTag.java b/src/main/java/com/cryptomorin/xseries/XTag.java index ddb11c36..77094aba 100644 --- a/src/main/java/com/cryptomorin/xseries/XTag.java +++ b/src/main/java/com/cryptomorin/xseries/XTag.java @@ -30,6 +30,10 @@ @SuppressWarnings("NotNullFieldNotInitialized") public final class XTag<@NonNull T extends Enum> { + public static final @NonNull XTag AIR; + + public static final @NonNull XTag INVENTORY_NOT_DISPLAYABLE; + /** * Tag representing all acacia log and bark variants */ @@ -879,7 +883,10 @@ public final class XTag<@NonNull T extends Enum> { } static { + AIR = new XTag<>(XMaterial.AIR, XMaterial.CAVE_AIR, XMaterial.VOID_AIR); PORTALS = new XTag<>(XMaterial.END_GATEWAY, XMaterial.END_PORTAL, XMaterial.NETHER_PORTAL); + INVENTORY_NOT_DISPLAYABLE = new XTag<>(XMaterial.class, AIR, PORTALS); + WALLS = new XTag<>(XMaterial.POLISHED_DEEPSLATE_WALL, XMaterial.NETHER_BRICK_WALL, XMaterial.POLISHED_BLACKSTONE_WALL, @@ -2270,21 +2277,23 @@ public static boolean isInteractable(XMaterial material) { } public boolean isTagged(@Nullable T value) { - // Just encase some plugins pass thru a null value. - if (value == null) { - return false; - } - return this.values.contains(value); + return value != null && this.values.contains(value); } @SafeVarargs - private final void inheritFrom(@NonNull XTag<@NonNull T>... values) { + private final XTag inheritFrom(@NonNull XTag<@NonNull T>... values) { + // Copied because of Collections.unmodifiableSet. + // Better than wrapping it during getValues() every single time. + Set<@NonNull T> newValues; if (this.values.isEmpty()) newValues = EnumSet.copyOf((EnumSet) this.values); else newValues = EnumSet.copyOf(this.values); + for (XTag value : values) { newValues.addAll(value.values); } + this.values = Collections.unmodifiableSet(newValues); + return this; } } diff --git a/src/main/java/com/cryptomorin/xseries/messages/Titles.java b/src/main/java/com/cryptomorin/xseries/messages/Titles.java index 3b07860f..5944029e 100644 --- a/src/main/java/com/cryptomorin/xseries/messages/Titles.java +++ b/src/main/java/com/cryptomorin/xseries/messages/Titles.java @@ -33,6 +33,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Objects; +import java.util.function.Function; /** * A reflection API for titles in Minecraft. @@ -45,7 +46,7 @@ * PacketPlayOutTitle: https://wiki.vg/Protocol#Title * * @author Crypto Morin - * @version 2.1.0 + * @version 3.0.0 * @see ReflectionUtils */ public final class Titles { @@ -61,6 +62,9 @@ public final class Titles { */ private static final MethodHandle CHAT_COMPONENT_TEXT; + private String title, subtitle; + private final int fadeIn, stay, fadeOut; + static { MethodHandle packetCtor = null; MethodHandle chatComp = null; @@ -112,7 +116,17 @@ public final class Titles { CHAT_COMPONENT_TEXT = chatComp; } - private Titles() {} + public Titles(String title, String subtitle, int fadeIn, int stay, int fadeOut) { + this.title = title; + this.subtitle = subtitle; + this.fadeIn = fadeIn; + this.stay = stay; + this.fadeOut = fadeOut; + } + + public void send(Player player) { + sendTitle(player, fadeIn, stay, fadeOut, title, subtitle); + } /** * Sends a title message with title and subtitle to a player. @@ -169,8 +183,12 @@ public static void sendTitle(@Nonnull Player player, @Nonnull String title, @Non sendTitle(player, 10, 20, 10, title, subtitle); } + public static Titles parseTitle(@Nonnull ConfigurationSection config) { + return parseTitle(config, null); + } + /** - * Parses and sends a title from the config. + * Parses a title from config. * The configuration section must at least * contain {@code title} or {@code subtitle} * @@ -181,15 +199,19 @@ public static void sendTitle(@Nonnull Player player, @Nonnull String title, @Non * Titles.sendTitle(player, titleSection); * * - * @param player the player to send the title to. * @param config the configuration section to parse the title properties from. * - * @since 1.0.0 + * @since 3.0.0 */ - public static void sendTitle(@Nonnull Player player, @Nonnull ConfigurationSection config) { + public static Titles parseTitle(@Nonnull ConfigurationSection config, @Nullable Function transformers) { String title = config.getString("title"); String subtitle = config.getString("subtitle"); + if (transformers != null) { + title = transformers.apply(title); + subtitle = transformers.apply(subtitle); + } + int fadeIn = config.getInt("fade-in"); int stay = config.getInt("stay"); int fadeOut = config.getInt("fade-out"); @@ -198,7 +220,37 @@ public static void sendTitle(@Nonnull Player player, @Nonnull ConfigurationSecti if (stay < 1) stay = 20; if (fadeOut < 1) fadeOut = 10; - sendTitle(player, fadeIn, stay, fadeOut, title, subtitle); + return new Titles(title, subtitle, fadeIn, stay, fadeOut); + } + + public String getTitle() { + return title; + } + + public String getSubtitle() { + return subtitle; + } + + public void setTitle(String title) { + this.title = title; + } + + public void setSubtitle(String subtitle) { + this.subtitle = subtitle; + } + + /** + * Parses and sends a title from the config. + * + * @param player the player to send the title to. + * @param config the configuration section to parse the title properties from. + * + * @since 1.0.0 + */ + public static Titles sendTitle(@Nonnull Player player, @Nonnull ConfigurationSection config) { + Titles titles = parseTitle(config, null); + titles.send(player); + return titles; } /** diff --git a/src/main/java/com/cryptomorin/xseries/particles/ParticleDisplay.java b/src/main/java/com/cryptomorin/xseries/particles/ParticleDisplay.java index 35672028..31a64424 100644 --- a/src/main/java/com/cryptomorin/xseries/particles/ParticleDisplay.java +++ b/src/main/java/com/cryptomorin/xseries/particles/ParticleDisplay.java @@ -78,7 +78,7 @@ public class ParticleDisplay implements Cloneable { * * @since 8.6.0.0.1 */ - private static final boolean ISFLAT2 = XParticle.getParticle("DUST_COLOR_TRANSITION") != null; + private static final boolean SUPPORTS_DUST_TRANSITION = XParticle.getParticle("DUST_COLOR_TRANSITION") != null; private static final Axis[] DEFAULT_ROTATION_ORDER = {Axis.X, Axis.Y, Axis.Z}; private static final Particle DEFAULT_PARTICLE = Particle.CLOUD; @@ -573,7 +573,7 @@ public ParticleDisplay withColor(@Nonnull Color color, float size) { * to get custom colors. * * @param color1 the RGB color of the particle on spawn. - * @param size the size of the particle. + * @param size the size of the particle. * @param color2 the RGB color of the particle at the end. * * @return the same particle display, but modified. @@ -1010,15 +1010,15 @@ public Location spawn(Location loc, @Nullable Player... players) { .fromRGB((int) datas[0], (int) datas[1], (int) datas[2]), datas[3]); if (players == null) world.spawnParticle(particle, loc, count, offsetx, offsety, offsetz, extra, dust, force); else for (Player player : players) player.spawnParticle(particle, loc, count, offsetx, offsety, offsetz, extra, dust); - - } else if (ISFLAT2 && particle.getDataType() == Particle.DustTransition.class) { - Particle.DustOptions dust = new Particle.DustTransition( + } else if (SUPPORTS_DUST_TRANSITION && particle.getDataType() == Particle.DustTransition.class) { + // Having the variable type as Particle.DustOptions causes NoClassDefFoundError for DustOptions + // because of some weird upcasting stuff. + Particle.DustTransition dust = new Particle.DustTransition( org.bukkit.Color.fromRGB((int) datas[0], (int) datas[1], (int) datas[2]), org.bukkit.Color.fromRGB((int) datas[4], (int) datas[5], (int) datas[6]), datas[3]); if (players == null) world.spawnParticle(particle, loc, count, offsetx, offsety, offsetz, extra, dust, force); else for (Player player : players) player.spawnParticle(particle, loc, count, offsetx, offsety, offsetz, extra, dust); - } else if (isDirectional()) { // With count=0, color on offset e.g. for MOB_SPELL or 1.12 REDSTONE float[] rgb = {datas[0] / 255f, datas[1] / 255f, datas[2] / 255f};