diff --git a/build.gradle.kts b/build.gradle.kts index b923a5d..78844a1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,11 +12,11 @@ plugins { signing id("cn.lalaki.central").version("1.2.5") // Paper - id("io.papermc.paperweight.userdev") version "1.7.3" apply false + id("io.papermc.paperweight.userdev") version "2.0.0-beta.8" apply false } group = "xyz.alexcrea" -version = "1.6.13" +version = "1.7.0" repositories { // EcoEnchants @@ -39,15 +39,19 @@ dependencies { // EcoEnchants compileOnly("com.willfp:EcoEnchants:12.5.1") compileOnly("com.willfp:eco:6.70.1") + compileOnly(project(":impl:LegacyEcoEnchant")) // ExcellentEnchants compileOnly(files("libs/nightcore-2.6.4.jar")) compileOnly(files("libs/ExcellentEnchants-4.2.2.jar")) - compileOnly(files("libs/ExcellentEnchants 4.1.0-striped.jar")) + compileOnly(files("libs/ExcellentEnchants 4.1.0-striped.jar")) // For legacy excellent enchants // Disenchantment compileOnly("cz.kominekjan:Disenchantment:v5.4.0") + // HavenBags + compileOnly(files("libs/HavenBags-1.30.1.1729.jar")) + // Include nms implementation(project(":nms:nms-common")) implementation(project(":nms:v1_17R1", configuration = "reobf")) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 19cfad9..d6e308a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/impl/LegacyEcoEnchant/build.gradle.kts b/impl/LegacyEcoEnchant/build.gradle.kts new file mode 100644 index 0000000..ec24ae1 --- /dev/null +++ b/impl/LegacyEcoEnchant/build.gradle.kts @@ -0,0 +1,15 @@ +group = rootProject.group +version = rootProject.version + +plugins { + kotlin("jvm") version "2.0.21" +} + +// Imitate needed class and method to support legacy version of EcoEnchant +dependencies { + // Spigot api + compileOnly("org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT") + + + +} \ No newline at end of file diff --git a/impl/LegacyEcoEnchant/src/main/java/com/willfp/ecoenchants/enchantments/EcoEnchant.java b/impl/LegacyEcoEnchant/src/main/java/com/willfp/ecoenchants/enchantments/EcoEnchant.java new file mode 100644 index 0000000..edfe1e9 --- /dev/null +++ b/impl/LegacyEcoEnchant/src/main/java/com/willfp/ecoenchants/enchantments/EcoEnchant.java @@ -0,0 +1,26 @@ +package com.willfp.ecoenchants.enchantments; + +import com.willfp.ecoenchants.enchantments.meta.EnchantmentTarget; +import com.willfp.ecoenchants.enchantments.meta.EnchantmentType; +import org.bukkit.enchantments.Enchantment; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +/** + * Mock class for legacy package of eco enchants + */ +public class EcoEnchant { + + public boolean conflictsWith(@NotNull Enchantment enchant) { + return false; + } + + public Set getTargets() { + return null; + } + + public EnchantmentType getType() { + return null; + } +} diff --git a/impl/LegacyEcoEnchant/src/main/java/com/willfp/ecoenchants/enchantments/EcoEnchants.java b/impl/LegacyEcoEnchant/src/main/java/com/willfp/ecoenchants/enchantments/EcoEnchants.java new file mode 100644 index 0000000..39f8064 --- /dev/null +++ b/impl/LegacyEcoEnchant/src/main/java/com/willfp/ecoenchants/enchantments/EcoEnchants.java @@ -0,0 +1,14 @@ +package com.willfp.ecoenchants.enchantments; + +import java.util.List; + +/** + * Mock class for legacy package of eco enchants + */ +public class EcoEnchants { + + public static List values(){ + return null; // We don't care here. + } + +} diff --git a/impl/LegacyEcoEnchant/src/main/java/com/willfp/ecoenchants/enchantments/meta/EnchantmentTarget.java b/impl/LegacyEcoEnchant/src/main/java/com/willfp/ecoenchants/enchantments/meta/EnchantmentTarget.java new file mode 100644 index 0000000..19a667b --- /dev/null +++ b/impl/LegacyEcoEnchant/src/main/java/com/willfp/ecoenchants/enchantments/meta/EnchantmentTarget.java @@ -0,0 +1,16 @@ +package com.willfp.ecoenchants.enchantments.meta; + +import org.bukkit.Material; + +import java.util.Set; + +/** + * Mock class for legacy package of eco enchants + */ +public class EnchantmentTarget { + + public Set getMaterials() { + return null; + } + +} diff --git a/impl/LegacyEcoEnchant/src/main/java/com/willfp/ecoenchants/enchantments/meta/EnchantmentType.java b/impl/LegacyEcoEnchant/src/main/java/com/willfp/ecoenchants/enchantments/meta/EnchantmentType.java new file mode 100644 index 0000000..183ec74 --- /dev/null +++ b/impl/LegacyEcoEnchant/src/main/java/com/willfp/ecoenchants/enchantments/meta/EnchantmentType.java @@ -0,0 +1,9 @@ +package com.willfp.ecoenchants.enchantments.meta; + +public class EnchantmentType { + + public boolean isSingular() { + return false; + } + +} diff --git a/libs/HavenBags-1.30.1.1729.jar b/libs/HavenBags-1.30.1.1729.jar new file mode 100644 index 0000000..e5d58e5 Binary files /dev/null and b/libs/HavenBags-1.30.1.1729.jar differ diff --git a/nms/v1_17R1/build.gradle.kts b/nms/v1_17R1/build.gradle.kts index 12e9c90..0480a4b 100644 --- a/nms/v1_17R1/build.gradle.kts +++ b/nms/v1_17R1/build.gradle.kts @@ -24,7 +24,7 @@ repositories { // Configure used version of kotlin and java java { disableAutoTargetJvm() - toolchain.languageVersion.set(JavaLanguageVersion.of(16)) + toolchain.languageVersion.set(JavaLanguageVersion.of(17)) } // Set target version diff --git a/settings.gradle.kts b/settings.gradle.kts index 9e75656..576d36d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -38,3 +38,5 @@ include("nms:v1_21R2") findProject(":nms:v1_21R2")?.name = "v1_21R2" include("nms:v1_21R3") findProject(":nms:v1_21R3")?.name = "v1_21R3" +include(":impl:LegacyEcoEnchant") +findProject(":impl:LegacyEcoEnchant")?.name = "LegacyEcoEnchant" diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java index 1225209..5e2b1c1 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java @@ -5,6 +5,7 @@ import org.bukkit.NamespacedKey; import org.bukkit.enchantments.Enchantment; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.enchant.bulk.BukkitEnchantBulkOperation; import xyz.alexcrea.cuanvil.enchant.bulk.BulkCleanEnchantOperation; import xyz.alexcrea.cuanvil.enchant.bulk.BulkGetEnchantOperation; @@ -16,6 +17,7 @@ import java.util.logging.Level; public class CAEnchantmentRegistry { private static final CAEnchantmentRegistry instance = new CAEnchantmentRegistry(); + public static CAEnchantmentRegistry getInstance() { return instance; } @@ -49,7 +51,7 @@ public class CAEnchantmentRegistry { * This should only be called on main of custom anvil. * If called more than one time, chance of thing being broken will be high. */ - public void registerBukkit(){ + public void registerBukkit() { // Register enchantment for (Enchantment enchantment : Enchantment.values()) { register(new CABukkitEnchantment(enchantment)); @@ -59,7 +61,6 @@ public class CAEnchantmentRegistry { BukkitEnchantBulkOperation bukkitOperation = new BukkitEnchantBulkOperation(); optimisedGetOperators.add(bukkitOperation); optimisedCleanOperators.add(bukkitOperation); - } private static boolean hasWarnedRegistering = false; @@ -69,20 +70,30 @@ public class CAEnchantmentRegistry { *

* No guarantee that the enchantment will be present on the config gui if registered late. * (By late I mean after custom anvil startup.) + * * @param enchantment The enchantment to be registered. * @return If the operation was successful. */ - public boolean register(@NotNull CAEnchantment enchantment){ - if(byKeyMap.containsKey(enchantment.getKey())){ + public boolean register(@NotNull CAEnchantment enchantment) { + if (byKeyMap.containsKey(enchantment.getKey())) { + if (!enchantment.equals(byKeyMap.get(enchantment.getKey()))) { + // We are trying to register the exact same enchantment. so we just skip it. + return false; + } + + if(ConfigHolder.DEFAULT_CONFIG.getConfig().getBoolean("caution_secret_do_not_log_duplicated_registered_key", false)){ + return false; + } + CustomAnvil.instance.getLogger().log(Level.WARNING, - "Duplicate registered enchantment. This should NOT happen any time.\n" + - "If you are a custom anvil developer. You maybe custom anvil detected your enchantment as a bukkit enchantment. " + - "maybe remove enchantment with the same key before registering yours", - new IllegalStateException(enchantment.getKey()+" enchantment was already registered")); + "Duplicate distinct registered enchantment. This should NOT happen any time.\n" + + "If you are a custom anvil developer: Maybe custom anvil detected your enchantment as a bukkit enchantment. " + + "you should maybe remove enchantment with the same key before registering yours", + new IllegalStateException("enchantment " + enchantment.getKey() + " was already registered")); return false; } - if((!hasWarnedRegistering) && byNameMap.containsKey(enchantment.getName())){ + if ((!hasWarnedRegistering) && byNameMap.containsKey(enchantment.getName())) { hasWarnedRegistering = true; CustomAnvil.instance.getLogger().log(Level.WARNING, @@ -96,10 +107,10 @@ public class CAEnchantmentRegistry { nameSortedEnchantments.add(enchantment); - if(!enchantment.isGetOptimised()){ + if (!enchantment.isGetOptimised()) { unoptimisedGetValues.add(enchantment); } - if(!enchantment.isCleanOptimised()){ + if (!enchantment.isCleanOptimised()) { unoptimisedCleanValues.add(enchantment); } @@ -113,12 +124,13 @@ public class CAEnchantmentRegistry { *

* No guarantee that the enchantment will absent if the config guis if unregistered late. * (By late I mean after custom anvil startup.) + * * @param enchantment The enchantment to be unregistered. * @return If the operation was successful. */ - public boolean unregister(@Nullable CAEnchantment enchantment){ - if(enchantment == null) return false; + public boolean unregister(@Nullable CAEnchantment enchantment) { + if (enchantment == null) return false; byKeyMap.remove(enchantment.getKey()); byNameMap.get(enchantment.getName()).remove(enchantment); @@ -131,42 +143,45 @@ public class CAEnchantmentRegistry { /** * Gets the enchantment by the provided key. + * * @param key Key to fetch. * @return Registered enchantment. null if absent. */ @Nullable - public CAEnchantment getByKey(@NotNull NamespacedKey key){ + public CAEnchantment getByKey(@NotNull NamespacedKey key) { return byKeyMap.get(key); } /** * Gets the enchantment by the provided name. + * * @param name Name to fetch. * @return Registered enchantment. null if absent. - * * @deprecated use {@link #getListByName(String)} */ @Deprecated(since = "1.6.3") @Nullable - public CAEnchantment getByName(@NotNull String name){ + public CAEnchantment getByName(@NotNull String name) { List enchantments = getListByName(name); - if(enchantments.isEmpty()) return null; + if (enchantments.isEmpty()) return null; return enchantments.get(0); } /** * Gets list of enchantment using the provided name. + * * @param name Name to fetch. * @return List of registered enchantment. */ @NotNull - public List getListByName(@NotNull String name){ + public List getListByName(@NotNull String name) { return byNameMap.getOrDefault(name, Collections.emptyList()); } /** * Gets an array of all the registered enchantments. + * * @return Array of enchantments. */ @NotNull @@ -176,6 +191,7 @@ public class CAEnchantmentRegistry { /** * Gets a map of all the registered enchantments. + * * @return Immutable map of enchantments. */ public Map registeredEnchantments() { @@ -184,6 +200,7 @@ public class CAEnchantmentRegistry { /** * Gets a list of all the unoptimised get operation enchantments. + * * @return List of unoptimised enchantments. */ @NotNull @@ -193,6 +210,7 @@ public class CAEnchantmentRegistry { /** * Gets a list of all the unoptimised clean operation enchantments. + * * @return List of unoptimised enchantments. */ @NotNull @@ -202,6 +220,7 @@ public class CAEnchantmentRegistry { /** * Get "clean optimised operation" for get enchantments. + * * @return Mutable "clean enchantments optimised operation" list. */ public List getOptimisedCleanOperators() { @@ -210,6 +229,7 @@ public class CAEnchantmentRegistry { /** * Get "get optimised operation" for get enchantments. + * * @return Mutable "get enchantments optimised operation" list. */ public List getOptimisedGetOperators() { @@ -218,6 +238,7 @@ public class CAEnchantmentRegistry { /** * Get custom anvil enchantment sorted by name. + * * @return An immutable sorted set of every registered enchantment sorted by name. */ public SortedSet getNameSortedEnchantments() { diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BukkitEnchantBulkOperation.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BukkitEnchantBulkOperation.java index cb56436..c5bd07d 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BukkitEnchantBulkOperation.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BukkitEnchantBulkOperation.java @@ -1,7 +1,9 @@ package xyz.alexcrea.cuanvil.enchant.bulk; +import io.delilaheve.CustomAnvil; import io.delilaheve.util.ItemUtil; import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.EnchantmentStorageMeta; import org.bukkit.inventory.meta.ItemMeta; @@ -14,18 +16,29 @@ import java.util.Map; public class BukkitEnchantBulkOperation implements BulkGetEnchantOperation, BulkCleanEnchantOperation { @Override - public void bulkGet(@NotNull Map enchantmentList, @NotNull ItemStack item, @NotNull ItemMeta meta) { + public void bulkGet(@NotNull Map enchantmentMap, @NotNull ItemStack item, @NotNull ItemMeta meta) { if (ItemUtil.INSTANCE.isEnchantedBook(item)) { - ((EnchantmentStorageMeta)meta).getStoredEnchants().forEach((enchantment, level) -> - enchantmentList.put(EnchantmentApi.getByKey(enchantment.getKey()), level) + ((EnchantmentStorageMeta) meta).getStoredEnchants().forEach((enchantment, level) -> + addEnchantment(enchantmentMap, enchantment, level) ); } else { item.getEnchantments().forEach((enchantment, level) -> - enchantmentList.put(EnchantmentApi.getByKey(enchantment.getKey()), level) + addEnchantment(enchantmentMap, enchantment, level) ); } } + public void addEnchantment(@NotNull Map enchantmentMap, @NotNull Enchantment enchantment, int level) { + CAEnchantment enchant = EnchantmentApi.getByKey(enchantment.getKey()); + if (enchant == null) { + CustomAnvil.instance.getLogger().warning("Enchantment of key " + enchantment.getKey() + + " somehow not found in CustomAnvil ?"); + return; + } + + enchantmentMap.put(enchant, level); + } + @Override public void bulkClear(@NotNull ItemStack item) { if (item.getType() != Material.ENCHANTED_BOOK) { diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BulkGetEnchantOperation.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BulkGetEnchantOperation.java index a985edd..7c66e8a 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BulkGetEnchantOperation.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/BulkGetEnchantOperation.java @@ -14,10 +14,10 @@ public interface BulkGetEnchantOperation { /** * Bulk get part of the stored enchantment of this item. - * @param enchantmentList Mutable map of collected enchantment. should b + * @param enchantmentMap Mutable map of collected enchantment. should b * @param item The item to get enchantment from. Should not get edited. * @param meta The item meta to get enchantment from. Should not get edited. */ - void bulkGet(@NotNull Map enchantmentList, @NotNull ItemStack item, @NotNull ItemMeta meta); + void bulkGet(@NotNull Map enchantmentMap, @NotNull ItemStack item, @NotNull ItemMeta meta); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/EnchantSquaredBulkOperation.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/EnchantSquaredBulkOperation.java index 59bd6ec..ed4d010 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/EnchantSquaredBulkOperation.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/EnchantSquaredBulkOperation.java @@ -14,10 +14,10 @@ import java.util.Map; public class EnchantSquaredBulkOperation implements BulkGetEnchantOperation, BulkCleanEnchantOperation { @Override - public void bulkGet(@NotNull Map enchantmentList, @NotNull ItemStack item, @NotNull ItemMeta meta) { + public void bulkGet(@NotNull Map enchantmentMap, @NotNull ItemStack item, @NotNull ItemMeta meta) { EnchantmentSquaredDependency enchantmentSquared = DependencyManager.INSTANCE.getEnchantmentSquaredCompatibility(); if(enchantmentSquared != null){ - enchantmentSquared.getEnchantmentsSquared(item, enchantmentList); + enchantmentSquared.getEnchantmentsSquared(item, enchantmentMap); } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CABukkitEnchantment.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CABukkitEnchantment.java index 6b062aa..585c276 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CABukkitEnchantment.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CABukkitEnchantment.java @@ -157,4 +157,13 @@ public class CABukkitEnchantment extends CAEnchantmentBase { } + @Override + public boolean equals(Object obj) { + if(!(obj instanceof CABukkitEnchantment other)){ + return false; + } + + return this.enchantment.equals(other.getEnchant()); + } + } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEcoEnchant.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEcoEnchant.java index 0d85ffd..6e74b73 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEcoEnchant.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEcoEnchant.java @@ -2,6 +2,7 @@ package xyz.alexcrea.cuanvil.enchant.wrapped; import com.willfp.ecoenchants.enchant.EcoEnchant; import com.willfp.ecoenchants.target.EnchantmentTarget; +import com.willfp.ecoenchants.type.EnchantmentType; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; @@ -9,6 +10,7 @@ import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment; import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity; +import java.util.HashMap; import java.util.Map; public class CAEcoEnchant extends CABukkitEnchantment implements AdditionalTestEnchantment { @@ -22,19 +24,34 @@ public class CAEcoEnchant extends CABukkitEnchantment implements AdditionalTestE @Override public boolean isEnchantConflict(@NotNull Map enchantments, @NotNull Material itemMat) { - if(!enchantments.isEmpty()) { - if (this.ecoEnchant.getConflictsWithEverything()) { + if (enchantments.isEmpty()) return false; + + if (this.ecoEnchant.getConflictsWithEverything()) { + return true; + } + + HashMap typeAmountMap = new HashMap<>(); + + for (CAEnchantment other : enchantments.keySet()) { + if (other instanceof CABukkitEnchantment otherVanilla + && this.ecoEnchant.conflictsWith(otherVanilla.getEnchant())) { return true; } - for (CAEnchantment other : enchantments.keySet()) { - if(other instanceof CABukkitEnchantment otherVanilla - && this.ecoEnchant.conflictsWith(otherVanilla.getEnchant())){ + if (other instanceof CAEcoEnchant ecoOther) { + EnchantmentType type = ecoOther.ecoEnchant.getType(); + typeAmountMap.putIfAbsent(type, 0); + + int amount = typeAmountMap.get(type) + 1; + if (amount > type.getLimit()) { return true; } + + typeAmountMap.put(type, amount); } } + return false; } @@ -42,12 +59,12 @@ public class CAEcoEnchant extends CABukkitEnchantment implements AdditionalTestE public boolean isItemConflict(@NotNull Map enchantments, @NotNull Material itemMat, @NotNull ItemStack item) { - if(Material.ENCHANTED_BOOK.equals(itemMat)){ + if (Material.ENCHANTED_BOOK.equals(itemMat)) { return false; } for (EnchantmentTarget target : this.ecoEnchant.getTargets()) { - if(target.matches(item)){ + if (target.matches(item)) { return false; } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEnchantSquaredEnchantment.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEnchantSquaredEnchantment.java index ee5b9c0..8f1058e 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEnchantSquaredEnchantment.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CAEnchantSquaredEnchantment.java @@ -16,15 +16,20 @@ import java.util.Objects; public class CAEnchantSquaredEnchantment extends CAEnchantmentBase { public final @NotNull CustomEnchant enchant; + public CAEnchantSquaredEnchantment(@NotNull CustomEnchant enchant) { super(Objects.requireNonNull( - Objects.requireNonNull(DependencyManager.INSTANCE.getEnchantmentSquaredCompatibility()).getKeyFromEnchant(enchant)), + Objects.requireNonNull(DependencyManager.INSTANCE.getEnchantmentSquaredCompatibility()).getKeyFromEnchant(enchant)), EnchantmentRarity.COMMON, enchant.getMaxLevel()); this.enchant = enchant; } + public @NotNull CustomEnchant getEnchant() { + return enchant; + } + @Override public boolean isGetOptimised() { return true; @@ -61,4 +66,14 @@ public class CAEnchantSquaredEnchantment extends CAEnchantmentBase { CustomEnchantManager.getInstance().removeEnchant(item, this.enchant.getType()); } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof CAEnchantSquaredEnchantment other)) { + return false; + } + + return this.enchant.equals(other.getEnchant()); + } + } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CALegacyEcoEnchant.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CALegacyEcoEnchant.java new file mode 100644 index 0000000..3b4242d --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CALegacyEcoEnchant.java @@ -0,0 +1,65 @@ +package xyz.alexcrea.cuanvil.enchant.wrapped; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.meta.EnchantmentTarget; +import com.willfp.ecoenchants.enchantments.meta.EnchantmentType; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment; +import xyz.alexcrea.cuanvil.enchant.CAEnchantment; +import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity; + +import java.util.Map; + +public class CALegacyEcoEnchant extends CABukkitEnchantment implements AdditionalTestEnchantment { + + private final @NotNull EcoEnchant ecoEnchant; + + public CALegacyEcoEnchant(@NotNull EcoEnchant ecoEnchant, @NotNull Enchantment enchantment) { + super(enchantment, EnchantmentRarity.COMMON); + this.ecoEnchant = ecoEnchant; + } + + @Override + public boolean isEnchantConflict(@NotNull Map enchantments, @NotNull Material itemMat) { + if (enchantments.isEmpty()) return false; + + EnchantmentType type = this.ecoEnchant.getType(); + boolean isSingular = type.isSingular(); + + for (CAEnchantment other : enchantments.keySet()) { + if (other instanceof CABukkitEnchantment otherVanilla + && this.ecoEnchant.conflictsWith(otherVanilla.getEnchant())) { + return true; + } + + if (isSingular && + other != this && + (other instanceof CALegacyEcoEnchant otherEco) && + type.equals(otherEco.ecoEnchant.getType())) { + return true; + } + } + + return false; + } + + @Override + public boolean isItemConflict(@NotNull Map enchantments, + @NotNull Material itemMat, + @NotNull ItemStack item) { + if (Material.ENCHANTED_BOOK.equals(itemMat)) { + return false; + } + + for (EnchantmentTarget target : this.ecoEnchant.getTargets()) { + if (target.getMaterials().contains(itemMat)) { + return false; + } + } + + return true; + } +} diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt index 9082b95..e97744e 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt @@ -28,13 +28,14 @@ object DependencyManager { var excellentEnchantsCompatibility: ExcellentEnchantsDependency? = null var disenchantmentCompatibility: DisenchantmentDependency? = null + var havenBagsCompatibility: HavenBagsDependency? = null - fun loadDependency(){ + fun loadDependency() { val pluginManager = Bukkit.getPluginManager() // Bukkit or Paper scheduler ? isFolia = testIsFolia() - scheduler = if(isFolia) { + scheduler = if (isFolia) { CustomAnvil.instance.logger.info("Folia detected... Custom Anvil Folia support is experimental. issues are more likely to happens.") FoliaScheduler() @@ -46,29 +47,35 @@ object DependencyManager { externGuiTester = GuiTesterSelector.selectGuiTester // Enchantment Squared dependency - if(pluginManager.isPluginEnabled("EnchantsSquared")){ + if (pluginManager.isPluginEnabled("EnchantsSquared")) { enchantmentSquaredCompatibility = EnchantmentSquaredDependency(pluginManager.getPlugin("EnchantsSquared")!!) enchantmentSquaredCompatibility!!.disableAnvilListener() } // EcoEnchants dependency - if(pluginManager.isPluginEnabled("EcoEnchants")){ + if (pluginManager.isPluginEnabled("EcoEnchants")) { ecoEnchantCompatibility = EcoEnchantDependency(pluginManager.getPlugin("EcoEnchants")!!) ecoEnchantCompatibility!!.disableAnvilListener() } // Excellent Enchants dependency - if(pluginManager.isPluginEnabled("ExcellentEnchants")){ + if (pluginManager.isPluginEnabled("ExcellentEnchants")) { excellentEnchantsCompatibility = ExcellentEnchantsDependency() excellentEnchantsCompatibility!!.redirectListeners() } // Disenchantment dependency - if(pluginManager.isPluginEnabled("Disenchantment")){ + if (pluginManager.isPluginEnabled("Disenchantment")) { disenchantmentCompatibility = DisenchantmentDependency() disenchantmentCompatibility!!.redirectListeners() } + // HavenBags dependency + if (pluginManager.isPluginEnabled("HavenBags")) { + havenBagsCompatibility = HavenBagsDependency() + havenBagsCompatibility!!.redirectListeners() + } + } fun handleCompatibilityConfig() { @@ -83,7 +90,7 @@ object DependencyManager { } - fun handleConfigReload(){ + fun handleConfigReload() { // Register enchantment of compatible plugin and load configuration change. handleCompatibilityConfig() @@ -95,14 +102,18 @@ object DependencyManager { fun tryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean { var bypass = false - // Test if disenchantment used special prepare anvil - if(disenchantmentCompatibility?.testPrepareAnvil(event, player) == true) bypass = true + // Test if disenchantment used prepare anvil + if (disenchantmentCompatibility?.testPrepareAnvil(event, player) == true) bypass = true - // Test excellent enchantments used special prepare anvil - if(!bypass && (excellentEnchantsCompatibility?.testPrepareAnvil(event) == true)) bypass = true + // Test heaven bags used prepare anvil + if (!bypass && (havenBagsCompatibility?.testPrepareAnvil(event, player) == true)) bypass = true + + // Test excellent enchantments used prepare anvil + if (!bypass && (excellentEnchantsCompatibility?.testPrepareAnvil(event) == true)) bypass = true // Test if the inventory is a gui(version specific) - if(!bypass && (externGuiTester?.testIfGui(event.view) == true)) bypass = true + if (!bypass && (externGuiTester?.testIfGui(event.view) == true)) bypass = true + return bypass } @@ -114,14 +125,17 @@ object DependencyManager { fun tryClickAnvilResultBypass(event: InventoryClickEvent, inventory: AnvilInventory): Boolean { var bypass = false - // Test if disenchantment used special event click - if(disenchantmentCompatibility?.testAnvilResult(event, inventory) == true) bypass = true + // Test if disenchantment used event click + if (disenchantmentCompatibility?.testAnvilResult(event, inventory) == true) bypass = true - // Test if disenchantment used special event click - if(!bypass && (excellentEnchantsCompatibility?.testAnvilResult(event) == true)) bypass = true + // Test if haven bag used event click + if (!bypass && (havenBagsCompatibility?.testAnvilResult(event, inventory) == true)) bypass = true + + // Test if disenchantment used event click + if (!bypass && (excellentEnchantsCompatibility?.testAnvilResult(event) == true)) bypass = true // Test if the inventory is a gui(version specific) - if(!bypass && (externGuiTester?.testIfGui(event.view) == true)) bypass = true + if (!bypass && (externGuiTester?.testIfGui(event.view) == true)) bypass = true return bypass } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EcoEnchantDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EcoEnchantDependency.kt index e7bad3e..ba52e23 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EcoEnchantDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EcoEnchantDependency.kt @@ -10,11 +10,29 @@ import xyz.alexcrea.cuanvil.enchant.wrapped.CAEcoEnchant class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) { + private val isLegacy: Boolean + private val legacyDependency: LegacyEcoEnchantDependency? + init { CustomAnvil.instance.logger.info("Eco Enchant Detected !") + + var isLegacy = true + try { + Class.forName("com.willfp.ecoenchants.enchant.EcoEnchants") + isLegacy = false + } catch (_: ClassNotFoundException) { + } + + this.isLegacy = isLegacy; + if (isLegacy) { + this.legacyDependency = LegacyEcoEnchantDependency() + } else { + this.legacyDependency = null + } + } - fun disableAnvilListener(){ + fun disableAnvilListener() { PrepareAnvilEvent.getHandlerList().unregister(this.ecoEnchantPlugin) } @@ -22,6 +40,11 @@ class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) { fun registerEnchantments() { CustomAnvil.instance.logger.info("Preparing Eco Enchant compatibility...") + if (isLegacy) { + legacyDependency!!.registerEnchantments(); + return + } + val enchantments = EcoEnchants.values() for (ecoEnchant in enchantments) { EnchantmentApi.unregisterEnchantment(ecoEnchant.enchantment) // As eco enchants is loaded before custom anvil and register enchantment to registry, we need to unregister old "vanilla" enchant. @@ -34,14 +57,19 @@ class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) { } fun handleConfigReload() { + if (isLegacy) { + legacyDependency!!.handleConfigReload() + return + } + // Should not happen in known case. - if(this.ecoEnchantOldEnchantments == null) return + if (this.ecoEnchantOldEnchantments == null) return val newEnchantments = EcoEnchants.values() // Add new enchantments for (ecoEnchant in newEnchantments) - if(!this.ecoEnchantOldEnchantments!!.contains(ecoEnchant)) + if (!this.ecoEnchantOldEnchantments!!.contains(ecoEnchant)) EnchantmentApi.registerEnchantment(CAEcoEnchant(ecoEnchant)) // Remove old enchantments that not now currently used diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/HavenBagsDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/HavenBagsDependency.kt new file mode 100644 index 0000000..661107e --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/HavenBagsDependency.kt @@ -0,0 +1,92 @@ +package xyz.alexcrea.cuanvil.dependency + +import io.delilaheve.CustomAnvil +import org.bukkit.entity.HumanEntity +import org.bukkit.event.inventory.InventoryClickEvent +import org.bukkit.event.inventory.PrepareAnvilEvent +import org.bukkit.inventory.AnvilInventory +import org.bukkit.inventory.ItemStack +import org.bukkit.plugin.RegisteredListener +import valorless.havenbags.BagSkin +import valorless.havenbags.BagUpgrade +import valorless.havenbags.HavenBags +import valorless.havenbags.prevention.EquipPrevention +import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener +import xyz.alexcrea.cuanvil.util.AnvilXpUtil + +class HavenBagsDependency { + + init { + CustomAnvil.instance.logger.info("Heaven Bags Detected !") + } + + private lateinit var bagUpgrade: BagUpgrade + private lateinit var bagSkin: BagSkin + + fun redirectListeners() { + val toUnregister = ArrayList() + // get required PrepareAnvilEvent listener + for (registeredListener in PrepareAnvilEvent.getHandlerList().registeredListeners) { + val listener = registeredListener.listener + + if (listener is BagUpgrade) { + bagUpgrade = listener + toUnregister.add(registeredListener) + } + + if (listener is BagSkin) { + bagSkin = listener + toUnregister.add(registeredListener) + } + } + + for (listener in toUnregister) { + PrepareAnvilEvent.getHandlerList().unregister(listener) + InventoryClickEvent.getHandlerList().unregister(listener) + } + + } + + fun testPrepareAnvil(event: PrepareAnvilEvent, player: HumanEntity): Boolean { + val previousResult = event.result + event.result = null + + // Test if event change the result + bagSkin.onPrepareAnvil(event) + if (event.result != null) { + CustomAnvil.log("Detected pre anvil heaven bag anvil skin.") + AnvilXpUtil.setAnvilInvXp(event.inventory, event.view, player, event.inventory.repairCost) + return true + } + + bagUpgrade.onPrepareAnvil(event) + if (event.result != null) { + CustomAnvil.log("Detected pre anvil heaven bag anvil upgrade.") + AnvilXpUtil.setAnvilInvXp(event.inventory, event.view, player, event.inventory.repairCost) + return true + } + + event.result = previousResult + return false + } + + fun testAnvilResult(event: InventoryClickEvent, inventory: AnvilInventory): Boolean { + val result = inventory.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)?.clone() + + if (HavenBags.IsBag(result)) { + CustomAnvil.log("Detected anvil click haven bag bypass.") + bagUpgrade.onInventoryClick(event) + bagSkin.onInventoryClick(event) + return true; + } + + return false + } + + private fun testAnvilInventoryChange(inventory: AnvilInventory, previous: ItemStack?): Boolean { + val currentResult = inventory.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT) + + return currentResult == previous + } + +} diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/LegacyEcoEnchantDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/LegacyEcoEnchantDependency.kt new file mode 100644 index 0000000..5e82e5c --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/LegacyEcoEnchantDependency.kt @@ -0,0 +1,46 @@ +package xyz.alexcrea.cuanvil.dependency + +import com.willfp.ecoenchants.enchantments.EcoEnchant +import com.willfp.ecoenchants.enchantments.EcoEnchants +import org.bukkit.enchantments.Enchantment +import xyz.alexcrea.cuanvil.api.EnchantmentApi +import xyz.alexcrea.cuanvil.enchant.wrapped.CALegacyEcoEnchant + +class LegacyEcoEnchantDependency { + + + private var ecoEnchantOldEnchantments: MutableSet? = null + fun registerEnchantments() { + val enchantments = EcoEnchants.values() + for (ecoEnchant in enchantments) { + ecoEnchant as Enchantment + + EnchantmentApi.unregisterEnchantment(ecoEnchant) // As eco enchants is loaded before custom anvil and register enchantment to registry, we need to unregister old "vanilla" enchant. + EnchantmentApi.registerEnchantment(CALegacyEcoEnchant(ecoEnchant, ecoEnchant)) + } + + ecoEnchantOldEnchantments = HashSet(enchantments) + } + + fun handleConfigReload() { + // Should not happen in known case. + if (this.ecoEnchantOldEnchantments == null) return + + val newEnchantments = EcoEnchants.values() + + // Add new enchantments + for (ecoEnchant in newEnchantments) + if (!this.ecoEnchantOldEnchantments!!.contains(ecoEnchant)) + EnchantmentApi.registerEnchantment(CALegacyEcoEnchant(ecoEnchant, ecoEnchant as Enchantment)) + + + // Remove old enchantments that not now currently used + this.ecoEnchantOldEnchantments!!.removeAll(newEnchantments) + for (oldEnchantment in this.ecoEnchantOldEnchantments!!) { + EnchantmentApi.unregisterEnchantment(oldEnchantment as Enchantment) + } + + this.ecoEnchantOldEnchantments = HashSet(newEnchantments) + } + +} diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt index 0c0850b..1273c8e 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt @@ -191,7 +191,7 @@ class EnchantConflictManager { } val immutableEnchants = Collections.unmodifiableMap(appliedEnchants) - for (appliedEnchant in appliedEnchants) { + for (appliedEnchant in appliedEnchants.keys) { if(appliedEnchant is AdditionalTestEnchantment){ val doConflict = appliedEnchant.isEnchantConflict(immutableEnchants, mat) if(doConflict){ diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 4c27d82..570e258 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -58,3 +58,4 @@ softdepend: - EcoEnchants - eco - ExcellentEnchants + - HavenBags