diff --git a/eco-api/src/main/java/com/willfp/eco/core/items/Items.java b/eco-api/src/main/java/com/willfp/eco/core/items/Items.java index b5806aec..8c287380 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/items/Items.java +++ b/eco-api/src/main/java/com/willfp/eco/core/items/Items.java @@ -1,28 +1,27 @@ package com.willfp.eco.core.items; +import com.willfp.eco.core.items.args.LookupArgParser; import com.willfp.eco.core.recipe.parts.EmptyTestableItem; import com.willfp.eco.core.recipe.parts.MaterialTestableItem; import com.willfp.eco.core.recipe.parts.ModifiedTestableItem; import com.willfp.eco.core.recipe.parts.TestableStack; import com.willfp.eco.util.NamespacedKeyUtils; -import com.willfp.eco.util.SkullUtils; import lombok.experimental.UtilityClass; import org.bukkit.Material; import org.bukkit.NamespacedKey; -import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.EnchantmentStorageMeta; import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.SkullMeta; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Predicate; /** * Class to manage all custom and vanilla items. @@ -35,16 +34,30 @@ public final class Items { private static final Map REGISTRY = new ConcurrentHashMap<>(); /** - * Register a new recipe part. + * All recipe parts. + */ + private static final List ARG_PARSERS = new ArrayList<>(); + + /** + * Register a new custom item. * - * @param key The key of the recipe part. - * @param part The recipe part. + * @param key The key of the item. + * @param part The item. */ public void registerCustomItem(@NotNull final NamespacedKey key, @NotNull final CustomItem part) { REGISTRY.put(key, part); } + /** + * Register a new arg parser. + * + * @param parser The parser. + */ + public void registerArgParser(@NotNull final LookupArgParser parser) { + ARG_PARSERS.add(parser); + } + /** * Remove an item. * @@ -161,95 +174,19 @@ public final class Items { String[] modifierArgs = Arrays.copyOfRange(args, usingNewStackFormat ? 2 : 1, args.length); - boolean hasModifiers = false; - Map requiredEnchantments = new HashMap<>(); - String skullTexture = null; + List> predicates = new ArrayList<>(); - // Handle skull texture - for (String arg : modifierArgs) { - String[] argSplit = arg.split(":"); - if (!argSplit[0].equalsIgnoreCase("texture")) { - continue; - } - - if (argSplit.length < 2) { - continue; - } - - skullTexture = argSplit[1]; - hasModifiers = true; + for (LookupArgParser argParser : ARG_PARSERS) { + predicates.add(argParser.parseArguments(modifierArgs, meta)); } - if (meta instanceof SkullMeta skullMeta && skullTexture != null) { - SkullUtils.setSkullTexture(skullMeta, skullTexture); - } - - // Handle enchantment modifiers - for (String enchantArg : modifierArgs) { - String[] enchantArgSplit = enchantArg.split(":"); - - Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(enchantArgSplit[0].toLowerCase())); - if (enchantment == null) { - continue; - } - - if (enchantArgSplit.length < 2) { - continue; - } - - int level = Integer.parseInt(enchantArgSplit[1]); - - requiredEnchantments.put(enchantment, level); - hasModifiers = true; - } - - if (meta instanceof EnchantmentStorageMeta storageMeta) { - requiredEnchantments.forEach((enchantment, integer) -> storageMeta.addStoredEnchant(enchantment, integer, true)); - } else { - requiredEnchantments.forEach((enchantment, integer) -> meta.addEnchant(enchantment, integer, true)); - } - - /* - The modifiers are then applied. - */ - example.setItemMeta(meta); - - String finalSkullTexture = skullTexture; // I hate this, java. - if (hasModifiers) { + if (!predicates.isEmpty()) { item = new ModifiedTestableItem( item, test -> { - if (!test.hasItemMeta()) { - return false; - } - - ItemMeta testMeta = test.getItemMeta(); - - assert testMeta != null; - - if (testMeta instanceof EnchantmentStorageMeta storageMeta) { - for (Map.Entry entry : requiredEnchantments.entrySet()) { - if (!storageMeta.hasStoredEnchant(entry.getKey())) { - return false; - } - if (storageMeta.getStoredEnchantLevel(entry.getKey()) < entry.getValue()) { - return false; - } - } - } else { - for (Map.Entry entry : requiredEnchantments.entrySet()) { - if (!testMeta.hasEnchant(entry.getKey())) { - return false; - } - if (testMeta.getEnchantLevel(entry.getKey()) < entry.getValue()) { - return false; - } - } - } - - if (testMeta instanceof SkullMeta skullMeta && finalSkullTexture != null) { - if (!finalSkullTexture.equalsIgnoreCase(SkullUtils.getSkullTexture(skullMeta))) { + for (Predicate predicate : predicates) { + if (!predicate.test(test)) { return false; } } diff --git a/eco-api/src/main/java/com/willfp/eco/core/items/args/EnchantmentArgParser.java b/eco-api/src/main/java/com/willfp/eco/core/items/args/EnchantmentArgParser.java new file mode 100644 index 00000000..542f482f --- /dev/null +++ b/eco-api/src/main/java/com/willfp/eco/core/items/args/EnchantmentArgParser.java @@ -0,0 +1,75 @@ +package com.willfp.eco.core.items.args; + +import org.bukkit.NamespacedKey; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Predicate; + +public class EnchantmentArgParser implements LookupArgParser { + @Override + public Predicate parseArguments(@NotNull final String[] args, + @NotNull final ItemMeta meta) { + Map requiredEnchantments = new HashMap<>(); + + for (String enchantArg : args) { + String[] enchantArgSplit = enchantArg.split(":"); + + Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(enchantArgSplit[0].toLowerCase())); + if (enchantment == null) { + continue; + } + + if (enchantArgSplit.length < 2) { + continue; + } + + int level = Integer.parseInt(enchantArgSplit[1]); + + requiredEnchantments.put(enchantment, level); + } + + if (meta instanceof EnchantmentStorageMeta storageMeta) { + requiredEnchantments.forEach((enchantment, integer) -> storageMeta.addStoredEnchant(enchantment, integer, true)); + } else { + requiredEnchantments.forEach((enchantment, integer) -> meta.addEnchant(enchantment, integer, true)); + } + + return test -> { + if (!test.hasItemMeta()) { + return false; + } + + ItemMeta testMeta = test.getItemMeta(); + + assert testMeta != null; + + if (testMeta instanceof EnchantmentStorageMeta storageMeta) { + for (Map.Entry entry : requiredEnchantments.entrySet()) { + if (!storageMeta.hasStoredEnchant(entry.getKey())) { + return false; + } + if (storageMeta.getStoredEnchantLevel(entry.getKey()) < entry.getValue()) { + return false; + } + } + } else { + for (Map.Entry entry : requiredEnchantments.entrySet()) { + if (!testMeta.hasEnchant(entry.getKey())) { + return false; + } + if (testMeta.getEnchantLevel(entry.getKey()) < entry.getValue()) { + return false; + } + } + } + + return true; + }; + } +} diff --git a/eco-api/src/main/java/com/willfp/eco/core/items/args/LookupArgParser.java b/eco-api/src/main/java/com/willfp/eco/core/items/args/LookupArgParser.java new file mode 100644 index 00000000..d4ca9b73 --- /dev/null +++ b/eco-api/src/main/java/com/willfp/eco/core/items/args/LookupArgParser.java @@ -0,0 +1,19 @@ +package com.willfp.eco.core.items.args; + +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Predicate; + +public interface LookupArgParser { + /** + * Parse the arguments. + * + * @param args The arguments. + * @param meta The ItemMeta to modify. + * @return The predicate test to apply to the modified item. + */ + Predicate parseArguments(@NotNull String[] args, + @NotNull ItemMeta meta); +} diff --git a/eco-api/src/main/java/com/willfp/eco/core/items/args/TextureArgParser.java b/eco-api/src/main/java/com/willfp/eco/core/items/args/TextureArgParser.java new file mode 100644 index 00000000..9a5ffbd9 --- /dev/null +++ b/eco-api/src/main/java/com/willfp/eco/core/items/args/TextureArgParser.java @@ -0,0 +1,51 @@ +package com.willfp.eco.core.items.args; + +import com.willfp.eco.util.SkullUtils; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Predicate; + +public class TextureArgParser implements LookupArgParser { + @Override + public Predicate parseArguments(@NotNull final String[] args, + @NotNull final ItemMeta meta) { + String skullTexture = null; + + for (String arg : args) { + String[] argSplit = arg.split(":"); + if (!argSplit[0].equalsIgnoreCase("texture")) { + continue; + } + + if (argSplit.length < 2) { + continue; + } + + skullTexture = argSplit[1]; + } + + if (meta instanceof SkullMeta skullMeta && skullTexture != null) { + SkullUtils.setSkullTexture(skullMeta, skullTexture); + } + + String finalSkullTexture = skullTexture; + return test -> { + if (!test.hasItemMeta()) { + return false; + } + + ItemMeta testMeta = test.getItemMeta(); + + assert testMeta != null; + + if (testMeta instanceof SkullMeta skullMeta && finalSkullTexture != null) { + return finalSkullTexture.equalsIgnoreCase(SkullUtils.getSkullTexture(skullMeta)); + } + + return true; + }; + } +} diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/spigot/EcoSpigotPlugin.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/spigot/EcoSpigotPlugin.kt index 552c88e0..b12b3339 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/spigot/EcoSpigotPlugin.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/spigot/EcoSpigotPlugin.kt @@ -9,6 +9,9 @@ import com.willfp.eco.core.integrations.antigrief.AntigriefManager import com.willfp.eco.core.integrations.customitems.CustomItemsManager import com.willfp.eco.core.integrations.mcmmo.McmmoManager import com.willfp.eco.core.integrations.shop.ShopManager +import com.willfp.eco.core.items.Items +import com.willfp.eco.core.items.args.EnchantmentArgParser +import com.willfp.eco.core.items.args.TextureArgParser import com.willfp.eco.internal.drops.DropManager import com.willfp.eco.proxy.BlockBreakProxy import com.willfp.eco.proxy.FastItemStackFactoryProxy @@ -45,6 +48,9 @@ abstract class EcoSpigotPlugin : EcoPlugin( init { Display.setFinalizeKey(namespacedKeyFactory.create("finalized")) + Items.registerArgParser(EnchantmentArgParser()) + Items.registerArgParser(TextureArgParser()) + val skullProxy = getProxy(SkullProxy::class.java) SkullUtils.initialize( { meta: SkullMeta, base64: String -> skullProxy.setSkullTexture(meta, base64) }, diff --git a/eco-core/core-plugin/src/main/resources/plugin.yml b/eco-core/core-plugin/src/main/resources/plugin.yml index 6823faa6..16db5d9c 100644 --- a/eco-core/core-plugin/src/main/resources/plugin.yml +++ b/eco-core/core-plugin/src/main/resources/plugin.yml @@ -4,6 +4,7 @@ main: com.willfp.eco.spigot.EcoHandler api-version: 1.16 authors: [Auxilor] website: willfp.com +load: STARTUP depend: - ProtocolLib softdepend: