Added support for evaluating mathematical expressions via Crunch

This commit is contained in:
Auxilor
2022-01-11 16:43:36 +00:00
parent d35285d0dc
commit 86d5e9d09e
8 changed files with 125 additions and 1 deletions

View File

@@ -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 {

View File

@@ -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<>();
}
}

View File

@@ -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");
}

View File

@@ -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");
}

View File

@@ -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
}
}

View File

@@ -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'

View File

@@ -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()) },

View File

@@ -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
}