diff --git a/.github/workflows/checkstyle.yml b/.github/workflows/checkstyle.yml deleted file mode 100644 index 971c6423..00000000 --- a/.github/workflows/checkstyle.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: Check PR Codestyle -on: [ pull_request ] - -jobs: - checkstyle: - name: Checkstyle - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: dbelyaev/action-checkstyle@v0.5.1 - with: - github_token: ${{ secrets.github_token }} - reporter: github-pr-review - level: warning - checkstyle_config: ../../config/checkstyle/checkstyle.xml \ No newline at end of file diff --git a/eco-api/src/main/java/com/willfp/eco/core/EcoPlugin.java b/eco-api/src/main/java/com/willfp/eco/core/EcoPlugin.java index 6be687a3..f5d1b21f 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/EcoPlugin.java +++ b/eco-api/src/main/java/com/willfp/eco/core/EcoPlugin.java @@ -19,9 +19,10 @@ import com.willfp.eco.core.proxy.ProxyFactory; import com.willfp.eco.core.registry.Registrable; import com.willfp.eco.core.registry.Registry; import com.willfp.eco.core.scheduling.Scheduler; +import com.willfp.eco.core.version.OutdatedEcoVersionError; +import com.willfp.eco.core.version.Version; import com.willfp.eco.core.web.UpdateChecker; import org.apache.commons.lang.Validate; -import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.bukkit.Bukkit; import org.bukkit.NamespacedKey; import org.bukkit.configuration.file.FileConfiguration; @@ -347,14 +348,14 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike, Regist they have an outdated version of eco installed. */ - DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.get().getEcoPlugin().getDescription().getVersion()); - DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion(this.getMinimumEcoVersion()); + Version runningVersion = new Version(Eco.get().getEcoPlugin().getDescription().getVersion()); + Version requiredVersion = new Version(this.getMinimumEcoVersion()); if (!(runningVersion.compareTo(requiredVersion) > 0 || runningVersion.equals(requiredVersion))) { this.getLogger().severe("You are running an outdated version of eco!"); this.getLogger().severe("You must be on at least" + this.getMinimumEcoVersion()); this.getLogger().severe("Download the newest version here:"); this.getLogger().severe("https://polymart.org/download/773/recent/JSpprMspkuyecf5y1wQ2Jn8OoLQSQ_IW"); - Bukkit.getPluginManager().disablePlugin(this); + throw new OutdatedEcoVersionError("This plugin requires at least eco version " + this.getMinimumEcoVersion() + " to run."); } } @@ -370,8 +371,8 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike, Regist if (this.getResourceId() != 0 && !Eco.get().getEcoPlugin().getConfigYml().getBool("no-update-checker")) { new UpdateChecker(this).getVersion(version -> { - DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(this.getDescription().getVersion()); - DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version); + Version currentVersion = new Version(this.getDescription().getVersion()); + Version mostRecentVersion = new Version(version); if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) { this.outdated = true; this.getLogger().warning(this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")"); diff --git a/eco-api/src/main/java/com/willfp/eco/core/data/ExternalDataStore.java b/eco-api/src/main/java/com/willfp/eco/core/data/ExternalDataStore.java index e4f5eeaa..0e4a51fd 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/data/ExternalDataStore.java +++ b/eco-api/src/main/java/com/willfp/eco/core/data/ExternalDataStore.java @@ -3,17 +3,26 @@ package com.willfp.eco.core.data; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.function.Supplier; /** * A simple store key-value store for data to be stored outside of plugins. */ +@SuppressWarnings("unchecked") public final class ExternalDataStore { /** * The store. */ - private static final HashMap data = new HashMap<>(); + private static final Map DATA = new HashMap<>(); + + /** + * The store adapters. + */ + private static final List> STORE_ADAPTERS = new ArrayList<>(); /** * Put data into the store. @@ -23,7 +32,29 @@ public final class ExternalDataStore { */ public static void put(@NotNull final String key, @NotNull final Object value) { - data.put(key, value); + doPut(key, value); + } + + /** + * Put data into the store. + * + * @param key The key. + * @param value The value. + * @param The stored type. + */ + private static void doPut(@NotNull final String key, + @NotNull final A value) { + Object storedValue = value; + + for (ExternalDataStoreObjectAdapter unknownAdapter : STORE_ADAPTERS) { + if (unknownAdapter.getAccessedClass().isInstance(value)) { + ExternalDataStoreObjectAdapter adapter = (ExternalDataStoreObjectAdapter) unknownAdapter; + storedValue = adapter.toStoredObject(value); + break; + } + } + + DATA.put(key, storedValue); } /** @@ -37,7 +68,30 @@ public final class ExternalDataStore { @Nullable public static T get(@NotNull final String key, @NotNull final Class clazz) { - Object value = data.get(key); + return doGet(key, clazz); + } + + /** + * Get data from the store. + * + * @param key The key. + * @param clazz The class. + * @param The accessed type. + * @param The stored type. + * @return The value. + */ + @Nullable + private static A doGet(@NotNull final String key, + @NotNull final Class clazz) { + Object value = DATA.get(key); + + for (ExternalDataStoreObjectAdapter unknownAdapter : STORE_ADAPTERS) { + if (unknownAdapter.getStoredClass().isInstance(value) && unknownAdapter.getAccessedClass().equals(clazz)) { + ExternalDataStoreObjectAdapter adapter = (ExternalDataStoreObjectAdapter) unknownAdapter; + value = adapter.toAccessedObject((S) value); + break; + } + } if (clazz.isInstance(value)) { return clazz.cast(value); @@ -79,6 +133,15 @@ public final class ExternalDataStore { return get(key, clazz, defaultValue.get()); } + /** + * Register a new adapter. + * + * @param adapter The adapter. + */ + public static void registerAdapter(@NotNull final ExternalDataStoreObjectAdapter adapter) { + STORE_ADAPTERS.add(adapter); + } + private ExternalDataStore() { throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); } diff --git a/eco-api/src/main/java/com/willfp/eco/core/data/ExternalDataStoreObjectAdapter.java b/eco-api/src/main/java/com/willfp/eco/core/data/ExternalDataStoreObjectAdapter.java new file mode 100644 index 00000000..2e6a4fd8 --- /dev/null +++ b/eco-api/src/main/java/com/willfp/eco/core/data/ExternalDataStoreObjectAdapter.java @@ -0,0 +1,69 @@ +package com.willfp.eco.core.data; + +import org.jetbrains.annotations.NotNull; + +/** + * An adapter for objects stored in {@link ExternalDataStore}. + * + * @param The accessed class. + * @param The stored class. + */ +public abstract class ExternalDataStoreObjectAdapter { + /** + * The class that is accessed (read / written). + */ + private final Class accessedClass; + + /** + * The class that is stored internally. + */ + private final Class storedClass; + + /** + * Create a new adapter. + * + * @param accessedClass The class that is accessed (read / written). + * @param storedClass The class that is stored internally. + */ + protected ExternalDataStoreObjectAdapter(@NotNull final Class accessedClass, + @NotNull final Class storedClass) { + this.accessedClass = accessedClass; + this.storedClass = storedClass; + } + + /** + * Convert an object to the stored object. + * + * @param obj The object. + * @return The stored object. + */ + @NotNull + public abstract S toStoredObject(@NotNull final A obj); + + /** + * Convert an object to the accessed object. + * + * @param obj The object. + * @return The accessed object. + */ + @NotNull + public abstract A toAccessedObject(@NotNull final S obj); + + /** + * Get the class that is accessed (read / written). + * + * @return The class. + */ + public Class getAccessedClass() { + return accessedClass; + } + + /** + * Get the class that is stored internally. + * + * @return The class. + */ + public Class getStoredClass() { + return storedClass; + } +} diff --git a/eco-api/src/main/java/com/willfp/eco/core/integrations/Integration.java b/eco-api/src/main/java/com/willfp/eco/core/integrations/Integration.java index ccc60591..31d87d92 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/integrations/Integration.java +++ b/eco-api/src/main/java/com/willfp/eco/core/integrations/Integration.java @@ -1,13 +1,22 @@ package com.willfp.eco.core.integrations; +import com.willfp.eco.core.registry.Registrable; +import com.willfp.eco.core.registry.Registry; +import org.jetbrains.annotations.NotNull; + /** * Abstract class for integrations. */ -public interface Integration { +public interface Integration extends Registrable { /** * Get the name of integration. * * @return The name. */ String getPluginName(); + + @Override + default @NotNull String getID() { + return Registry.tryFitPattern(this.getPluginName()); + } } diff --git a/eco-api/src/main/java/com/willfp/eco/core/integrations/IntegrationRegistry.java b/eco-api/src/main/java/com/willfp/eco/core/integrations/IntegrationRegistry.java new file mode 100644 index 00000000..21a25f7f --- /dev/null +++ b/eco-api/src/main/java/com/willfp/eco/core/integrations/IntegrationRegistry.java @@ -0,0 +1,131 @@ +package com.willfp.eco.core.integrations; + +import com.willfp.eco.core.Eco; +import com.willfp.eco.core.registry.Registry; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashSet; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; + +/** + * Registry for integrations. + * + * @param The type of integration. + */ +public class IntegrationRegistry extends Registry { + @Override + public @NotNull T register(@NotNull final T element) { + return executeSafely(() -> super.register(element), element); + } + + /** + * Iterate over all integrations, safely. + * + * @param action The action to perform. + */ + public void forEachSafely(@NotNull final Consumer action) { + for (T integration : new HashSet<>(this.values())) { + executeSafely(() -> action.accept(integration), integration); + } + } + + /** + * If any integrations return true, safely. + * + * @param predicate The predicate to test. + * @return If any integrations return true. + */ + public boolean anySafely(@NotNull final Predicate predicate) { + for (T integration : new HashSet<>(this.values())) { + Boolean result = executeSafely(() -> predicate.test(integration), integration); + if (result != null && result) { + return true; + } + } + return false; + } + + /** + * Get the first integration that returns a value, safely. + * + * @param function The function to apply. + * @param defaultValue The default value. + * @param The type of value. + * @return The first value that returns a value. + */ + @NotNull + public R firstSafely(@NotNull final Function function, + @NotNull final R defaultValue) { + if (this.isEmpty()) { + return defaultValue; + } + + T integration = this.iterator().next(); + + return executeSafely(() -> function.apply(integration), integration, defaultValue); + } + + /** + * Executes a given action safely, catching any exceptions and logging the issue. + * + * @param action The action to execute. + * @param integration The integration to apply the action on. + */ + private void executeSafely(@NotNull final Runnable action, + @NotNull final T integration) { + executeSafely(() -> { + action.run(); + return null; + }, integration); + } + + /** + * Executes a given action safely, catching any exceptions and logging the issue. + * + * @param action The action to execute. + * @param integration The integration to apply the action on. + * @param The return type of the action. + * @return The result of the action, or null if an exception was thrown. + */ + private R executeSafely(@NotNull final Supplier action, + @NotNull final T integration) { + return executeSafely(action, integration, null); + } + + /** + * Executes a given action safely, catching any exceptions and logging the issue. + * + * @param action The action to execute. + * @param integration The integration to apply the action on. + * @param defaultValue The default value to return if an exception is thrown. + * @param The return type of the action. + * @return The result of the action, or the default value if an exception was thrown. + */ + private R executeSafely(@NotNull final Supplier action, + @NotNull final T integration, + @Nullable final R defaultValue) { + try { + return action.get(); + } catch (final Exception e) { + Eco.get().getEcoPlugin().getLogger().warning("Integration for " + integration.getPluginName() + " threw an exception!"); + Eco.get().getEcoPlugin().getLogger().warning("The integration will be disabled."); + e.printStackTrace(); + this.remove(integration.getPluginName()); + return defaultValue; + } + } + + /** + * If all integrations return true, safely. + * + * @param predicate The predicate to test. + * @return If all integrations return true. + */ + public boolean allSafely(@NotNull final Predicate predicate) { + return !this.anySafely(predicate.negate()); + } +} diff --git a/eco-api/src/main/java/com/willfp/eco/core/integrations/afk/AFKManager.java b/eco-api/src/main/java/com/willfp/eco/core/integrations/afk/AFKManager.java index 0fe4b1f4..32096497 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/integrations/afk/AFKManager.java +++ b/eco-api/src/main/java/com/willfp/eco/core/integrations/afk/AFKManager.java @@ -1,11 +1,9 @@ package com.willfp.eco.core.integrations.afk; +import com.willfp.eco.core.integrations.IntegrationRegistry; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; -import java.util.HashSet; -import java.util.Set; - /** * Class to handle afk integrations. */ @@ -13,7 +11,7 @@ public final class AFKManager { /** * A set of all registered integrations. */ - private static final Set REGISTERED = new HashSet<>(); + private static final IntegrationRegistry REGISTRY = new IntegrationRegistry<>(); /** * Register a new integration. @@ -21,8 +19,7 @@ public final class AFKManager { * @param integration The integration to register. */ public static void register(@NotNull final AFKIntegration integration) { - REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); - REGISTERED.add(integration); + REGISTRY.register(integration); } /** @@ -32,13 +29,7 @@ public final class AFKManager { * @return If afk. */ public static boolean isAfk(@NotNull final Player player) { - for (AFKIntegration integration : REGISTERED) { - if (integration.isAfk(player)) { - return true; - } - } - - return false; + return REGISTRY.anySafely(integration -> integration.isAfk(player)); } private AFKManager() { diff --git a/eco-api/src/main/java/com/willfp/eco/core/integrations/anticheat/AnticheatManager.java b/eco-api/src/main/java/com/willfp/eco/core/integrations/anticheat/AnticheatManager.java index e94738d6..446fc9fa 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/integrations/anticheat/AnticheatManager.java +++ b/eco-api/src/main/java/com/willfp/eco/core/integrations/anticheat/AnticheatManager.java @@ -1,13 +1,11 @@ package com.willfp.eco.core.integrations.anticheat; import com.willfp.eco.core.Eco; +import com.willfp.eco.core.integrations.IntegrationRegistry; import org.bukkit.entity.Player; import org.bukkit.event.Listener; import org.jetbrains.annotations.NotNull; -import java.util.HashSet; -import java.util.Set; - /** * Class to handle anticheat integrations. */ @@ -15,7 +13,7 @@ public final class AnticheatManager { /** * A set of all registered anticheats. */ - private static final Set ANTICHEATS = new HashSet<>(); + private static final IntegrationRegistry REGISTRY = new IntegrationRegistry<>(); /** * Register a new anticheat. @@ -26,8 +24,7 @@ public final class AnticheatManager { if (anticheat instanceof Listener) { Eco.get().getEcoPlugin().getEventManager().registerListener((Listener) anticheat); } - ANTICHEATS.removeIf(it -> it.getPluginName().equalsIgnoreCase(anticheat.getPluginName())); - ANTICHEATS.add(anticheat); + REGISTRY.register(anticheat); } /** @@ -36,17 +33,16 @@ public final class AnticheatManager { * @param player The player to exempt. */ public static void exemptPlayer(@NotNull final Player player) { - ANTICHEATS.forEach(anticheat -> anticheat.exempt(player)); + REGISTRY.forEachSafely(anticheat -> anticheat.exempt(player)); } /** * Unexempt a player from triggering anticheats. - * This is ran a tick after it is called to ensure that there are no event timing conflicts. * * @param player The player to remove the exemption. */ public static void unexemptPlayer(@NotNull final Player player) { - ANTICHEATS.forEach(anticheat -> anticheat.unexempt(player)); + REGISTRY.forEachSafely(anticheat -> anticheat.unexempt(player)); } private AnticheatManager() { diff --git a/eco-api/src/main/java/com/willfp/eco/core/integrations/antigrief/AntigriefManager.java b/eco-api/src/main/java/com/willfp/eco/core/integrations/antigrief/AntigriefManager.java index c96fcd52..a96d898f 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/integrations/antigrief/AntigriefManager.java +++ b/eco-api/src/main/java/com/willfp/eco/core/integrations/antigrief/AntigriefManager.java @@ -1,5 +1,6 @@ package com.willfp.eco.core.integrations.antigrief; +import com.willfp.eco.core.integrations.IntegrationRegistry; import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.entity.LivingEntity; @@ -16,7 +17,7 @@ public final class AntigriefManager { /** * Registered antigriefs. */ - private static final Set REGISTERED = new HashSet<>(); + private static final IntegrationRegistry REGISTRY = new IntegrationRegistry<>(); /** * Register a new AntiGrief/Land Management integration. @@ -24,8 +25,7 @@ public final class AntigriefManager { * @param antigrief The integration to register. */ public static void register(@NotNull final AntigriefIntegration antigrief) { - REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(antigrief.getPluginName())); - REGISTERED.add(antigrief); + REGISTRY.register(antigrief); } /** @@ -34,8 +34,7 @@ public final class AntigriefManager { * @param antigrief The integration to unregister. */ public static void unregister(@NotNull final AntigriefIntegration antigrief) { - REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(antigrief.getPluginName())); - REGISTERED.remove(antigrief); + REGISTRY.remove(antigrief); } /** @@ -47,7 +46,7 @@ public final class AntigriefManager { */ public static boolean canPickupItem(@NotNull final Player player, @NotNull final Location location) { - return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canPickupItem(player, location)); + return REGISTRY.allSafely(integration -> integration.canPickupItem(player, location)); } /** @@ -59,7 +58,7 @@ public final class AntigriefManager { */ public static boolean canBreakBlock(@NotNull final Player player, @NotNull final Block block) { - return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canBreakBlock(player, block)); + return REGISTRY.allSafely(integration -> integration.canBreakBlock(player, block)); } /** @@ -71,7 +70,7 @@ public final class AntigriefManager { */ public static boolean canCreateExplosion(@NotNull final Player player, @NotNull final Location location) { - return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canCreateExplosion(player, location)); + return REGISTRY.allSafely(integration -> integration.canCreateExplosion(player, location)); } /** @@ -83,7 +82,7 @@ public final class AntigriefManager { */ public static boolean canPlaceBlock(@NotNull final Player player, @NotNull final Block block) { - return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canPlaceBlock(player, block)); + return REGISTRY.allSafely(integration -> integration.canPlaceBlock(player, block)); } /** @@ -95,7 +94,7 @@ public final class AntigriefManager { */ public static boolean canInjure(@NotNull final Player player, @NotNull final LivingEntity victim) { - return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canInjure(player, victim)); + return REGISTRY.allSafely(integration -> integration.canInjure(player, victim)); } private AntigriefManager() { diff --git a/eco-api/src/main/java/com/willfp/eco/core/integrations/customentities/CustomEntitiesManager.java b/eco-api/src/main/java/com/willfp/eco/core/integrations/customentities/CustomEntitiesManager.java index 613bfe15..dc348304 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/integrations/customentities/CustomEntitiesManager.java +++ b/eco-api/src/main/java/com/willfp/eco/core/integrations/customentities/CustomEntitiesManager.java @@ -1,10 +1,8 @@ package com.willfp.eco.core.integrations.customentities; +import com.willfp.eco.core.integrations.IntegrationRegistry; import org.jetbrains.annotations.NotNull; -import java.util.HashSet; -import java.util.Set; - /** * Class to handle custom entity integrations. */ @@ -12,7 +10,7 @@ public final class CustomEntitiesManager { /** * A set of all registered integrations. */ - private static final Set REGISTERED = new HashSet<>(); + private static final IntegrationRegistry REGISTRY = new IntegrationRegistry<>(); /** * Register a new integration. @@ -20,8 +18,7 @@ public final class CustomEntitiesManager { * @param integration The integration to register. */ public static void register(@NotNull final CustomEntitiesIntegration integration) { - REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); - REGISTERED.add(integration); + REGISTRY.register(integration); } /** @@ -30,9 +27,7 @@ public final class CustomEntitiesManager { * @see com.willfp.eco.core.entities.Entities */ public static void registerAllEntities() { - for (CustomEntitiesIntegration integration : REGISTERED) { - integration.registerAllEntities(); - } + REGISTRY.forEachSafely(CustomEntitiesIntegration::registerAllEntities); } private CustomEntitiesManager() { diff --git a/eco-api/src/main/java/com/willfp/eco/core/integrations/customitems/CustomItemsManager.java b/eco-api/src/main/java/com/willfp/eco/core/integrations/customitems/CustomItemsManager.java index 047fbf9f..961bc3bc 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/integrations/customitems/CustomItemsManager.java +++ b/eco-api/src/main/java/com/willfp/eco/core/integrations/customitems/CustomItemsManager.java @@ -1,5 +1,6 @@ package com.willfp.eco.core.integrations.customitems; +import com.willfp.eco.core.integrations.IntegrationRegistry; import org.jetbrains.annotations.NotNull; import java.util.HashSet; @@ -12,7 +13,7 @@ public final class CustomItemsManager { /** * A set of all registered integrations. */ - private static final Set REGISTERED = new HashSet<>(); + private static final IntegrationRegistry REGISTRY = new IntegrationRegistry<>(); /** * Register a new integration. @@ -20,8 +21,7 @@ public final class CustomItemsManager { * @param integration The integration to register. */ public static void register(@NotNull final CustomItemsIntegration integration) { - REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); - REGISTERED.add(integration); + REGISTRY.register(integration); } /** @@ -30,9 +30,7 @@ public final class CustomItemsManager { * @see com.willfp.eco.core.items.Items */ public static void registerAllItems() { - for (CustomItemsIntegration customItemsIntegration : REGISTERED) { - customItemsIntegration.registerAllItems(); - } + REGISTRY.forEachSafely(CustomItemsIntegration::registerAllItems); } /** @@ -41,9 +39,7 @@ public final class CustomItemsManager { * @see com.willfp.eco.core.items.Items */ public static void registerProviders() { - for (CustomItemsIntegration customItemsIntegration : REGISTERED) { - customItemsIntegration.registerProvider(); - } + REGISTRY.forEachSafely(CustomItemsIntegration::registerProvider); } private CustomItemsManager() { diff --git a/eco-api/src/main/java/com/willfp/eco/core/integrations/economy/EconomyManager.java b/eco-api/src/main/java/com/willfp/eco/core/integrations/economy/EconomyManager.java index 894decd5..bbe12181 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/integrations/economy/EconomyManager.java +++ b/eco-api/src/main/java/com/willfp/eco/core/integrations/economy/EconomyManager.java @@ -1,11 +1,10 @@ package com.willfp.eco.core.integrations.economy; +import com.willfp.eco.core.integrations.IntegrationRegistry; import org.bukkit.OfflinePlayer; import org.jetbrains.annotations.NotNull; import java.math.BigDecimal; -import java.util.HashSet; -import java.util.Set; /** * Class to handle economy. @@ -14,7 +13,7 @@ public final class EconomyManager { /** * A set of all registered integrations. */ - private static final Set REGISTERED = new HashSet<>(); + private static final IntegrationRegistry REGISTRY = new IntegrationRegistry<>(); /** * Register a new integration. @@ -22,8 +21,7 @@ public final class EconomyManager { * @param integration The integration to register. */ public static void register(@NotNull final EconomyIntegration integration) { - REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); - REGISTERED.add(integration); + REGISTRY.register(integration); } /** @@ -32,7 +30,7 @@ public final class EconomyManager { * @return If any economy. */ public static boolean hasRegistrations() { - return !REGISTERED.isEmpty(); + return REGISTRY.isNotEmpty(); } /** @@ -56,11 +54,10 @@ public final class EconomyManager { */ public static boolean hasAmount(@NotNull final OfflinePlayer player, final BigDecimal amount) { - for (EconomyIntegration integration : REGISTERED) { - return integration.hasAmount(player, amount); - } - - return false; + return REGISTRY.firstSafely( + integration -> integration.hasAmount(player, amount), + false + ); } /** @@ -84,11 +81,10 @@ public final class EconomyManager { */ public static boolean giveMoney(@NotNull final OfflinePlayer player, @NotNull final BigDecimal amount) { - for (EconomyIntegration integration : REGISTERED) { - return integration.giveMoney(player, amount); - } - - return false; + return REGISTRY.firstSafely( + integration -> integration.giveMoney(player, amount), + false + ); } /** @@ -112,11 +108,10 @@ public final class EconomyManager { */ public static boolean removeMoney(@NotNull final OfflinePlayer player, @NotNull final BigDecimal amount) { - for (EconomyIntegration integration : REGISTERED) { - return integration.removeMoney(player, amount); - } - - return false; + return REGISTRY.firstSafely( + integration -> integration.removeMoney(player, amount), + false + ); } /** @@ -136,11 +131,10 @@ public final class EconomyManager { * @return The balance. */ public static BigDecimal getExactBalance(@NotNull final OfflinePlayer player) { - for (EconomyIntegration integration : REGISTERED) { - return integration.getExactBalance(player); - } - - return BigDecimal.ZERO; + return REGISTRY.firstSafely( + integration -> integration.getExactBalance(player), + BigDecimal.ZERO + ); } private EconomyManager() { diff --git a/eco-api/src/main/java/com/willfp/eco/core/integrations/guidetection/GUIDetectionManager.java b/eco-api/src/main/java/com/willfp/eco/core/integrations/guidetection/GUIDetectionManager.java index 07bd28f6..89d21ee9 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/integrations/guidetection/GUIDetectionManager.java +++ b/eco-api/src/main/java/com/willfp/eco/core/integrations/guidetection/GUIDetectionManager.java @@ -1,12 +1,10 @@ package com.willfp.eco.core.integrations.guidetection; +import com.willfp.eco.core.integrations.IntegrationRegistry; import com.willfp.eco.util.MenuUtils; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; -import java.util.HashSet; -import java.util.Set; - /** * Class to handle GUI detection. */ @@ -14,7 +12,7 @@ public final class GUIDetectionManager { /** * A set of all registered integrations. */ - private static final Set REGISTERED = new HashSet<>(); + private static final IntegrationRegistry REGISTRY = new IntegrationRegistry<>(); /** * Register a new integration. @@ -22,8 +20,7 @@ public final class GUIDetectionManager { * @param integration The integration to register. */ public static void register(@NotNull final GUIDetectionIntegration integration) { - REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); - REGISTERED.add(integration); + REGISTRY.register(integration); } /** @@ -37,13 +34,7 @@ public final class GUIDetectionManager { return true; } - for (GUIDetectionIntegration integration : REGISTERED) { - if (integration.hasGUIOpen(player)) { - return true; - } - } - - return false; + return REGISTRY.anySafely(integration -> integration.hasGUIOpen(player)); } private GUIDetectionManager() { diff --git a/eco-api/src/main/java/com/willfp/eco/core/integrations/hologram/HologramManager.java b/eco-api/src/main/java/com/willfp/eco/core/integrations/hologram/HologramManager.java index eed2f94a..0dc000fa 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/integrations/hologram/HologramManager.java +++ b/eco-api/src/main/java/com/willfp/eco/core/integrations/hologram/HologramManager.java @@ -1,11 +1,10 @@ package com.willfp.eco.core.integrations.hologram; +import com.willfp.eco.core.integrations.IntegrationRegistry; import org.bukkit.Location; import org.jetbrains.annotations.NotNull; -import java.util.HashSet; import java.util.List; -import java.util.Set; /** * Class to handle hologram integrations. @@ -14,7 +13,7 @@ public final class HologramManager { /** * A set of all registered integrations. */ - private static final Set REGISTERED = new HashSet<>(); + private static final IntegrationRegistry REGISTRY = new IntegrationRegistry<>(); /** * Register a new integration. @@ -22,8 +21,7 @@ public final class HologramManager { * @param integration The integration to register. */ public static void register(@NotNull final HologramIntegration integration) { - REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); - REGISTERED.add(integration); + REGISTRY.register(integration); } /** @@ -35,11 +33,10 @@ public final class HologramManager { */ public static Hologram createHologram(@NotNull final Location location, @NotNull final List contents) { - for (HologramIntegration integration : REGISTERED) { - return integration.createHologram(location, contents); - } - - return new DummyHologram(); + return REGISTRY.firstSafely( + integration -> integration.createHologram(location, contents), + new DummyHologram() + ); } private HologramManager() { diff --git a/eco-api/src/main/java/com/willfp/eco/core/integrations/mcmmo/McmmoManager.java b/eco-api/src/main/java/com/willfp/eco/core/integrations/mcmmo/McmmoManager.java index 0a29ac77..43f3dd1c 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/integrations/mcmmo/McmmoManager.java +++ b/eco-api/src/main/java/com/willfp/eco/core/integrations/mcmmo/McmmoManager.java @@ -1,5 +1,6 @@ package com.willfp.eco.core.integrations.mcmmo; +import com.willfp.eco.core.integrations.IntegrationRegistry; import org.bukkit.block.Block; import org.bukkit.event.Event; import org.jetbrains.annotations.NotNull; @@ -14,7 +15,7 @@ public final class McmmoManager { /** * A set of all registered integrations. */ - private static final Set REGISTERED = new HashSet<>(); + private static final IntegrationRegistry REGISTERED = new IntegrationRegistry<>(); /** * Register a new integration. @@ -22,8 +23,7 @@ public final class McmmoManager { * @param integration The integration to register. */ public static void register(@NotNull final McmmoIntegration integration) { - REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); - REGISTERED.add(integration); + REGISTERED.register(integration); } /** @@ -34,13 +34,11 @@ public final class McmmoManager { */ public static int getBonusDropCount(@NotNull final Block block) { int finalValue = 0; + for (McmmoIntegration mcmmoIntegration : REGISTERED) { finalValue += mcmmoIntegration.getBonusDropCount(block); - - - - } + return finalValue; } @@ -51,13 +49,7 @@ public final class McmmoManager { * @return If the event is fake. */ public static boolean isFake(@NotNull final Event event) { - for (McmmoIntegration mcmmoIntegration : REGISTERED) { - if (mcmmoIntegration.isFake(event)) { - return true; - } - - } - return false; + return REGISTERED.anySafely(integration -> integration.isFake(event)); } private McmmoManager() { diff --git a/eco-api/src/main/java/com/willfp/eco/core/integrations/shop/ShopManager.java b/eco-api/src/main/java/com/willfp/eco/core/integrations/shop/ShopManager.java index ffdfc8ab..4b0bff11 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/integrations/shop/ShopManager.java +++ b/eco-api/src/main/java/com/willfp/eco/core/integrations/shop/ShopManager.java @@ -1,5 +1,6 @@ package com.willfp.eco.core.integrations.shop; +import com.willfp.eco.core.integrations.IntegrationRegistry; import com.willfp.eco.core.price.Price; import com.willfp.eco.core.price.impl.PriceFree; import org.bukkit.entity.Player; @@ -13,11 +14,12 @@ import java.util.Set; /** * Class to handle shop integrations. */ +@SuppressWarnings("DeprecatedIsStillUsed") public final class ShopManager { /** * A set of all registered integrations. */ - private static final Set REGISTERED = new HashSet<>(); + private static final IntegrationRegistry REGISTRY = new IntegrationRegistry<>(); /** * Register a new integration. @@ -25,17 +27,14 @@ public final class ShopManager { * @param integration The integration to register. */ public static void register(@NotNull final ShopIntegration integration) { - REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); - REGISTERED.add(integration); + REGISTRY.register(integration); } /** * Register eco item provider for shop plugins. */ public static void registerEcoProvider() { - for (ShopIntegration shopIntegration : REGISTERED) { - shopIntegration.registerEcoProvider(); - } + REGISTRY.forEachSafely(ShopIntegration::registerEcoProvider); } /** @@ -51,11 +50,7 @@ public final class ShopManager { return false; } - for (ShopIntegration integration : REGISTERED) { - return integration.isSellable(itemStack, player); - } - - return false; + return REGISTRY.anySafely(integration -> integration.isSellable(itemStack, player)); } /** @@ -74,11 +69,10 @@ public final class ShopManager { return new PriceFree(); } - for (ShopIntegration integration : REGISTERED) { - return integration.getUnitValue(itemStack, player); - } - - return new PriceFree(); + return REGISTRY.firstSafely( + integration -> integration.getUnitValue(itemStack, player), + new PriceFree() + ); } /** @@ -108,11 +102,10 @@ public final class ShopManager { return 0.0; } - for (ShopIntegration shopIntegration : REGISTERED) { - return shopIntegration.getUnitValue(itemStack, player).getValue(player, itemStack.getAmount()); - } - - return 0.0; + return REGISTRY.firstSafely( + integration -> integration.getUnitValue(itemStack, player).getValue(player, itemStack.getAmount()), + 0.0 + ); } /** @@ -121,7 +114,7 @@ public final class ShopManager { * @return The integrations. */ public static Set getRegisteredIntegrations() { - return new HashSet<>(REGISTERED); + return new HashSet<>(REGISTRY.values()); } private ShopManager() { diff --git a/eco-api/src/main/java/com/willfp/eco/core/registry/Registry.java b/eco-api/src/main/java/com/willfp/eco/core/registry/Registry.java index dceda57b..e6ff3087 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/registry/Registry.java +++ b/eco-api/src/main/java/com/willfp/eco/core/registry/Registry.java @@ -5,6 +5,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.regex.Pattern; @@ -14,7 +16,7 @@ import java.util.regex.Pattern; * * @param The type of {@link Registrable}. */ -public class Registry { +public class Registry implements Iterable { /** * The ID pattern. */ @@ -25,6 +27,17 @@ public class Registry { */ private final Map registry = new HashMap<>(); + /** + * If the registry is locked. + */ + private boolean isLocked = false; + + /** + * The locker, used to 'secure' registries and prevent random unlocking. + */ + @Nullable + private Object locker = null; + /** * Instantiate a new registry. */ @@ -40,6 +53,10 @@ public class Registry { */ @NotNull public T register(@NotNull final T element) { + if (this.isLocked) { + throw new IllegalStateException("Cannot add to locked registry! (ID: " + element.getID() + ")"); + } + Validate.isTrue(ID_PATTERN.matcher(element.getID()).matches(), "ID must match pattern: " + ID_PATTERN.pattern() + " (was " + element.getID() + ")"); registry.put(element.getID(), element); @@ -56,6 +73,10 @@ public class Registry { * @return The element. */ public T remove(@NotNull final T element) { + if (this.isLocked) { + throw new IllegalStateException("Cannot remove from locked registry! (ID: " + element.getID() + ")"); + } + element.onRemove(); registry.remove(element.getID()); @@ -71,6 +92,10 @@ public class Registry { */ @Nullable public T remove(@NotNull final String id) { + if (this.isLocked) { + throw new IllegalStateException("Cannot remove from locked registry! (ID: " + id + ")"); + } + T element = registry.get(id); if (element != null) { @@ -109,6 +134,61 @@ public class Registry { return Set.copyOf(registry.values()); } + /** + * Get if the registry is locked. + * + * @return If the registry is locked. + */ + public boolean isLocked() { + return isLocked; + } + + /** + * Lock the registry. + * + * @param locker The locker. + */ + public void lock(@Nullable final Object locker) { + this.locker = locker; + isLocked = true; + } + + /** + * Unlock the registry. + * + * @param locker The locker. + */ + public void unlock(@Nullable final Object locker) { + if (this.locker != locker) { + throw new IllegalArgumentException("Cannot unlock registry!"); + } + isLocked = false; + } + + /** + * Get if the registry is empty. + * + * @return If the registry is empty. + */ + public boolean isEmpty() { + return registry.isEmpty(); + } + + /** + * Get if the registry is not empty. + * + * @return If the registry is not empty. + */ + public boolean isNotEmpty() { + return !isEmpty(); + } + + @NotNull + @Override + public Iterator iterator() { + return values().iterator(); + } + /** * Try to fit a string to the ID pattern. * @@ -120,6 +200,6 @@ public class Registry { return string.replace(" ", "_") .replace(".", "_") .replace("-", "_") - .toLowerCase(); + .toLowerCase(Locale.ENGLISH); } } diff --git a/eco-api/src/main/java/com/willfp/eco/core/version/OutdatedEcoVersionError.java b/eco-api/src/main/java/com/willfp/eco/core/version/OutdatedEcoVersionError.java new file mode 100644 index 00000000..5a1ca56f --- /dev/null +++ b/eco-api/src/main/java/com/willfp/eco/core/version/OutdatedEcoVersionError.java @@ -0,0 +1,17 @@ +package com.willfp.eco.core.version; + +import org.jetbrains.annotations.NotNull; + +/** + * An error thrown when eco is outdated. + */ +public class OutdatedEcoVersionError extends Error { + /** + * Create a new OutdatedEcoVersionError. + * + * @param message The message. + */ + public OutdatedEcoVersionError(@NotNull final String message) { + super(message); + } +} diff --git a/eco-api/src/main/java/com/willfp/eco/core/version/Version.java b/eco-api/src/main/java/com/willfp/eco/core/version/Version.java new file mode 100644 index 00000000..c0c62c53 --- /dev/null +++ b/eco-api/src/main/java/com/willfp/eco/core/version/Version.java @@ -0,0 +1,53 @@ +package com.willfp.eco.core.version; + +import org.apache.maven.artifact.versioning.DefaultArtifactVersion; +import org.jetbrains.annotations.NotNull; + +/** + * A minimal class to represent a version, uses DefaultArtifactVersion under the hood. + *

+ * This class exists to resolve issues where 1.17 doesn't include DefaultArtifactVersion. + */ +public class Version implements Comparable { + /** + * The version. + */ + private final DefaultArtifactVersion version; + + /** + * Create a new version. + * + * @param version The version. + */ + public Version(@NotNull final String version) { + this.version = new DefaultArtifactVersion(version); + } + + @Override + public int compareTo(@NotNull final Version o) { + return this.version.compareTo(o.version); + } + + @Override + public String toString() { + return this.version.toString(); + } + + @Override + public boolean equals(@NotNull final Object obj) { + if (obj == this) { + return true; + } + + if (!(obj instanceof Version other)) { + return false; + } + + return this.version.equals(other.version); + } + + @Override + public int hashCode() { + return this.version.hashCode(); + } +} diff --git a/eco-api/src/main/kotlin/com/willfp/eco/core/registry/KRegistrable.kt b/eco-api/src/main/kotlin/com/willfp/eco/core/registry/KRegistrable.kt new file mode 100644 index 00000000..e61ad5d5 --- /dev/null +++ b/eco-api/src/main/kotlin/com/willfp/eco/core/registry/KRegistrable.kt @@ -0,0 +1,13 @@ +package com.willfp.eco.core.registry + +/** + * A registrable that has a string ID, for use with Kotlin. + */ +interface KRegistrable : Registrable { + /** + * The ID of the registrable. + */ + val id: String + + override fun getID() = id +} diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/data/VersionAdapters.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/data/VersionAdapters.kt new file mode 100644 index 00000000..2ce7417f --- /dev/null +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/data/VersionAdapters.kt @@ -0,0 +1,27 @@ +package com.willfp.eco.internal.data + +import com.willfp.eco.core.data.ExternalDataStoreObjectAdapter +import com.willfp.eco.core.version.Version + +object VersionToStringAdapter: ExternalDataStoreObjectAdapter( + Version::class.java, + String::class.java +) { + override fun toAccessedObject(obj: String): Version = Version(obj) + + override fun toStoredObject(obj: Version): String = obj.toString() +} + +class MavenVersionToStringAdapter( + className: String +): ExternalDataStoreObjectAdapter( + Class.forName(className), + String::class.java +) { + private val constructor = Class.forName(className) + .getConstructor(String::class.java) + + override fun toAccessedObject(obj: String): Any = constructor.newInstance(obj) + + override fun toStoredObject(obj: Any): String = obj.toString() +} diff --git a/eco-core/core-nms/v1_17_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_17_R1/SNBTConverter.kt b/eco-core/core-nms/v1_17_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_17_R1/SNBTConverter.kt index e130ccd9..a8a24249 100644 --- a/eco-core/core-nms/v1_17_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_17_R1/SNBTConverter.kt +++ b/eco-core/core-nms/v1_17_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_17_R1/SNBTConverter.kt @@ -45,7 +45,7 @@ class SNBTConverter : SNBTConverterProxy { val nms = CraftItemStack.asNMSCopy(itemStack) val nmsTag = nms.save(CompoundTag()) nmsTag.remove("Count") - return tag.copy().merge(nmsTag) == nmsTag + return tag.copy().merge(nmsTag) == nmsTag && itemStack.type == item.type } override fun getItem(): ItemStack = item diff --git a/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/SNBTConverter.kt b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/SNBTConverter.kt index aa91422e..12732258 100644 --- a/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/SNBTConverter.kt +++ b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/SNBTConverter.kt @@ -45,7 +45,7 @@ class SNBTConverter : SNBTConverterProxy { val nms = CraftItemStack.asNMSCopy(itemStack) val nmsTag = nms.save(CompoundTag()) nmsTag.remove("Count") - return tag.copy().merge(nmsTag) == nmsTag + return tag.copy().merge(nmsTag) == nmsTag && itemStack.type == item.type } override fun getItem(): ItemStack = item diff --git a/eco-core/core-nms/v1_18_R2/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R2/SNBTConverter.kt b/eco-core/core-nms/v1_18_R2/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R2/SNBTConverter.kt index f4fbd2bf..afaab596 100644 --- a/eco-core/core-nms/v1_18_R2/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R2/SNBTConverter.kt +++ b/eco-core/core-nms/v1_18_R2/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R2/SNBTConverter.kt @@ -45,7 +45,7 @@ class SNBTConverter : SNBTConverterProxy { val nms = CraftItemStack.asNMSCopy(itemStack) val nmsTag = nms.save(CompoundTag()) nmsTag.remove("Count") - return tag.copy().merge(nmsTag) == nmsTag + return tag.copy().merge(nmsTag) == nmsTag && itemStack.type == item.type } override fun getItem(): ItemStack = item diff --git a/eco-core/core-nms/v1_19_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_19_R1/SNBTConverter.kt b/eco-core/core-nms/v1_19_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_19_R1/SNBTConverter.kt index 8f15528e..4bb9b080 100644 --- a/eco-core/core-nms/v1_19_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_19_R1/SNBTConverter.kt +++ b/eco-core/core-nms/v1_19_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_19_R1/SNBTConverter.kt @@ -3,6 +3,7 @@ package com.willfp.eco.internal.spigot.proxy.v1_19_R1 import com.willfp.eco.core.items.TestableItem import com.willfp.eco.core.recipe.parts.EmptyTestableItem import com.willfp.eco.internal.spigot.proxy.SNBTConverterProxy +import com.willfp.eco.internal.spigot.proxy.common.toMaterial import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.SnbtPrinterTagVisitor import net.minecraft.nbt.TagParser @@ -44,7 +45,7 @@ class SNBTConverter : SNBTConverterProxy { val nms = CraftItemStack.asNMSCopy(itemStack) val nmsTag = nms.save(CompoundTag()) nmsTag.remove("Count") - return tag.copy().merge(nmsTag) == nmsTag + return tag.copy().merge(nmsTag) == nmsTag && itemStack.type == item.type } override fun getItem(): ItemStack = item diff --git a/eco-core/core-nms/v1_19_R2/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_19_R2/SNBTConverter.kt b/eco-core/core-nms/v1_19_R2/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_19_R2/SNBTConverter.kt index bf94e70d..2d7a5ab4 100644 --- a/eco-core/core-nms/v1_19_R2/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_19_R2/SNBTConverter.kt +++ b/eco-core/core-nms/v1_19_R2/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_19_R2/SNBTConverter.kt @@ -44,7 +44,7 @@ class SNBTConverter : SNBTConverterProxy { val nms = CraftItemStack.asNMSCopy(itemStack) val nmsTag = nms.save(CompoundTag()) nmsTag.remove("Count") - return tag.copy().merge(nmsTag) == nmsTag + return tag.copy().merge(nmsTag) == nmsTag && itemStack.type == item.type } override fun getItem(): ItemStack = item diff --git a/eco-core/core-nms/v1_19_R3/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_19_R3/SNBTConverter.kt b/eco-core/core-nms/v1_19_R3/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_19_R3/SNBTConverter.kt index 45379534..c3bad750 100644 --- a/eco-core/core-nms/v1_19_R3/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_19_R3/SNBTConverter.kt +++ b/eco-core/core-nms/v1_19_R3/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_19_R3/SNBTConverter.kt @@ -44,7 +44,7 @@ class SNBTConverter : SNBTConverterProxy { val nms = CraftItemStack.asNMSCopy(itemStack) val nmsTag = nms.save(CompoundTag()) nmsTag.remove("Count") - return tag.copy().merge(nmsTag) == nmsTag + return tag.copy().merge(nmsTag) == nmsTag && itemStack.type == item.type } override fun getItem(): ItemStack = item diff --git a/eco-core/core-plugin/build.gradle.kts b/eco-core/core-plugin/build.gradle.kts index 00f8ebda..feeb4e61 100644 --- a/eco-core/core-plugin/build.gradle.kts +++ b/eco-core/core-plugin/build.gradle.kts @@ -37,7 +37,7 @@ dependencies { compileOnly("com.github.jiangdashao:matrix-api-repo:317d4635fd") compileOnly("com.gmail.nossr50.mcMMO:mcMMO:2.1.202") compileOnly("me.clip:placeholderapi:2.10.10") - compileOnly("com.github.oraxen:oraxen:bea381fb82") + compileOnly("com.github.oraxen:oraxen:1.155.0") compileOnly("com.github.brcdev-minecraft:shopgui-api:3.0.0") compileOnly("com.github.LoneDev6:API-ItemsAdder:2.4.7") compileOnly("com.arcaniax:HeadDatabase-API:1.3.0") diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/EcoSpigotPlugin.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/EcoSpigotPlugin.kt index c47dbfc0..48f343da 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/EcoSpigotPlugin.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/EcoSpigotPlugin.kt @@ -3,6 +3,7 @@ package com.willfp.eco.internal.spigot import com.willfp.eco.core.Eco import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.Prerequisite +import com.willfp.eco.core.data.ExternalDataStore import com.willfp.eco.core.entities.Entities import com.willfp.eco.core.integrations.IntegrationLoader import com.willfp.eco.core.integrations.afk.AFKManager @@ -19,6 +20,8 @@ import com.willfp.eco.core.items.Items import com.willfp.eco.core.packet.PacketListener import com.willfp.eco.core.particle.Particles import com.willfp.eco.core.price.Prices +import com.willfp.eco.internal.data.MavenVersionToStringAdapter +import com.willfp.eco.internal.data.VersionToStringAdapter import com.willfp.eco.internal.entities.EntityArgParserAdult import com.willfp.eco.internal.entities.EntityArgParserAttackDamage import com.willfp.eco.internal.entities.EntityArgParserAttackSpeed @@ -120,6 +123,7 @@ import com.willfp.eco.internal.spigot.recipes.listeners.ComplexInComplex import com.willfp.eco.internal.spigot.recipes.listeners.ComplexInVanilla import com.willfp.eco.internal.spigot.recipes.stackhandlers.ShapedCraftingRecipeStackHandler import com.willfp.eco.internal.spigot.recipes.stackhandlers.ShapelessCraftingRecipeStackHandler +import com.willfp.eco.util.ClassUtils import me.TechsCode.UltraEconomy.UltraEconomy import net.kyori.adventure.platform.bukkit.BukkitAudiences import net.milkbowl.vault.economy.Economy @@ -178,6 +182,20 @@ abstract class EcoSpigotPlugin : EcoPlugin() { SegmentParserUseIfPresent.register() CustomItemsManager.registerProviders() + + ExternalDataStore.registerAdapter(VersionToStringAdapter) + // Handle with shadow. + val className = listOf( + "org", + "apache", + "maven", + "artifact", + "versioning", + "DefaultArtifactVersion" + ).joinToString(".") + if (ClassUtils.exists(className)) { + ExternalDataStore.registerAdapter(MavenVersionToStringAdapter(className)) + } } override fun handleEnable() { @@ -270,6 +288,7 @@ abstract class EcoSpigotPlugin : EcoPlugin() { IntegrationLoader("CombatLogX") { val pluginManager = Bukkit.getPluginManager() val combatLogXPlugin = pluginManager.getPlugin("CombatLogX") ?: return@IntegrationLoader + @Suppress("DEPRECATION") val pluginVersion = combatLogXPlugin.description.version if (pluginVersion.startsWith("10")) { @@ -294,7 +313,7 @@ abstract class EcoSpigotPlugin : EcoPlugin() { IntegrationLoader("MythicMobs") { CustomEntitiesManager.register(CustomEntitiesMythicMobs()) }, // Custom Items - IntegrationLoader("Oraxen") { CustomItemsManager.register(CustomItemsOraxen()) }, + IntegrationLoader("Oraxen") { CustomItemsManager.register(CustomItemsOraxen(this)) }, IntegrationLoader("ItemsAdder") { CustomItemsManager.register(CustomItemsItemsAdder()) }, IntegrationLoader("HeadDatabase") { CustomItemsManager.register(CustomItemsHeadDatabase(this)) }, IntegrationLoader("ExecutableItems") { CustomItemsManager.register(CustomItemsExecutableItems()) }, diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/integrations/customitems/CustomItemsOraxen.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/integrations/customitems/CustomItemsOraxen.kt index d8e776c7..9b4c7fb1 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/integrations/customitems/CustomItemsOraxen.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/integrations/customitems/CustomItemsOraxen.kt @@ -1,5 +1,6 @@ package com.willfp.eco.internal.spigot.integrations.customitems +import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.integrations.customitems.CustomItemsIntegration import com.willfp.eco.core.items.CustomItem import com.willfp.eco.core.items.Items @@ -7,16 +8,27 @@ import com.willfp.eco.core.items.TestableItem import com.willfp.eco.core.items.provider.ItemProvider import com.willfp.eco.util.NamespacedKeyUtils import io.th0rgal.oraxen.api.OraxenItems +import io.th0rgal.oraxen.api.events.OraxenItemsLoadedEvent +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener -class CustomItemsOraxen : CustomItemsIntegration { +class CustomItemsOraxen( + private val plugin: EcoPlugin +) : CustomItemsIntegration, Listener { override fun registerProvider() { - Items.registerItemProvider(OraxenProvider()) + plugin.eventManager.registerListener(this) } override fun getPluginName(): String { return "Oraxen" } + @EventHandler + @Suppress("UNUSED_PARAMETER") + fun onItemRegister(event: OraxenItemsLoadedEvent) { + Items.registerItemProvider(OraxenProvider()) + } + private class OraxenProvider : ItemProvider("oraxen") { override fun provideForKey(key: String): TestableItem? { val item = OraxenItems.getItemById(key) ?: return null diff --git a/gradle.properties b/gradle.properties index 084b75e1..0b20d595 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -version = 6.54.1 +version = 6.55.1 plugin-name = eco kotlin.code.style = official \ No newline at end of file diff --git a/lib/KingdomsX-1.14.13-BETA.jar b/lib/KingdomsX-1.14.13-BETA.jar deleted file mode 100644 index 75ba3b54..00000000 Binary files a/lib/KingdomsX-1.14.13-BETA.jar and /dev/null differ diff --git a/lib/KingdomsX-1.16.5.jar b/lib/KingdomsX-1.16.5.jar new file mode 100644 index 00000000..de5625a5 Binary files /dev/null and b/lib/KingdomsX-1.16.5.jar differ