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