Added support for evaluating mathematical expressions via Crunch
This commit is contained in:
@@ -64,6 +64,9 @@ allprojects {
|
||||
|
||||
// MythicMobs
|
||||
maven("https://mvn.lumine.io/repository/maven-public/")
|
||||
|
||||
// Crunch
|
||||
maven("https://redempt.dev")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -97,6 +100,7 @@ allprojects {
|
||||
shadowJar {
|
||||
relocate("org.bstats", "com.willfp.eco.shaded.bstats")
|
||||
relocate("net.kyori.adventure.text.minimessage", "com.willfp.eco.shaded.minimessage")
|
||||
relocate("redempt.crunch", "com.willfp.eco.shaded.crunch")
|
||||
}
|
||||
|
||||
compileJava {
|
||||
|
||||
@@ -5,6 +5,9 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wrapper class for placeholder integrations.
|
||||
*/
|
||||
@@ -24,4 +27,14 @@ public interface PlaceholderIntegration extends Integration {
|
||||
*/
|
||||
String translate(@NotNull String text,
|
||||
@Nullable Player player);
|
||||
|
||||
/**
|
||||
* Find all placeholders in a given text.
|
||||
*
|
||||
* @param text The text.
|
||||
* @return The placeholders.
|
||||
*/
|
||||
default List<String> findPlaceholdersIn(@NotNull String text) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -80,6 +82,21 @@ public final class PlaceholderManager {
|
||||
return processed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all placeholders in a given text.
|
||||
*
|
||||
* @param text The text.
|
||||
* @return The placeholders.
|
||||
*/
|
||||
public static List<String> findPlaceholdersIn(@NotNull final String text) {
|
||||
List<String> found = new ArrayList<>();
|
||||
for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) {
|
||||
found.addAll(integration.findPlaceholdersIn(text));
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private PlaceholderManager() {
|
||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||
}
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
package com.willfp.eco.util;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
* Utilities / API methods for numbers.
|
||||
@@ -16,6 +20,11 @@ public final class NumberUtils {
|
||||
*/
|
||||
private static final double[] SIN_LOOKUP = new double[65536];
|
||||
|
||||
/**
|
||||
* Crunch handler.
|
||||
*/
|
||||
private static BiFunction<@NotNull String, @Nullable Player, @NotNull Double> crunch;
|
||||
|
||||
/**
|
||||
* Set of roman numerals to look up.
|
||||
*/
|
||||
@@ -218,6 +227,38 @@ public final class NumberUtils {
|
||||
return formatted.endsWith("00") ? String.valueOf((int) toFormat) : formatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate an expression.
|
||||
*
|
||||
* @param expression The expression.
|
||||
* @return The value of the expression.
|
||||
*/
|
||||
public static double evaluateExpression(@NotNull final String expression) {
|
||||
return evaluateExpression(expression, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate an expression with respect to a player (for placeholders).
|
||||
*
|
||||
* @param expression The expression.
|
||||
* @param player The player.
|
||||
* @return The value of the expression.
|
||||
*/
|
||||
public static double evaluateExpression(@NotNull final String expression,
|
||||
@Nullable final Player player) {
|
||||
return crunch.apply(expression, player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init crunch handler.
|
||||
*
|
||||
* @param handler The handler.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static void initCrunch(@NotNull final BiFunction<@NotNull String, @Nullable Player, @NotNull Double> handler) {
|
||||
crunch = handler;
|
||||
}
|
||||
|
||||
private NumberUtils() {
|
||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||
}
|
||||
|
||||
@@ -49,4 +49,14 @@ class PlaceholderIntegrationPAPI(private val plugin: EcoPlugin) : PlaceholderExp
|
||||
): String {
|
||||
return PlaceholderAPI.setPlaceholders(player, text)
|
||||
}
|
||||
|
||||
override fun findPlaceholdersIn(text: String): MutableList<String> {
|
||||
val placeholders = mutableListOf<String>()
|
||||
val matcher = PlaceholderAPI.getPlaceholderPattern().matcher(text)
|
||||
while (matcher.find()) {
|
||||
placeholders.add(matcher.group())
|
||||
}
|
||||
|
||||
return placeholders
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ dependencies {
|
||||
implementation('net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT') {
|
||||
exclude group: 'net.kyori', module: 'adventure-api'
|
||||
}
|
||||
implementation 'com.github.Redempt:Crunch:1.0'
|
||||
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
|
||||
compileOnly 'org.apache.maven:maven-artifact:3.8.1'
|
||||
compileOnly 'com.google.code.gson:gson:2.8.8'
|
||||
|
||||
@@ -95,12 +95,14 @@ import com.willfp.eco.internal.spigot.integrations.hologram.HologramHolographicD
|
||||
import com.willfp.eco.internal.spigot.integrations.mcmmo.McmmoIntegrationImpl
|
||||
import com.willfp.eco.internal.spigot.integrations.multiverseinventories.MultiverseInventoriesIntegration
|
||||
import com.willfp.eco.internal.spigot.integrations.shop.ShopShopGuiPlus
|
||||
import com.willfp.eco.internal.spigot.math.evaluateExpression
|
||||
import com.willfp.eco.internal.spigot.proxy.BlockBreakProxy
|
||||
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
|
||||
import com.willfp.eco.internal.spigot.proxy.SkullProxy
|
||||
import com.willfp.eco.internal.spigot.proxy.TPSProxy
|
||||
import com.willfp.eco.internal.spigot.recipes.ShapedRecipeListener
|
||||
import com.willfp.eco.util.BlockUtils
|
||||
import com.willfp.eco.util.NumberUtils
|
||||
import com.willfp.eco.util.ServerUtils
|
||||
import com.willfp.eco.util.SkullUtils
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences
|
||||
@@ -155,6 +157,8 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
||||
val tpsProxy = getProxy(TPSProxy::class.java)
|
||||
ServerUtils.initialize { tpsProxy.getTPS() }
|
||||
|
||||
NumberUtils.initCrunch { exp, player -> evaluateExpression(exp, player) }
|
||||
|
||||
postInit()
|
||||
}
|
||||
|
||||
@@ -235,7 +239,7 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
||||
IntegrationLoader("Alice") { AnticheatManager.register(this, AnticheatAlice()) },
|
||||
|
||||
// Custom Entities
|
||||
IntegrationLoader("MythicMobs") { CustomEntitiesManager.register(CustomEntitiesMythicMobs())},
|
||||
IntegrationLoader("MythicMobs") { CustomEntitiesManager.register(CustomEntitiesMythicMobs()) },
|
||||
|
||||
// Custom Items
|
||||
IntegrationLoader("Oraxen") { CustomItemsManager.register(CustomItemsOraxen()) },
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.willfp.eco.internal.spigot.math
|
||||
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
|
||||
import org.bukkit.entity.Player
|
||||
import redempt.crunch.CompiledExpression
|
||||
import redempt.crunch.Crunch
|
||||
import redempt.crunch.functional.EvaluationEnvironment
|
||||
|
||||
private val cache = mutableMapOf<String, CompiledExpression>()
|
||||
|
||||
fun evaluateExpression(expression: String, player: Player?): Double {
|
||||
val placeholderValues = PlaceholderManager.findPlaceholdersIn(expression)
|
||||
.map { PlaceholderManager.getResult(player, expression).toDouble() }
|
||||
.toDoubleArray()
|
||||
val compiled = generateExpression(expression)
|
||||
return compiled.evaluate(*placeholderValues)
|
||||
}
|
||||
|
||||
private fun generateExpression(expression: String): CompiledExpression {
|
||||
val cached = cache[expression]
|
||||
|
||||
if (cached != null) {
|
||||
return cached
|
||||
}
|
||||
|
||||
val placeholders = PlaceholderManager.findPlaceholdersIn(expression)
|
||||
|
||||
val env = EvaluationEnvironment()
|
||||
env.setVariableNames(*placeholders.toTypedArray())
|
||||
|
||||
val compiled = Crunch.compileExpression(expression, env)
|
||||
cache[expression] = compiled
|
||||
return compiled
|
||||
}
|
||||
Reference in New Issue
Block a user