diff --git a/eco-api/src/main/java/com/willfp/eco/core/Eco.java b/eco-api/src/main/java/com/willfp/eco/core/Eco.java index c78f444f..2844cb6d 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/Eco.java +++ b/eco-api/src/main/java/com/willfp/eco/core/Eco.java @@ -26,7 +26,7 @@ import com.willfp.eco.core.gui.slot.SlotBuilder; import com.willfp.eco.core.gui.slot.functional.SlotProvider; import com.willfp.eco.core.items.TestableItem; import com.willfp.eco.core.packet.Packet; -import com.willfp.eco.core.placeholder.parsing.PlaceholderContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContext; import com.willfp.eco.core.proxy.ProxyFactory; import com.willfp.eco.core.scheduling.Scheduler; import net.kyori.adventure.platform.bukkit.BukkitAudiences; diff --git a/eco-api/src/main/java/com/willfp/eco/core/config/interfaces/Config.java b/eco-api/src/main/java/com/willfp/eco/core/config/interfaces/Config.java index e9ee7f64..33d7d439 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/config/interfaces/Config.java +++ b/eco-api/src/main/java/com/willfp/eco/core/config/interfaces/Config.java @@ -6,6 +6,7 @@ import com.willfp.eco.core.config.Configs; import com.willfp.eco.core.placeholder.AdditionalPlayer; import com.willfp.eco.core.placeholder.InjectablePlaceholder; import com.willfp.eco.core.placeholder.PlaceholderInjectable; +import com.willfp.eco.core.placeholder.context.PlaceholderContext; import com.willfp.eco.util.NumberUtils; import com.willfp.eco.util.StringUtils; import org.bukkit.configuration.ConfigurationSection; @@ -134,7 +135,7 @@ public interface Config extends Cloneable, PlaceholderInjectable { * @return The computed value, or 0 if not found or invalid. */ default int getIntFromExpression(@NotNull String path) { - return getIntFromExpression(path, null); + return getIntFromExpression(path, PlaceholderContext.of(this)); } /** @@ -163,6 +164,18 @@ public interface Config extends Cloneable, PlaceholderInjectable { return Double.valueOf(getDoubleFromExpression(path, player, additionalPlayers)).intValue(); } + /** + * Get a decimal value via a mathematical expression. + * + * @param path The key to fetch the value from. + * @param context The placeholder context. + * @return The computed value, or 0 if not found or invalid. + */ + default int getIntFromExpression(@NotNull String path, + @NotNull PlaceholderContext context) { + return Double.valueOf(getDoubleFromExpression(path, context)).intValue(); + } + /** * Get an integer from config. @@ -256,6 +269,19 @@ public interface Config extends Cloneable, PlaceholderInjectable { return getString(path, true, option); } + /** + * Get a formatted string from config. + * + * @param path The key to fetch the value from. + * @param context The placeholder context. + * @return The found value, or an empty string if not found. + */ + @NotNull + default String getFormattedString(@NotNull String path, + @NotNull PlaceholderContext context) { + return StringUtils.format(getString(path), context.withInjectableContext(this)); + } + /** * Get a string from config. *

@@ -288,7 +314,7 @@ public interface Config extends Cloneable, PlaceholderInjectable { * Get a formatted string from config. * * @param path The key to fetch the value from. - * @return The found value, or an empty string if not found. + * @return The found value, or null if not found. */ @Nullable default String getFormattedStringOrNull(@NotNull String path) { @@ -300,7 +326,7 @@ public interface Config extends Cloneable, PlaceholderInjectable { * * @param path The key to fetch the value from. * @param option The format option. - * @return The found value, or an empty string if not found. + * @return The found value, or null if not found. */ @Nullable default String getFormattedStringOrNull(@NotNull String path, @@ -308,6 +334,25 @@ public interface Config extends Cloneable, PlaceholderInjectable { return getStringOrNull(path, true, option); } + /** + * Get a formatted string from config. + * + * @param path The key to fetch the value from. + * @param context The placeholder context. + * @return The found value, or null if not found. + */ + @Nullable + default String getFormattedStringOrNull(@NotNull String path, + @NotNull PlaceholderContext context) { + String nullable = getStringOrNull(path); + + if (nullable == null) { + return null; + } + + return StringUtils.format(nullable, context.withInjectableContext(this)); + } + /** * Get a string from config. *

@@ -362,6 +407,24 @@ public interface Config extends Cloneable, PlaceholderInjectable { return getStrings(path, true, option); } + /** + * Get a list of strings from config. + *

+ * Formatted. + * + * @param path The key to fetch the value from. + * @param context The placeholder context. + * @return The found value, or a blank {@link java.util.ArrayList} if not found. + */ + @NotNull + default List getFormattedStrings(@NotNull String path, + @NotNull PlaceholderContext context) { + return StringUtils.formatList( + getStrings(path), + context.withInjectableContext(this) + ); + } + /** * Get a list of strings from config. *

@@ -418,6 +481,30 @@ public interface Config extends Cloneable, PlaceholderInjectable { return getStringsOrNull(path, true, option); } + /** + * Get a list of strings from config. + *

+ * Formatted. + * + * @param path The key to fetch the value from. + * @param context The placeholder context. + * @return The found value, or null if not found. + */ + @Nullable + default List getFormattedStringsOrNull(@NotNull String path, + @NotNull PlaceholderContext context) { + List nullable = getStringsOrNull(path); + + if (nullable == null) { + return null; + } + + return StringUtils.formatList( + nullable, + context.withInjectableContext(this) + ); + } + /** * Get a list of strings from config. *

@@ -463,7 +550,7 @@ public interface Config extends Cloneable, PlaceholderInjectable { * @return The computed value, or 0 if not found or invalid. */ default double getDoubleFromExpression(@NotNull String path) { - return getDoubleFromExpression(path, null); + return getDoubleFromExpression(path, PlaceholderContext.of(this)); } /** @@ -481,8 +568,8 @@ public interface Config extends Cloneable, PlaceholderInjectable { /** * Get a decimal value via a mathematical expression. * - * @param path The key to fetch the value from. - * @param player The player to evaluate placeholders with respect to. + * @param path The key to fetch the value from. + * @param player The player to evaluate placeholders with respect to. * @param additionalPlayers The additional players to evaluate placeholders with respect to. * @return The computed value, or 0 if not found or invalid. */ @@ -492,6 +579,18 @@ public interface Config extends Cloneable, PlaceholderInjectable { return NumberUtils.evaluateExpression(this.getString(path), player, this, additionalPlayers); } + /** + * Get a decimal value via a mathematical expression. + * + * @param path The key to fetch the value from. + * @param context The placeholder context. + * @return The computed value, or 0 if not found or invalid. + */ + default double getDoubleFromExpression(@NotNull String path, + @NotNull PlaceholderContext context) { + return NumberUtils.evaluateExpression(this.getString(path), context.withInjectableContext(this)); + } + /** * Get a decimal from config. * diff --git a/eco-api/src/main/java/com/willfp/eco/core/integrations/placeholder/PlaceholderManager.java b/eco-api/src/main/java/com/willfp/eco/core/integrations/placeholder/PlaceholderManager.java index 09a7bc51..148fdb07 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/integrations/placeholder/PlaceholderManager.java +++ b/eco-api/src/main/java/com/willfp/eco/core/integrations/placeholder/PlaceholderManager.java @@ -3,12 +3,13 @@ package com.willfp.eco.core.integrations.placeholder; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import com.willfp.eco.core.EcoPlugin; +import com.willfp.eco.core.map.DefaultMap; import com.willfp.eco.core.placeholder.AdditionalPlayer; import com.willfp.eco.core.placeholder.InjectablePlaceholder; import com.willfp.eco.core.placeholder.Placeholder; import com.willfp.eco.core.placeholder.PlaceholderInjectable; import com.willfp.eco.core.placeholder.RegistrablePlaceholder; -import com.willfp.eco.core.placeholder.parsing.PlaceholderContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContext; import com.willfp.eco.util.StringUtils; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; @@ -35,7 +36,7 @@ public final class PlaceholderManager { /** * All registered placeholders. */ - private static final Map> REGISTERED_PLACEHOLDERS = new HashMap<>(); + private static final DefaultMap> REGISTERED_PLACEHOLDERS = DefaultMap.createNestedMap(); /** * All registered arguments integrations. @@ -144,27 +145,18 @@ public final class PlaceholderManager { /** * Get the result of a placeholder given a plugin and arguments. * - * @param plugin The plugin for the placeholder. - * @param args The arguments. + * @param plugin The plugin for the placeholder. + * @param args The arguments. + * @param context The context. * @return The value of the arguments. */ @Nullable public static String getResult(@NotNull final EcoPlugin plugin, @NotNull final String args, @NotNull final PlaceholderContext context) { - // This is really janky, and it sucks, but it works so? - // Compensating for regex being slow so that's why we get it. Placeholder placeholder = PLACEHOLDER_LOOKUP_CACHE.get( new PlaceholderLookup(args, plugin), - (it) -> { - // I hate the streams API. - return REGISTERED_PLACEHOLDERS - .getOrDefault(plugin, new HashMap<>()) - .entrySet() - .stream().filter(entry -> entry.getKey().matcher(args).matches()) - .map(Map.Entry::getValue) - .findFirst(); - } + (it) -> findMatchingPlaceholder(plugin, args) ).orElse(null); if (placeholder == null) { @@ -174,6 +166,27 @@ public final class PlaceholderManager { return placeholder.getValue(args, context); } + /** + * Find matching placeholder. + * + * @param plugin The plugin. + * @param args The args. + * @return The placeholder. + */ + @NotNull + private static Optional findMatchingPlaceholder(@NotNull final EcoPlugin plugin, + @NotNull final String args) { + Map pluginPlaceholders = REGISTERED_PLACEHOLDERS.get(plugin); + + for (Map.Entry entry : pluginPlaceholders.entrySet()) { + if (entry.getKey().matcher(args).matches()) { + return Optional.of(entry.getValue()); + } + } + + return Optional.empty(); + } + /** * Translate all placeholders with respect to a player. * @@ -266,15 +279,15 @@ public final class PlaceholderManager { */ - for (InjectablePlaceholder injection : context.injectableContext().getPlaceholderInjections()) { + for (InjectablePlaceholder injection : context.getInjectableContext().getPlaceholderInjections()) { processed = injection.tryTranslateQuickly(processed, context); } // Prevent running 2 scans if there are no additional players. - if (!context.additionalPlayers().isEmpty()) { + if (!context.getAdditionalPlayers().isEmpty()) { List found = findPlaceholdersIn(text); - for (AdditionalPlayer additionalPlayer : context.additionalPlayers()) { + for (AdditionalPlayer additionalPlayer : context.getAdditionalPlayers()) { for (String placeholder : found) { String prefix = "%" + additionalPlayer.getIdentifier() + "_"; @@ -291,17 +304,14 @@ public final class PlaceholderManager { } } - // Only run jank code if there are no integrations. - if (REGISTERED_INTEGRATIONS.isEmpty()) { - processed = setWithoutIntegration(processed, context.player()); - } + processed = translateEcoPlaceholdersIn(processed, context); for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) { - processed = integration.translate(processed, context.player()); + processed = integration.translate(processed, context.getPlayer()); } // DON'T REMOVE THIS, IT'S NOT DUPLICATE CODE. - for (InjectablePlaceholder injection : context.injectableContext().getPlaceholderInjections()) { + for (InjectablePlaceholder injection : context.getInjectableContext().getPlaceholderInjections()) { processed = injection.tryTranslateQuickly(processed, context); } @@ -330,92 +340,39 @@ public final class PlaceholderManager { } /** - * Set placeholders without any integrations. - *

- * This is fallback if for some reason you don't have PAPI installed. - * It's a cut-down version of the actual PAPI code, and I don't - * really know how it works. - *

- * Original source - * here. + * Translate all eco placeholders in a given text. * - * @param text The text. - * @param player The player. + * @param text The text. + * @param context The context. * @return The text. */ - private static String setWithoutIntegration(@NotNull final String text, - @Nullable final Player player) { - char[] chars = text.toCharArray(); - StringBuilder builder = new StringBuilder(text.length()); - StringBuilder identifier = new StringBuilder(); - StringBuilder parameters = new StringBuilder(); + private static String translateEcoPlaceholdersIn(@NotNull final String text, + @NotNull final PlaceholderContext context) { + StringBuilder output = new StringBuilder(); + Matcher matcher = PATTERN.matcher(text); - for (int i = 0; i < chars.length; i++) { - char currentChar = chars[i]; - if (currentChar == '%' && i + 1 < chars.length) { - boolean identified = false; - boolean badPlaceholder = true; - boolean hadSpace = false; + while (matcher.find()) { + String placeholder = matcher.group(1); + String[] parts = placeholder.split("_", 2); - while (true) { - i++; - if (i >= chars.length) { - break; - } + if (parts.length == 2) { + EcoPlugin plugin = EcoPlugin.getPlugin(parts[0]); - char p = chars[i]; - if (p == ' ' && !identified) { - hadSpace = true; - break; - } + if (plugin != null) { + String result = getResult(plugin, parts[1], context); - if (p == '%') { - badPlaceholder = false; - break; - } - - if (p == '_' && !identified) { - identified = true; - } else if (identified) { - parameters.append(p); - } else { - identifier.append(p); + if (result != null) { + matcher.appendReplacement(output, Matcher.quoteReplacement(result)); + continue; } } - - String pluginName = identifier.toString().toLowerCase(); - EcoPlugin plugin = EcoPlugin.getPlugin(pluginName); - String placeholderIdentifier = parameters.toString(); - identifier.setLength(0); - parameters.setLength(0); - if (badPlaceholder) { - builder.append('%').append(pluginName); - if (identified) { - builder.append('_').append(placeholderIdentifier); - } - - if (hadSpace) { - builder.append(' '); - } - } else { - if (plugin == null) { - builder.append('%').append(pluginName); - - if (identified) { - builder.append('_'); - } - - builder.append(placeholderIdentifier).append('%'); - } else { - builder.append(getResult(player, placeholderIdentifier, plugin)); - } - } - } else { - builder.append(currentChar); } + + matcher.appendReplacement(output, Matcher.quoteReplacement(matcher.group(0))); } - return builder.toString(); + matcher.appendTail(output); + return output.toString(); } private record PlaceholderLookup(@NotNull String identifier, diff --git a/eco-api/src/main/java/com/willfp/eco/core/math/MathContext.java b/eco-api/src/main/java/com/willfp/eco/core/math/MathContext.java index c4da6670..0c8759b2 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/math/MathContext.java +++ b/eco-api/src/main/java/com/willfp/eco/core/math/MathContext.java @@ -3,7 +3,7 @@ package com.willfp.eco.core.math; import com.willfp.eco.core.integrations.placeholder.PlaceholderManager; import com.willfp.eco.core.placeholder.AdditionalPlayer; import com.willfp.eco.core.placeholder.PlaceholderInjectable; -import com.willfp.eco.core.placeholder.parsing.PlaceholderContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContext; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -12,6 +12,13 @@ import java.util.Collection; import java.util.Collections; import java.util.Objects; +/** + * Represents a context to parse math in. + * + * @deprecated Use {@link PlaceholderContext} instead. + */ +@SuppressWarnings("DeprecatedIsStillUsed") +@Deprecated(since = "6.56.0", forRemoval = true) public class MathContext { /** * Returns an empty math parseContext. @@ -61,8 +68,9 @@ public class MathContext { * Duplicate method because MathContext used to be a record. * * @return The injectable context. + * @deprecated Use {@link #getInjectableContext()} instead. */ - @NotNull + @Deprecated(since = "6.56.0", forRemoval = true) public PlaceholderInjectable injectableContext() { return injectableContext; } @@ -83,7 +91,9 @@ public class MathContext { * Duplicate method because MathContext used to be a record. * * @return The player. + * @deprecated Use {@link #getPlayer()} instead. */ + @Deprecated(since = "6.56.0", forRemoval = true) @Nullable public Player player() { return player; @@ -105,7 +115,9 @@ public class MathContext { * Duplicate method because MathContext used to be a record. * * @return The additional players. + * @deprecated Use {@link #getAdditionalPlayers()} instead. */ + @Deprecated(since = "6.56.0", forRemoval = true) @NotNull public Collection additionalPlayers() { return additionalPlayers; @@ -151,10 +163,9 @@ public class MathContext { return true; } - if (!(o instanceof MathContext)) { + if (!(o instanceof MathContext that)) { return false; } - MathContext that = (MathContext) o; return injectableContext.equals(that.injectableContext) && Objects.equals(player, that.player) && diff --git a/eco-api/src/main/java/com/willfp/eco/core/placeholder/DynamicPlaceholder.java b/eco-api/src/main/java/com/willfp/eco/core/placeholder/DynamicPlaceholder.java index 85e019c7..d218a8be 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/placeholder/DynamicPlaceholder.java +++ b/eco-api/src/main/java/com/willfp/eco/core/placeholder/DynamicPlaceholder.java @@ -1,7 +1,7 @@ package com.willfp.eco.core.placeholder; import com.willfp.eco.core.EcoPlugin; -import com.willfp.eco.core.placeholder.parsing.PlaceholderContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/eco-api/src/main/java/com/willfp/eco/core/placeholder/Placeholder.java b/eco-api/src/main/java/com/willfp/eco/core/placeholder/Placeholder.java index 71c5dde7..26a21b0f 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/placeholder/Placeholder.java +++ b/eco-api/src/main/java/com/willfp/eco/core/placeholder/Placeholder.java @@ -1,7 +1,7 @@ package com.willfp.eco.core.placeholder; import com.willfp.eco.core.EcoPlugin; -import com.willfp.eco.core.placeholder.parsing.PlaceholderContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlaceholderInjectable.java b/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlaceholderInjectable.java index 5f40deba..70533cb4 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlaceholderInjectable.java +++ b/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlaceholderInjectable.java @@ -29,7 +29,7 @@ public interface PlaceholderInjectable { /** * Inject placeholders. *

- * When implementing a PlaceholderInjectable object, override this method. + * If a placeholder already has the same pattern, it should be replaced. * * @param placeholders The placeholders. */ @@ -43,7 +43,7 @@ public interface PlaceholderInjectable { /** * Get injected placeholders. *

- * Override this method in implementations. + * This method should always return an immutable list. * * @return Injected placeholders. */ diff --git a/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlayerDynamicPlaceholder.java b/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlayerDynamicPlaceholder.java index 270c5e48..b6130f98 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlayerDynamicPlaceholder.java +++ b/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlayerDynamicPlaceholder.java @@ -1,7 +1,7 @@ package com.willfp.eco.core.placeholder; import com.willfp.eco.core.EcoPlugin; -import com.willfp.eco.core.placeholder.parsing.PlaceholderContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContext; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -47,7 +47,7 @@ public final class PlayerDynamicPlaceholder implements RegistrablePlaceholder { @Override public @Nullable String getValue(@NotNull final String args, @NotNull final PlaceholderContext context) { - Player player = context.player(); + Player player = context.getPlayer(); if (player == null) { return null; diff --git a/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlayerPlaceholder.java b/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlayerPlaceholder.java index 46c96c2a..bfa45068 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlayerPlaceholder.java +++ b/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlayerPlaceholder.java @@ -1,7 +1,7 @@ package com.willfp.eco.core.placeholder; import com.willfp.eco.core.EcoPlugin; -import com.willfp.eco.core.placeholder.parsing.PlaceholderContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContext; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -53,7 +53,7 @@ public final class PlayerPlaceholder implements RegistrablePlaceholder { @Override public @Nullable String getValue(@NotNull final String args, @NotNull final PlaceholderContext context) { - Player player = context.player(); + Player player = context.getPlayer(); if (player == null) { return null; diff --git a/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlayerStaticPlaceholder.java b/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlayerStaticPlaceholder.java index c5f103e3..1967b184 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlayerStaticPlaceholder.java +++ b/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlayerStaticPlaceholder.java @@ -1,6 +1,6 @@ package com.willfp.eco.core.placeholder; -import com.willfp.eco.core.placeholder.parsing.PlaceholderContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContext; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -44,7 +44,7 @@ public final class PlayerStaticPlaceholder implements InjectablePlaceholder { @Override public @Nullable String getValue(@NotNull final String args, @NotNull final PlaceholderContext context) { - Player player = context.player(); + Player player = context.getPlayer(); if (player == null) { return null; diff --git a/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlayerlessPlaceholder.java b/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlayerlessPlaceholder.java index 442237ef..131b2bdc 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlayerlessPlaceholder.java +++ b/eco-api/src/main/java/com/willfp/eco/core/placeholder/PlayerlessPlaceholder.java @@ -1,7 +1,7 @@ package com.willfp.eco.core.placeholder; import com.willfp.eco.core.EcoPlugin; -import com.willfp.eco.core.placeholder.parsing.PlaceholderContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/eco-api/src/main/java/com/willfp/eco/core/placeholder/RegistrablePlaceholder.java b/eco-api/src/main/java/com/willfp/eco/core/placeholder/RegistrablePlaceholder.java index 86eb2eae..6db0b631 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/placeholder/RegistrablePlaceholder.java +++ b/eco-api/src/main/java/com/willfp/eco/core/placeholder/RegistrablePlaceholder.java @@ -3,6 +3,9 @@ package com.willfp.eco.core.placeholder; import com.willfp.eco.core.integrations.placeholder.PlaceholderManager; import org.jetbrains.annotations.NotNull; +/** + * Represents a placeholder that can be registered. + */ public interface RegistrablePlaceholder extends Placeholder { /** * Register the arguments. diff --git a/eco-api/src/main/java/com/willfp/eco/core/placeholder/StaticPlaceholder.java b/eco-api/src/main/java/com/willfp/eco/core/placeholder/StaticPlaceholder.java index fff22690..c6ab6545 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/placeholder/StaticPlaceholder.java +++ b/eco-api/src/main/java/com/willfp/eco/core/placeholder/StaticPlaceholder.java @@ -1,6 +1,6 @@ package com.willfp.eco.core.placeholder; -import com.willfp.eco.core.placeholder.parsing.PlaceholderContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/eco-api/src/main/java/com/willfp/eco/core/placeholder/context/MergedInjectableContext.java b/eco-api/src/main/java/com/willfp/eco/core/placeholder/context/MergedInjectableContext.java new file mode 100644 index 00000000..d3a0a23e --- /dev/null +++ b/eco-api/src/main/java/com/willfp/eco/core/placeholder/context/MergedInjectableContext.java @@ -0,0 +1,66 @@ +package com.willfp.eco.core.placeholder.context; + +import com.willfp.eco.core.placeholder.InjectablePlaceholder; +import com.willfp.eco.core.placeholder.PlaceholderInjectable; +import org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * A merged injectable context. + */ +public class MergedInjectableContext implements PlaceholderInjectable { + /** + * The base context. + */ + private final PlaceholderInjectable baseContext; + + /** + * The additional context. + */ + private final PlaceholderInjectable additionalContext; + + /** + * Extra injections. + */ + private final Set extraInjections = new HashSet<>(); + + /** + * Create a new merged injectable context. + * + * @param baseContext The base context. + * @param additionalContext The additional context. + */ + public MergedInjectableContext(@NotNull final PlaceholderInjectable baseContext, + @NotNull final PlaceholderInjectable additionalContext) { + this.baseContext = baseContext; + this.additionalContext = additionalContext; + } + + @Override + public void addInjectablePlaceholder(@NotNull final Iterable placeholders) { + for (InjectablePlaceholder placeholder : placeholders) { + extraInjections.add(placeholder); + } + } + + @Override + public void clearInjectedPlaceholders() { + baseContext.clearInjectedPlaceholders(); + additionalContext.clearInjectedPlaceholders(); + extraInjections.clear(); + } + + @Override + public @NotNull List getPlaceholderInjections() { + List base = baseContext.getPlaceholderInjections(); + List additional = additionalContext.getPlaceholderInjections(); + + base.addAll(additional); + base.addAll(extraInjections); + + return base; + } +} diff --git a/eco-api/src/main/java/com/willfp/eco/core/placeholder/context/PlaceholderContext.java b/eco-api/src/main/java/com/willfp/eco/core/placeholder/context/PlaceholderContext.java new file mode 100644 index 00000000..723bc0af --- /dev/null +++ b/eco-api/src/main/java/com/willfp/eco/core/placeholder/context/PlaceholderContext.java @@ -0,0 +1,200 @@ +package com.willfp.eco.core.placeholder.context; + +import com.willfp.eco.core.integrations.placeholder.PlaceholderManager; +import com.willfp.eco.core.placeholder.AdditionalPlayer; +import com.willfp.eco.core.placeholder.PlaceholderInjectable; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.Collections; +import java.util.Objects; + +/** + * Represents a context to translate placeholders in. + */ +public class PlaceholderContext { + /** + * An empty context. + */ + public static final PlaceholderContext EMPTY = new PlaceholderContext( + null, + null, + PlaceholderManager.EMPTY_INJECTABLE, + Collections.emptyList() + ); + + /** + * The player. + */ + @Nullable + private final Player player; + + /** + * The ItemStack. + */ + @Nullable + private final ItemStack itemStack; + + /** + * The PlaceholderInjectable context. + */ + @NotNull + private final PlaceholderInjectable injectableContext; + + /** + * The additional players. + */ + @NotNull + private final Collection additionalPlayers; + + /** + * Constructs a new PlaceholderContext with the given parameters. + * + * @param player The player. + * @param itemStack The ItemStack. + * @param injectableContext The PlaceholderInjectable parseContext. + * @param additionalPlayers The additional players. + */ + public PlaceholderContext(@Nullable final Player player, + @Nullable final ItemStack itemStack, + @NotNull final PlaceholderInjectable injectableContext, + @NotNull final Collection additionalPlayers) { + this.player = player; + this.itemStack = itemStack; + this.injectableContext = injectableContext; + this.additionalPlayers = additionalPlayers; + } + + /** + * Get the player. + * + * @return The player. + */ + @Nullable + public Player getPlayer() { + return player; + } + + /** + * Get the ItemStack. + * + * @return The ItemStack. + */ + @Nullable + public ItemStack getItemStack() { + return itemStack; + } + + /** + * Get the PlaceholderInjectable context. + * + * @return The PlaceholderInjectable context. + */ + @NotNull + public PlaceholderInjectable getInjectableContext() { + return injectableContext; + } + + /** + * Get the additional players. + * + * @return The additional players. + */ + @NotNull + public Collection getAdditionalPlayers() { + return additionalPlayers; + } + + /** + * Convert to a {@link com.willfp.eco.core.math.MathContext}. + * + * @return The math context. + * @deprecated MathContext is deprecated, use {@link PlaceholderContext} instead. + */ + @Deprecated(since = "6.56.0", forRemoval = true) + @SuppressWarnings({"removal", "DeprecatedIsStillUsed"}) + public com.willfp.eco.core.math.MathContext toMathContext() { + return new com.willfp.eco.core.math.MathContext(this.getInjectableContext(), this.getPlayer(), this.getAdditionalPlayers()); + } + + /** + * Copy with a player. + * + * @param player The player. + * @return The new context. + */ + public PlaceholderContext copyWithPlayer(@Nullable final Player player) { + return new PlaceholderContext( + player, + this.getItemStack(), + this.getInjectableContext(), + this.getAdditionalPlayers() + ); + } + + /** + * Copy with an extra injectable context. + * + * @param injectableContext The injectable context to add. + * @return The new context. + */ + public PlaceholderContext withInjectableContext(@NotNull final PlaceholderInjectable injectableContext) { + return new PlaceholderContext( + this.getPlayer(), + this.getItemStack(), + new MergedInjectableContext(this.getInjectableContext(), injectableContext), + this.getAdditionalPlayers() + ); + } + + @Override + public String toString() { + return "PlaceholderContext{" + + "player=" + player + + ", itemStack=" + itemStack + + ", injectableContext=" + injectableContext + + ", additionalPlayers=" + additionalPlayers + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof PlaceholderContext that)) { + return false; + } + + return Objects.equals( + getPlayer(), that.getPlayer()) + && Objects.equals(getItemStack(), that.getItemStack()) + && getInjectableContext().equals(that.getInjectableContext()) + && getAdditionalPlayers().equals(that.getAdditionalPlayers() + ); + } + + @Override + public int hashCode() { + return Objects.hash(getPlayer(), getItemStack(), getInjectableContext(), getAdditionalPlayers()); + } + + /** + * Create PlaceholderContext of a PlaceholderInjectable parseContext. + * + * @param injectableContext The PlaceholderInjectable parseContext. + * @return The context. + */ + public static PlaceholderContext of(@NotNull final PlaceholderInjectable injectableContext) { + return new PlaceholderContext( + null, + null, + injectableContext, + Collections.emptyList() + ); + } +} diff --git a/eco-api/src/main/java/com/willfp/eco/core/placeholder/context/PlaceholderContextSupplier.java b/eco-api/src/main/java/com/willfp/eco/core/placeholder/context/PlaceholderContextSupplier.java new file mode 100644 index 00000000..b0188689 --- /dev/null +++ b/eco-api/src/main/java/com/willfp/eco/core/placeholder/context/PlaceholderContextSupplier.java @@ -0,0 +1,19 @@ +package com.willfp.eco.core.placeholder.context; + +import org.jetbrains.annotations.NotNull; + +/** + * A supplier that takes a {@link PlaceholderContext} and returns a value. + * + * @param The type of value to return. + */ +public interface PlaceholderContextSupplier { + /** + * Get the value. + * + * @param context The context. + * @return The value. + */ + @NotNull + T get(@NotNull PlaceholderContext context); +} diff --git a/eco-api/src/main/java/com/willfp/eco/core/placeholder/parsing/PlaceholderContext.java b/eco-api/src/main/java/com/willfp/eco/core/placeholder/parsing/PlaceholderContext.java deleted file mode 100644 index b6c68568..00000000 --- a/eco-api/src/main/java/com/willfp/eco/core/placeholder/parsing/PlaceholderContext.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.willfp.eco.core.placeholder.parsing; - -import com.willfp.eco.core.integrations.placeholder.PlaceholderManager; -import com.willfp.eco.core.math.MathContext; -import com.willfp.eco.core.placeholder.AdditionalPlayer; -import com.willfp.eco.core.placeholder.PlaceholderInjectable; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Collection; -import java.util.Collections; - -/** - * Represents a context to translate placeholders in. - */ -public class PlaceholderContext extends MathContext { - /** - * An empty context. - */ - public static final PlaceholderContext EMPTY = new PlaceholderContext( - null, - null, - PlaceholderManager.EMPTY_INJECTABLE, - Collections.emptyList() - ); - - /** - * The ItemStack. - */ - @Nullable - private final ItemStack itemStack; - - /** - * Constructs a new PlaceholderContext with the given parameters. - * - * @param player The player. - * @param itemStack The ItemStack. - * @param injectableContext The PlaceholderInjectable parseContext. - * @param additionalPlayers The additional players. - */ - public PlaceholderContext(@Nullable final Player player, - @Nullable final ItemStack itemStack, - @NotNull final PlaceholderInjectable injectableContext, - @NotNull final Collection additionalPlayers) { - super(injectableContext, player, additionalPlayers); - - this.itemStack = itemStack; - } - - /** - * Get the ItemStack. - * - * @return The ItemStack. - */ - @Nullable - public ItemStack getItemStack() { - return itemStack; - } - - /** - * Create MathContext of a PlaceholderInjectable parseContext. - * - * @param injectableContext The PlaceholderInjectable parseContext. - * @return The MathContext. - */ - public static PlaceholderContext of(@NotNull final PlaceholderInjectable injectableContext) { - return new PlaceholderContext( - null, - null, - injectableContext, - Collections.emptyList() - ); - } - - /** - * Copy with a player. - * - * @param player The player. - * @return The new MathContext. - */ - public PlaceholderContext copyWithPlayer(@Nullable final Player player) { - return new PlaceholderContext( - player, - this.getItemStack(), - this.getInjectableContext(), - this.getAdditionalPlayers() - ); - } -} diff --git a/eco-api/src/main/java/com/willfp/eco/core/price/ConfiguredPrice.java b/eco-api/src/main/java/com/willfp/eco/core/price/ConfiguredPrice.java index d455de8d..02c55dbd 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/price/ConfiguredPrice.java +++ b/eco-api/src/main/java/com/willfp/eco/core/price/ConfiguredPrice.java @@ -1,7 +1,7 @@ package com.willfp.eco.core.price; import com.willfp.eco.core.config.interfaces.Config; -import com.willfp.eco.core.math.MathContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContext; import com.willfp.eco.core.price.impl.PriceFree; import com.willfp.eco.core.serialization.ConfigDeserializer; import com.willfp.eco.util.NumberUtils; @@ -168,7 +168,7 @@ public final class ConfiguredPrice implements Price { Price price = Prices.create( config.getString("value"), config.getString("type"), - MathContext.of(config) + PlaceholderContext.of(config) ); return new ConfiguredPrice(price, formatString); diff --git a/eco-api/src/main/java/com/willfp/eco/core/price/PriceFactory.java b/eco-api/src/main/java/com/willfp/eco/core/price/PriceFactory.java index f87de073..cb7f18fe 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/price/PriceFactory.java +++ b/eco-api/src/main/java/com/willfp/eco/core/price/PriceFactory.java @@ -1,6 +1,7 @@ package com.willfp.eco.core.price; -import com.willfp.eco.core.math.MathContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContextSupplier; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; @@ -10,7 +11,8 @@ import java.util.function.Function; /** * Create prices. *

- * You must override one of the create methods. + * Override create(PlaceholderContext, PlaceholderContextSupplier), other methods + * are for backwards compatibility. */ public interface PriceFactory { /** @@ -27,20 +29,38 @@ public interface PriceFactory { * * @param value The value. * @return The price. + * @deprecated Use {@link #create(PlaceholderContext, PlaceholderContextSupplier)} instead. */ + @Deprecated(since = "6.56.0", forRemoval = true) default @NotNull Price create(final double value) { - return create(MathContext.EMPTY, (ctx) -> value); + return create(PlaceholderContext.EMPTY, (ctx) -> value); } /** * Create the price. * * @param baseContext The base MathContext. - * @param function The function to use. Should use {@link MathContext#copyWithPlayer(MathContext, Player)} on calls. + * @param function The function to use. Should use {@link com.willfp.eco.core.math.MathContext#copyWithPlayer(com.willfp.eco.core.math.MathContext, Player)} on calls. + * @return The price. + * @deprecated Use {@link #create(PlaceholderContext, PlaceholderContextSupplier)} instead. + */ + @Deprecated(since = "6.56.0", forRemoval = true) + @SuppressWarnings("removal") + default @NotNull Price create(@NotNull final com.willfp.eco.core.math.MathContext baseContext, + @NotNull final Function function) { + return create(baseContext.toPlaceholderContext(), (PlaceholderContext ctx) -> function.apply(ctx.toMathContext())); + } + + /** + * Create the price. + * + * @param baseContext The base PlaceholderContext. + * @param function The function to use. Should use {@link PlaceholderContext#copyWithPlayer(Player)} on calls. * @return The price. */ - default @NotNull Price create(@NotNull final MathContext baseContext, - @NotNull final Function function) { - return create(function.apply(baseContext)); + @SuppressWarnings("removal") + default @NotNull Price create(@NotNull final PlaceholderContext baseContext, + @NotNull final PlaceholderContextSupplier function) { + return create(baseContext.toMathContext(), (com.willfp.eco.core.math.MathContext ctx) -> function.get(ctx.toPlaceholderContext())); } } diff --git a/eco-api/src/main/java/com/willfp/eco/core/price/Prices.java b/eco-api/src/main/java/com/willfp/eco/core/price/Prices.java index f2363c0c..ea940c88 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/price/Prices.java +++ b/eco-api/src/main/java/com/willfp/eco/core/price/Prices.java @@ -2,7 +2,8 @@ package com.willfp.eco.core.price; import com.willfp.eco.core.items.Items; import com.willfp.eco.core.items.TestableItem; -import com.willfp.eco.core.math.MathContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContextSupplier; import com.willfp.eco.core.price.impl.PriceEconomy; import com.willfp.eco.core.price.impl.PriceFree; import com.willfp.eco.core.price.impl.PriceItem; @@ -13,7 +14,6 @@ import org.jetbrains.annotations.Nullable; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Function; /** * Class to manage prices. @@ -48,7 +48,28 @@ public final class Prices { @NotNull public static Price create(@NotNull final String expression, @Nullable final String priceName) { - return create(expression, priceName, MathContext.EMPTY); + return create(expression, priceName, PlaceholderContext.EMPTY); + } + + /** + * Create price from an expression (representing the value), + * and a price name. Uses a context to parse the expression. + *

+ * Supports items as price names. + * + * @param expression The expression for the value. + * @param priceName The price name. + * @param context The math context to parse the expression. + * @return The price, or free if invalid. + * @deprecated Use {@link #create(String, String, PlaceholderContext)} instead. + */ + @NotNull + @Deprecated(since = "6.56.0", forRemoval = true) + @SuppressWarnings("removal") + public static Price create(@NotNull final String expression, + @Nullable final String priceName, + @NotNull final com.willfp.eco.core.math.MathContext context) { + return create(expression, priceName, context.toPlaceholderContext()); } /** @@ -65,8 +86,8 @@ public final class Prices { @NotNull public static Price create(@NotNull final String expression, @Nullable final String priceName, - @NotNull final MathContext context) { - Function function = (ctx) -> NumberUtils.evaluateExpression( + @NotNull final PlaceholderContext context) { + PlaceholderContextSupplier function = (ctx) -> NumberUtils.evaluateExpression( expression, ctx ); diff --git a/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceEconomy.java b/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceEconomy.java index 36a6dcef..c024b043 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceEconomy.java +++ b/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceEconomy.java @@ -1,7 +1,8 @@ package com.willfp.eco.core.price.impl; import com.willfp.eco.core.integrations.economy.EconomyManager; -import com.willfp.eco.core.math.MathContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContextSupplier; import com.willfp.eco.core.price.Price; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; @@ -18,12 +19,12 @@ public final class PriceEconomy implements Price { /** * The value of the price. */ - private final Function function; + private final PlaceholderContextSupplier function; /** - * The base math context. + * The base placeholder context. */ - private final MathContext baseContext; + private final PlaceholderContext baseContext; /** * The multipliers. @@ -36,7 +37,21 @@ public final class PriceEconomy implements Price { * @param value The value. */ public PriceEconomy(final double value) { - this(MathContext.EMPTY, ctx -> value); + this(PlaceholderContext.EMPTY, (PlaceholderContext ctx) -> value); + } + + /** + * Create a new economy-based price. + * + * @param baseContext The base context. + * @param function The function. + * @deprecated Use {@link #PriceEconomy(PlaceholderContext, PlaceholderContextSupplier)} instead. + */ + @Deprecated(since = "6.56.0", forRemoval = true) + @SuppressWarnings("removal") + public PriceEconomy(@NotNull final com.willfp.eco.core.math.MathContext baseContext, + @NotNull final Function function) { + this(baseContext.toPlaceholderContext(), (PlaceholderContext ctx) -> function.apply(ctx.toMathContext())); } /** @@ -45,8 +60,8 @@ public final class PriceEconomy implements Price { * @param baseContext The base context. * @param function The function. */ - public PriceEconomy(@NotNull final MathContext baseContext, - @NotNull final Function function) { + public PriceEconomy(@NotNull final PlaceholderContext baseContext, + @NotNull final PlaceholderContextSupplier function) { this.baseContext = baseContext; this.function = function; } @@ -72,7 +87,7 @@ public final class PriceEconomy implements Price { @Override public double getValue(@NotNull final Player player, final double multiplier) { - return this.function.apply(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player) * multiplier; + return this.function.get(baseContext.copyWithPlayer(player)) * getMultiplier(player) * multiplier; } @Override diff --git a/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceItem.java b/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceItem.java index 894b827f..a8851628 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceItem.java +++ b/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceItem.java @@ -3,7 +3,8 @@ package com.willfp.eco.core.price.impl; import com.willfp.eco.core.drops.DropQueue; import com.willfp.eco.core.items.HashedItem; import com.willfp.eco.core.items.TestableItem; -import com.willfp.eco.core.math.MathContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContextSupplier; import com.willfp.eco.core.price.Price; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -20,14 +21,14 @@ import java.util.function.Function; */ public final class PriceItem implements Price { /** - * The base MathContext. + * The base PlaceholderContext. */ - private final MathContext baseContext; + private final PlaceholderContext baseContext; /** * The amount of items. */ - private final Function function; + private final PlaceholderContextSupplier function; /** * The item. @@ -47,7 +48,23 @@ public final class PriceItem implements Price { */ public PriceItem(final int amount, @NotNull final TestableItem item) { - this(MathContext.EMPTY, ctx -> (double) amount, item); + this(PlaceholderContext.EMPTY, (PlaceholderContext ctx) -> (double) amount, item); + } + + /** + * Create a new item-based price. + * + * @param baseContext The base MathContext. + * @param function The function to get the amount of items to remove. + * @param item The item. + * @deprecated Use {@link #PriceItem(PlaceholderContext, PlaceholderContextSupplier, TestableItem)} instead. + */ + @Deprecated(since = "6.56.0", forRemoval = true) + @SuppressWarnings("removal") + public PriceItem(@NotNull final com.willfp.eco.core.math.MathContext baseContext, + @NotNull final Function function, + @NotNull final TestableItem item) { + this(baseContext.toPlaceholderContext(), (PlaceholderContext ctx) -> function.apply(ctx.toMathContext()), item); } /** @@ -57,8 +74,8 @@ public final class PriceItem implements Price { * @param function The function to get the amount of items to remove. * @param item The item. */ - public PriceItem(@NotNull final MathContext baseContext, - @NotNull final Function function, + public PriceItem(@NotNull final PlaceholderContext baseContext, + @NotNull final PlaceholderContextSupplier function, @NotNull final TestableItem item) { this.baseContext = baseContext; this.function = function; @@ -137,7 +154,7 @@ public final class PriceItem implements Price { public double getValue(@NotNull final Player player, final double multiplier) { return Math.toIntExact(Math.round( - this.function.apply(MathContext.copyWithPlayer(baseContext, player)) + this.function.get(baseContext.copyWithPlayer(player)) * getMultiplier(player) * multiplier )); } diff --git a/eco-api/src/main/java/com/willfp/eco/util/NumberUtils.java b/eco-api/src/main/java/com/willfp/eco/util/NumberUtils.java index 5777a436..c2b1c7bf 100644 --- a/eco-api/src/main/java/com/willfp/eco/util/NumberUtils.java +++ b/eco-api/src/main/java/com/willfp/eco/util/NumberUtils.java @@ -2,10 +2,9 @@ package com.willfp.eco.util; import com.willfp.eco.core.Eco; import com.willfp.eco.core.integrations.placeholder.PlaceholderManager; -import com.willfp.eco.core.math.MathContext; import com.willfp.eco.core.placeholder.AdditionalPlayer; import com.willfp.eco.core.placeholder.PlaceholderInjectable; -import com.willfp.eco.core.placeholder.parsing.PlaceholderContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContext; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -267,9 +266,12 @@ public final class NumberUtils { * @param expression The expression. * @param context The context. * @return The value of the expression, or zero if invalid. + * @deprecated Use {@link #evaluateExpression(String, PlaceholderContext)} instead. */ + @Deprecated(since = "6.56.0", forRemoval = true) + @SuppressWarnings("removal") public static double evaluateExpression(@NotNull final String expression, - @NotNull final MathContext context) { + @NotNull final com.willfp.eco.core.math.MathContext context) { return evaluateExpression(expression, context.toPlaceholderContext()); } diff --git a/eco-api/src/main/java/com/willfp/eco/util/StringUtils.java b/eco-api/src/main/java/com/willfp/eco/util/StringUtils.java index 15cccf7f..e802c10c 100644 --- a/eco-api/src/main/java/com/willfp/eco/util/StringUtils.java +++ b/eco-api/src/main/java/com/willfp/eco/util/StringUtils.java @@ -8,7 +8,7 @@ import com.google.common.collect.ImmutableMap; import com.google.gson.JsonSyntaxException; import com.willfp.eco.core.Eco; import com.willfp.eco.core.integrations.placeholder.PlaceholderManager; -import com.willfp.eco.core.placeholder.parsing.PlaceholderContext; +import com.willfp.eco.core.placeholder.context.PlaceholderContext; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.TextDecoration; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; diff --git a/eco-api/src/main/kotlin/com/willfp/eco/util/StringUtils.kt b/eco-api/src/main/kotlin/com/willfp/eco/util/StringUtils.kt index c2cdf0e9..b9bf4793 100644 --- a/eco-api/src/main/kotlin/com/willfp/eco/util/StringUtils.kt +++ b/eco-api/src/main/kotlin/com/willfp/eco/util/StringUtils.kt @@ -2,7 +2,7 @@ package com.willfp.eco.util -import com.willfp.eco.core.placeholder.parsing.PlaceholderContext +import com.willfp.eco.core.placeholder.context.PlaceholderContext import net.kyori.adventure.text.Component import org.bukkit.entity.Player diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfig.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfig.kt index 5f87b02b..15edc419 100644 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfig.kt +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfig.kt @@ -3,10 +3,11 @@ package com.willfp.eco.internal.config import com.willfp.eco.core.config.ConfigType import com.willfp.eco.core.config.interfaces.Config import com.willfp.eco.core.placeholder.InjectablePlaceholder -import com.willfp.eco.core.placeholder.StaticPlaceholder +import com.willfp.eco.core.placeholder.context.PlaceholderContext import com.willfp.eco.util.StringUtils import org.bukkit.configuration.file.YamlConfiguration import java.util.concurrent.ConcurrentHashMap +import java.util.regex.Pattern @Suppress("UNCHECKED_CAST") open class EcoConfig( @@ -15,7 +16,7 @@ open class EcoConfig( private val values = ConcurrentHashMap() @Transient - var injections = ConcurrentHashMap() + var injections = ConcurrentHashMap() fun init(values: Map) { this.values.clear() @@ -141,9 +142,7 @@ open class EcoConfig( var string = get(path)?.toString() ?: return null if (format && option == StringUtils.FormatOption.WITH_PLACEHOLDERS) { for (injection in placeholderInjections) { - if (injection is StaticPlaceholder) { - string = string.replace("%${injection.identifier}%", injection.value) - } + string = injection.tryTranslateQuickly(string, PlaceholderContext.EMPTY) } } return if (format) StringUtils.format(string, option) else string @@ -161,9 +160,7 @@ open class EcoConfig( strings.replaceAll { var string = it for (injection in placeholderInjections) { - if (injection is StaticPlaceholder) { - string = string.replace("%${injection.identifier}%", injection.value) - } + string = injection.tryTranslateQuickly(string, PlaceholderContext.EMPTY) } string } @@ -181,7 +178,7 @@ open class EcoConfig( override fun addInjectablePlaceholder(placeholders: Iterable) { for (placeholder in placeholders) { - injections[placeholder.identifier] = placeholder + injections[placeholder.pattern] = placeholder } } diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfigSection.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfigSection.kt index fe378231..1cb7bbb9 100644 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfigSection.kt +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfigSection.kt @@ -3,11 +3,12 @@ package com.willfp.eco.internal.config import com.willfp.eco.core.config.ConfigType import com.willfp.eco.core.placeholder.InjectablePlaceholder import java.util.concurrent.ConcurrentHashMap +import java.util.regex.Pattern class EcoConfigSection( type: ConfigType, values: Map = emptyMap(), - injections: MutableMap = mutableMapOf() + injections: MutableMap = mutableMapOf() ) : EcoConfig(type) { init { this.init(values) diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryEconomy.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryEconomy.kt index a97fddb6..e7e11afc 100644 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryEconomy.kt +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryEconomy.kt @@ -1,10 +1,10 @@ package com.willfp.eco.internal.price -import com.willfp.eco.core.math.MathContext +import com.willfp.eco.core.placeholder.context.PlaceholderContext +import com.willfp.eco.core.placeholder.context.PlaceholderContextSupplier import com.willfp.eco.core.price.Price import com.willfp.eco.core.price.PriceFactory import com.willfp.eco.core.price.impl.PriceEconomy -import java.util.function.Function object PriceFactoryEconomy : PriceFactory { override fun getNames() = listOf( @@ -12,7 +12,7 @@ object PriceFactoryEconomy : PriceFactory { "$" ) - override fun create(baseContext: MathContext, function: Function): Price { + override fun create(baseContext: PlaceholderContext, function: PlaceholderContextSupplier): Price { return PriceEconomy(baseContext, function) } } diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryXP.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryXP.kt index a18e5cf0..8e122944 100644 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryXP.kt +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryXP.kt @@ -1,11 +1,11 @@ package com.willfp.eco.internal.price -import com.willfp.eco.core.math.MathContext +import com.willfp.eco.core.placeholder.context.PlaceholderContext +import com.willfp.eco.core.placeholder.context.PlaceholderContextSupplier import com.willfp.eco.core.price.Price import com.willfp.eco.core.price.PriceFactory import org.bukkit.entity.Player import java.util.UUID -import java.util.function.Function import kotlin.math.roundToInt object PriceFactoryXP : PriceFactory { @@ -15,13 +15,13 @@ object PriceFactoryXP : PriceFactory { "experience" ) - override fun create(baseContext: MathContext, function: Function): Price { - return PriceXP(baseContext) { function.apply(it).roundToInt() } + override fun create(baseContext: PlaceholderContext, function: PlaceholderContextSupplier): Price { + return PriceXP(baseContext) { function.get(it).roundToInt() } } private class PriceXP( - private val baseContext: MathContext, - private val xp: (MathContext) -> Int + private val baseContext: PlaceholderContext, + private val xp: (PlaceholderContext) -> Int ) : Price { private val multipliers = mutableMapOf() @@ -37,7 +37,7 @@ object PriceFactoryXP : PriceFactory { } override fun getValue(player: Player, multiplier: Double): Double { - return xp(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player) * multiplier + return xp(baseContext.copyWithPlayer(player)) * getMultiplier(player) * multiplier } override fun getMultiplier(player: Player): Double { diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryXPLevels.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryXPLevels.kt index 9a53d2e4..b71147e7 100644 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryXPLevels.kt +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryXPLevels.kt @@ -1,11 +1,11 @@ package com.willfp.eco.internal.price -import com.willfp.eco.core.math.MathContext +import com.willfp.eco.core.placeholder.context.PlaceholderContext +import com.willfp.eco.core.placeholder.context.PlaceholderContextSupplier import com.willfp.eco.core.price.Price import com.willfp.eco.core.price.PriceFactory import org.bukkit.entity.Player import java.util.UUID -import java.util.function.Function import kotlin.math.roundToInt object PriceFactoryXPLevels : PriceFactory { @@ -16,13 +16,13 @@ object PriceFactoryXPLevels : PriceFactory { "explevels", ) - override fun create(baseContext: MathContext, function: Function): Price { - return PriceXPLevel(baseContext) { function.apply(it).roundToInt() } + override fun create(baseContext: PlaceholderContext, function: PlaceholderContextSupplier): Price { + return PriceXPLevel(baseContext) { function.get(it).roundToInt() } } private class PriceXPLevel( - private val baseContext: MathContext, - private val level: (MathContext) -> Int + private val baseContext: PlaceholderContext, + private val level: (PlaceholderContext) -> Int ) : Price { private val multipliers = mutableMapOf() @@ -37,7 +37,7 @@ object PriceFactoryXPLevels : PriceFactory { } override fun getValue(player: Player, multiplier: Double): Double { - return level(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player) * multiplier + return level(baseContext.copyWithPlayer(player)) * getMultiplier(player) * multiplier } override fun getMultiplier(player: Player): Double { diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/EcoImpl.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/EcoImpl.kt index 6abd7a18..9f971e6d 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/EcoImpl.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/EcoImpl.kt @@ -14,7 +14,7 @@ import com.willfp.eco.core.gui.menu.MenuType import com.willfp.eco.core.gui.slot.functional.SlotProvider import com.willfp.eco.core.items.Items import com.willfp.eco.core.packet.Packet -import com.willfp.eco.core.placeholder.parsing.PlaceholderContext +import com.willfp.eco.core.placeholder.context.PlaceholderContext import com.willfp.eco.internal.EcoPropsParser import com.willfp.eco.internal.command.EcoPluginCommand import com.willfp.eco.internal.command.EcoSubcommand diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/integrations/price/PriceFactoryUltraEconomy.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/integrations/price/PriceFactoryUltraEconomy.kt index 89f3641e..9b350097 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/integrations/price/PriceFactoryUltraEconomy.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/integrations/price/PriceFactoryUltraEconomy.kt @@ -1,6 +1,7 @@ package com.willfp.eco.internal.spigot.integrations.price -import com.willfp.eco.core.math.MathContext +import com.willfp.eco.core.placeholder.context.PlaceholderContext +import com.willfp.eco.core.placeholder.context.PlaceholderContextSupplier import com.willfp.eco.core.price.Price import com.willfp.eco.core.price.PriceFactory import com.willfp.eco.util.toSingletonList @@ -9,21 +10,20 @@ import me.TechsCode.UltraEconomy.objects.Account import me.TechsCode.UltraEconomy.objects.Currency import org.bukkit.entity.Player import java.util.UUID -import java.util.function.Function class PriceFactoryUltraEconomy(private val currency: Currency) : PriceFactory { override fun getNames(): List { return currency.name.lowercase().toSingletonList() } - override fun create(baseContext: MathContext, function: Function): Price { - return PriceUltraEconomy(currency, baseContext) { function.apply(it) } + override fun create(baseContext: PlaceholderContext, function: PlaceholderContextSupplier): Price { + return PriceUltraEconomy(currency, baseContext) { function.get(it) } } private class PriceUltraEconomy( private val currency: Currency, - private val baseContext: MathContext, - private val function: (MathContext) -> Double + private val baseContext: PlaceholderContext, + private val function: (PlaceholderContext) -> Double ) : Price { private val multipliers = mutableMapOf() private val api = UltraEconomy.getAPI() @@ -44,7 +44,7 @@ class PriceFactoryUltraEconomy(private val currency: Currency) : PriceFactory { } override fun getValue(player: Player, multiplier: Double): Double { - return function(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player) * multiplier + return function(baseContext.copyWithPlayer(player)) * getMultiplier(player) * multiplier } override fun getMultiplier(player: Player): Double { diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/math/CrunchHandler.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/math/CrunchHandler.kt index f5065145..09266c5e 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/math/CrunchHandler.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/math/CrunchHandler.kt @@ -3,7 +3,7 @@ package com.willfp.eco.internal.spigot.math import com.github.benmanes.caffeine.cache.Cache import com.github.benmanes.caffeine.cache.Caffeine import com.willfp.eco.core.integrations.placeholder.PlaceholderManager -import com.willfp.eco.core.placeholder.parsing.PlaceholderContext +import com.willfp.eco.core.placeholder.context.PlaceholderContext import redempt.crunch.CompiledExpression import redempt.crunch.Crunch import redempt.crunch.data.FastNumberParsing