Merge remote-tracking branch 'origin/master'

# Conflicts:
#	gradle.properties
This commit is contained in:
Auxilor
2024-03-29 16:39:42 +00:00
36 changed files with 522 additions and 90 deletions

View File

@@ -1,6 +1,6 @@
name: Java CI name: Java CI
on: [ push, pull_request ] on: [ push, pull_request, workflow_dispatch ]
jobs: jobs:
build: build:

View File

@@ -89,6 +89,9 @@ allprojects {
// IridiumSkyblock // IridiumSkyblock
maven("https://nexus.iridiumdevelopment.net/repository/maven-releases/") maven("https://nexus.iridiumdevelopment.net/repository/maven-releases/")
// HuskPlugins
maven("https://repo.william278.net/releases")
} }
dependencies { dependencies {

View File

@@ -167,7 +167,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike, Regist
/** /**
* The tasks to run on task creation. * The tasks to run on task creation.
*/ */
private final ListMap<LifecyclePosition, Runnable> createTasks = new ListMap<>(); private final ListMap<LifecyclePosition, Runnable> onCreateTasks = new ListMap<>();
/** /**
* Create a new plugin. * Create a new plugin.
@@ -638,7 +638,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike, Regist
this.handleLifecycle(this.onReload, this::handleReload); this.handleLifecycle(this.onReload, this::handleReload);
if (cancelTasks) { if (cancelTasks) {
this.handleLifecycle(this.createTasks, this::createTasks); this.handleLifecycle(this.onCreateTasks, this::createTasks);
} }
for (Extension extension : this.extensionLoader.getLoadedExtensions()) { for (Extension extension : this.extensionLoader.getLoadedExtensions()) {
@@ -666,6 +666,26 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike, Regist
this.onReload.append(position, task); this.onReload.append(position, task);
} }
/**
* Add new task to run on createTasks.
*
* @param task The task.
*/
public final void onCreateTasks(@NotNull final Runnable task) {
this.onCreateTasks(LifecyclePosition.END, task);
}
/**
* Add new task to run on createTasks.
*
* @param position The position to run the task.
* @param task The task.
*/
public final void onCreateTasks(@NotNull final LifecyclePosition position,
@NotNull final Runnable task) {
this.onCreateTasks.append(position, task);
}
/** /**
* Reload the plugin and return the time taken to reload. * Reload the plugin and return the time taken to reload.
* *

View File

@@ -86,7 +86,7 @@ public class ConfigSlot extends CustomSlot {
for (String command : config.getStrings(configKey)) { for (String command : config.getStrings(configKey)) {
if (command.startsWith("console:")) { if (command.startsWith("console:")) {
commands.add(new CommandToDispatch( commands.add(new CommandToDispatch(
StringUtils.removePrefix("console:", command), StringUtils.removePrefix(command, "console:"),
true true
)); ));
} else { } else {

View File

@@ -120,8 +120,12 @@ public final class ConfiguredPrice implements Price {
*/ */
public String getDisplay(@NotNull final Player player, public String getDisplay(@NotNull final Player player,
final double multiplier) { final double multiplier) {
double value = this.getPrice().getValue(player, multiplier);
return StringUtils.format( return StringUtils.format(
formatString.replace("%value%", NumberUtils.format(this.getPrice().getValue(player, multiplier))), formatString
.replace("%value%", NumberUtils.format(value))
.replace("%value_commas%", NumberUtils.formatWithCommas(value)),
player, player,
StringUtils.FormatOption.WITH_PLACEHOLDERS StringUtils.FormatOption.WITH_PLACEHOLDERS
); );

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.proxy; package com.willfp.eco.core.proxy;
import com.willfp.eco.core.version.Version;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import java.util.Arrays; import java.util.Arrays;
@@ -12,7 +13,7 @@ public final class ProxyConstants {
/** /**
* The NMS version that the server is running on. * The NMS version that the server is running on.
*/ */
public static final String NMS_VERSION = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; public static final String NMS_VERSION;
/** /**
* All supported NMS versions. * All supported NMS versions.
@@ -32,4 +33,17 @@ public final class ProxyConstants {
private ProxyConstants() { private ProxyConstants() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }
static {
String currentMinecraftVersion = Bukkit.getServer().getBukkitVersion().split("-")[0];
String nmsVersion;
if (new Version(currentMinecraftVersion).compareTo(new Version("1.20.5")) < 0) {
nmsVersion = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
} else {
nmsVersion = currentMinecraftVersion.replace(".", "_");
}
NMS_VERSION = nmsVersion;
}
} }

View File

@@ -203,6 +203,20 @@ public final class NumberUtils {
return formatted.endsWith("00") ? String.valueOf((int) toFormat) : formatted; return formatted.endsWith("00") ? String.valueOf((int) toFormat) : formatted;
} }
/**
* Format double to string with commas.
*
* @param toFormat The number to format.
* @return Formatted.
*/
@NotNull
public static String formatWithCommas(final double toFormat) {
DecimalFormat df = new DecimalFormat("#,##0.00");
String formatted = df.format(toFormat);
return formatted.endsWith(".00") ? formatted.substring(0, formatted.length() - 3) : formatted;
}
/** /**
* Evaluate an expression. * Evaluate an expression.
* *

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.util;
import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Caffeine;
import com.willfp.eco.core.Eco;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -15,7 +16,7 @@ public final class PatternUtils {
* Cache of compiled literal patterns. * Cache of compiled literal patterns.
*/ */
private static final Cache<String, Pattern> LITERAL_PATTERN_CACHE = Caffeine.newBuilder() private static final Cache<String, Pattern> LITERAL_PATTERN_CACHE = Caffeine.newBuilder()
.expireAfterAccess(1, TimeUnit.MINUTES) .expireAfterAccess(Eco.get().getEcoPlugin().getConfigYml().getInt("literal-cache-ttl"), TimeUnit.MINUTES)
.build(); .build();
/** /**

View File

@@ -37,9 +37,14 @@ fun ItemStack.toSNBT() =
Items.toSNBT(this) Items.toSNBT(this)
/** @see Items.isEmpty */ /** @see Items.isEmpty */
@Deprecated("Use ItemStack.isEcoEmpty", ReplaceWith("Items.isEmpty(this)"))
val ItemStack?.isEmpty: Boolean val ItemStack?.isEmpty: Boolean
get() = Items.isEmpty(this) get() = Items.isEmpty(this)
/** @see Items.isEmpty */
val ItemStack?.isEcoEmpty: Boolean
get() = Items.isEmpty(this)
/** @see Items.matchesAny */ /** @see Items.matchesAny */
fun Collection<TestableItem>.matches(item: ItemStack): Boolean = fun Collection<TestableItem>.matches(item: ItemStack): Boolean =
Items.matchesAny(item, this) Items.matchesAny(item, this)

View File

@@ -8,6 +8,10 @@ import com.willfp.eco.core.placeholder.context.PlaceholderContext
fun Number.toNumeral(): String = fun Number.toNumeral(): String =
NumberUtils.toNumeral(this.toInt()) NumberUtils.toNumeral(this.toInt())
/** @see NumberUtils.formatWithCommas */
fun Number.formatWithCommas(): String =
NumberUtils.formatWithCommas(this.toDouble())
/** @see NumberUtils.fromNumeral */ /** @see NumberUtils.fromNumeral */
fun String.parseNumeral(): Int = fun String.parseNumeral(): Int =
NumberUtils.fromNumeral(this) NumberUtils.fromNumeral(this)

View File

@@ -3,7 +3,6 @@ package com.willfp.eco.internal.command
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.command.CommandBase import com.willfp.eco.core.command.CommandBase
import com.willfp.eco.core.command.NotificationException import com.willfp.eco.core.command.NotificationException
import com.willfp.eco.core.config.base.LangYml
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.command.Command import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandExecutor

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.internal.config
import com.willfp.eco.core.config.ConfigType import com.willfp.eco.core.config.ConfigType
import com.willfp.eco.core.placeholder.InjectablePlaceholder import com.willfp.eco.core.placeholder.InjectablePlaceholder
import java.util.concurrent.ConcurrentHashMap
class EcoConfigSection( class EcoConfigSection(
type: ConfigType, type: ConfigType,

View File

@@ -15,7 +15,6 @@ import java.nio.channels.AsynchronousFileChannel
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.StandardOpenOption import java.nio.file.StandardOpenOption
@Suppress("UNCHECKED_CAST")
open class EcoLoadableConfig( open class EcoLoadableConfig(
type: ConfigType, type: ConfigType,
configName: String, configName: String,

View File

@@ -42,6 +42,7 @@ class EcoExtensionLoader(
} }
} }
@Suppress("DEPRECATION")
@Throws(MalformedExtensionException::class) @Throws(MalformedExtensionException::class)
private fun loadExtension(extensionJar: File) { private fun loadExtension(extensionJar: File) {
val url = extensionJar.toURI().toURL() val url = extensionJar.toURI().toURL()

View File

@@ -25,7 +25,6 @@ class FastInternalNamespacedKeyFactory : InternalNamespacedKeyFactory {
class SafeInternalNamespacedKeyFactory : InternalNamespacedKeyFactory { class SafeInternalNamespacedKeyFactory : InternalNamespacedKeyFactory {
override fun create(namespace: String, key: String): NamespacedKey { override fun create(namespace: String, key: String): NamespacedKey {
@Suppress("DEPRECATION")
return NamespacedKey(namespace, key) return NamespacedKey(namespace, key)
} }
} }

View File

@@ -1,7 +1,7 @@
package com.willfp.eco.internal.gui.menu package com.willfp.eco.internal.gui.menu
import com.willfp.eco.core.gui.menu.events.CaptiveItemChangeEvent import com.willfp.eco.core.gui.menu.events.CaptiveItemChangeEvent
import com.willfp.eco.core.items.isEmpty import com.willfp.eco.core.items.isEcoEmpty
import com.willfp.eco.core.recipe.parts.EmptyTestableItem import com.willfp.eco.core.recipe.parts.EmptyTestableItem
import com.willfp.eco.util.MenuUtils import com.willfp.eco.util.MenuUtils
import com.willfp.eco.util.openMenu import com.willfp.eco.util.openMenu
@@ -55,7 +55,7 @@ class RenderedInventory(
val actualItem = inventory.getItem(bukkit) ?: continue val actualItem = inventory.getItem(bukkit) ?: continue
if (slot.isCaptiveFromEmpty) { if (slot.isCaptiveFromEmpty) {
if (!actualItem.isEmpty) { if (!actualItem.isEcoEmpty) {
newCaptive[position] = actualItem newCaptive[position] = actualItem
} }
} else { } else {

View File

@@ -6,6 +6,7 @@ import com.willfp.eco.core.placeholder.context.placeholderContext
import me.clip.placeholderapi.expansion.PlaceholderExpansion import me.clip.placeholderapi.expansion.PlaceholderExpansion
import org.bukkit.entity.Player import org.bukkit.entity.Player
@Suppress("DEPRECATION")
class PAPIExpansion(private val plugin: EcoPlugin) : PlaceholderExpansion() { class PAPIExpansion(private val plugin: EcoPlugin) : PlaceholderExpansion() {
init { init {
register() register()

View File

@@ -0,0 +1,64 @@
package com.willfp.eco.internal.items
import com.willfp.eco.core.items.args.LookupArgParser
import org.bukkit.block.CreatureSpawner
import org.bukkit.entity.EntityType
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.BlockStateMeta
import org.bukkit.inventory.meta.ItemMeta
import java.util.function.Predicate
object ArgParserEntity : LookupArgParser {
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
if (meta !is BlockStateMeta) {
return null
}
if (meta.hasBlockState() || meta.blockState !is CreatureSpawner) {
return null
}
val state = meta.blockState as CreatureSpawner
var type: String? = null
for (arg in args) {
val argSplit = arg.split(":")
if (!argSplit[0].equals("entity", ignoreCase = true)) {
continue
}
if (argSplit.size < 2) {
continue
}
type = argSplit[1]
}
type ?: return null
val entityType = runCatching { EntityType.valueOf(type.uppercase()) }.getOrNull() ?: return null
state.spawnedType = entityType
meta.blockState = state
return Predicate {
val testMeta = ((it.itemMeta as? BlockStateMeta) as? CreatureSpawner) ?: return@Predicate false
testMeta.spawnedType?.name?.equals(type, true) == true
}
}
override fun serializeBack(meta: ItemMeta): String? {
if (meta !is BlockStateMeta) {
return null
}
if (meta.hasBlockState() || meta.blockState !is CreatureSpawner) {
return null
}
val state = meta.blockState as CreatureSpawner
return state.spawnedType?.let { "entity:${state.spawnedType!!.name}" } ?: return null
}
}

View File

@@ -28,7 +28,6 @@ object ArgParserHead : LookupArgParser {
playerName ?: return null playerName ?: return null
@Suppress("DEPRECATION")
val player = Bukkit.getOfflinePlayer(playerName) val player = Bukkit.getOfflinePlayer(playerName)
meta.owningPlayer = player meta.owningPlayer = player

View File

@@ -1,13 +1,11 @@
package com.willfp.eco.internal.items package com.willfp.eco.internal.items
import com.willfp.eco.core.items.args.LookupArgParser import com.willfp.eco.core.items.args.LookupArgParser
import org.bukkit.Color
import org.bukkit.NamespacedKey import org.bukkit.NamespacedKey
import org.bukkit.Registry import org.bukkit.Registry
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ArmorMeta import org.bukkit.inventory.meta.ArmorMeta
import org.bukkit.inventory.meta.ItemMeta import org.bukkit.inventory.meta.ItemMeta
import org.bukkit.inventory.meta.LeatherArmorMeta
import org.bukkit.inventory.meta.trim.ArmorTrim import org.bukkit.inventory.meta.trim.ArmorTrim
import org.bukkit.inventory.meta.trim.TrimMaterial import org.bukkit.inventory.meta.trim.TrimMaterial
import org.bukkit.inventory.meta.trim.TrimPattern import org.bukkit.inventory.meta.trim.TrimPattern

View File

@@ -7,6 +7,8 @@ import com.willfp.eco.core.placeholder.InjectablePlaceholder
import com.willfp.eco.core.placeholder.Placeholder import com.willfp.eco.core.placeholder.Placeholder
import com.willfp.eco.core.placeholder.context.PlaceholderContext import com.willfp.eco.core.placeholder.context.PlaceholderContext
import com.willfp.eco.util.StringUtils import com.willfp.eco.util.StringUtils
import com.willfp.eco.util.evaluateExpression
import com.willfp.eco.util.toNiceString
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
/* /*
@@ -19,6 +21,8 @@ but it's still best to minimise the memory overhead.
class PlaceholderParser { class PlaceholderParser {
private val placeholderRegex = Regex("%([^% ]+)%") private val placeholderRegex = Regex("%([^% ]+)%")
private val prettyMathExpressionRegex = Regex("(\\{\\^\\{)(.)+(}})")
private val mathExpressionRegex = Regex("(\\{\\{)(.)+(}})")
private val placeholderLookupCache = Caffeine.newBuilder() private val placeholderLookupCache = Caffeine.newBuilder()
.expireAfterWrite(1, TimeUnit.SECONDS) .expireAfterWrite(1, TimeUnit.SECONDS)
@@ -34,6 +38,29 @@ class PlaceholderParser {
injections: Collection<InjectablePlaceholder>, injections: Collection<InjectablePlaceholder>,
translateEcoPlaceholders: Boolean = true translateEcoPlaceholders: Boolean = true
): String { ): String {
var processed = text
// Only evaluate math expressions if there might be any
// Checking { as a char is faster than checking a string sequence,
// even if it might lead to false positives.
if ('{' in processed) {
if ('^' in processed) {
// Evaluate pretty math expressions
processed = prettyMathExpressionRegex.findAll(processed).fold(processed) { acc, matchResult ->
val expression = matchResult.value.substring(3, matchResult.value.length - 2)
val result = evaluateExpression(expression, context)
acc.replace(matchResult.value, result.toNiceString())
}
}
// Evaluate math expressions
processed = mathExpressionRegex.findAll(processed).fold(processed) { acc, matchResult ->
val expression = matchResult.value.substring(2, matchResult.value.length - 2)
val result = evaluateExpression(expression, context)
acc.replace(matchResult.value, result.toString())
}
}
/* /*
Why am I doing injections at the start, and again at the end? Why am I doing injections at the start, and again at the end?
@@ -55,7 +82,7 @@ class PlaceholderParser {
*/ */
// Apply injections first // Apply injections first
var processed = injections.fold(text) { acc, injection -> processed = injections.fold(processed) { acc, injection ->
injection.tryTranslateQuickly(acc, context) injection.tryTranslateQuickly(acc, context)
} }

View File

@@ -7,7 +7,7 @@ version = rootProject.version
dependencies { dependencies {
implementation(project(":eco-core:core-nms:nms-common")) implementation(project(":eco-core:core-nms:nms-common"))
paperweight.paperDevBundle("1.20.3-R0.1-SNAPSHOT") paperweight.paperDevBundle("1.20.4-R0.1-SNAPSHOT")
implementation("net.kyori:adventure-text-minimessage:4.11.0") { implementation("net.kyori:adventure-text-minimessage:4.11.0") {
version { version {

View File

@@ -46,17 +46,17 @@ class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFa
override fun <T : Any, Z : Any> set(key: String, dataType: PersistentDataType<T, Z>, value: Z) { override fun <T : Any, Z : Any> set(key: String, dataType: PersistentDataType<T, Z>, value: Z) {
customDataTags[key] = customDataTags[key] =
registry.wrap(dataType.primitiveType, dataType.toPrimitive(value, handle.adapterContext)) registry.wrap(dataType, dataType.toPrimitive(value, handle.adapterContext))
} }
override fun <T : Any, Z : Any> has(key: String, dataType: PersistentDataType<T, Z>): Boolean { override fun <T : Any, Z : Any> has(key: String, dataType: PersistentDataType<T, Z>): Boolean {
val value = customDataTags[key] ?: return false val value = customDataTags[key] ?: return false
return registry.isInstanceOf(dataType.primitiveType, value) return registry.isInstanceOf(dataType, value)
} }
override fun <T : Any, Z : Any> get(key: String, dataType: PersistentDataType<T, Z>): Z? { override fun <T : Any, Z : Any> get(key: String, dataType: PersistentDataType<T, Z>): Z? {
val value = customDataTags[key] ?: return null val value = customDataTags[key] ?: return null
return dataType.fromPrimitive(registry.extract(dataType.primitiveType, value), handle.adapterContext) return dataType.fromPrimitive(registry.extract<T, Tag>(dataType, value), handle.adapterContext)
} }
override fun <T : Any, Z : Any> getOrDefault( override fun <T : Any, Z : Any> getOrDefault(

View File

@@ -25,7 +25,7 @@ dependencies {
// Included in spigot jar // Included in spigot jar
compileOnly("com.google.code.gson:gson:2.8.8") compileOnly("com.google.code.gson:gson:2.8.8")
compileOnly("io.papermc.paper:paper-api:1.19.3-R0.1-SNAPSHOT") compileOnly("io.papermc.paper:paper-api:1.20.2-R0.1-SNAPSHOT")
// Plugin dependencies // Plugin dependencies
compileOnly("com.comphenix.protocol:ProtocolLib:5.0.0-SNAPSHOT") compileOnly("com.comphenix.protocol:ProtocolLib:5.0.0-SNAPSHOT")
@@ -62,6 +62,9 @@ dependencies {
exclude(group = "*", module = "*") exclude(group = "*", module = "*")
} }
compileOnly("com.iridium:IridiumSkyblock:4.0.8") compileOnly("com.iridium:IridiumSkyblock:4.0.8")
compileOnly("net.william278.huskclaims:huskclaims-bukkit:1.0.1")
compileOnly("net.william278:husktowns:2.6.1")
compileOnly("com.github.jojodmo:ItemBridge:b0054538c1")
compileOnly(fileTree("../../lib") { compileOnly(fileTree("../../lib") {
include("*.jar") include("*.jar")

View File

@@ -22,34 +22,8 @@ import com.willfp.eco.core.particle.Particles
import com.willfp.eco.core.price.Prices import com.willfp.eco.core.price.Prices
import com.willfp.eco.internal.data.MavenVersionToStringAdapter import com.willfp.eco.internal.data.MavenVersionToStringAdapter
import com.willfp.eco.internal.data.VersionToStringAdapter import com.willfp.eco.internal.data.VersionToStringAdapter
import com.willfp.eco.internal.entities.EntityArgParserAdult import com.willfp.eco.internal.entities.*
import com.willfp.eco.internal.entities.EntityArgParserAttackDamage import com.willfp.eco.internal.items.*
import com.willfp.eco.internal.entities.EntityArgParserAttackSpeed
import com.willfp.eco.internal.entities.EntityArgParserBaby
import com.willfp.eco.internal.entities.EntityArgParserCharged
import com.willfp.eco.internal.entities.EntityArgParserEquipment
import com.willfp.eco.internal.entities.EntityArgParserExplosionRadius
import com.willfp.eco.internal.entities.EntityArgParserFlySpeed
import com.willfp.eco.internal.entities.EntityArgParserFollowRange
import com.willfp.eco.internal.entities.EntityArgParserHealth
import com.willfp.eco.internal.entities.EntityArgParserJumpStrength
import com.willfp.eco.internal.entities.EntityArgParserKnockback
import com.willfp.eco.internal.entities.EntityArgParserKnockbackResistance
import com.willfp.eco.internal.entities.EntityArgParserName
import com.willfp.eco.internal.entities.EntityArgParserNoAI
import com.willfp.eco.internal.entities.EntityArgParserSilent
import com.willfp.eco.internal.entities.EntityArgParserSize
import com.willfp.eco.internal.entities.EntityArgParserSpawnReinforcements
import com.willfp.eco.internal.entities.EntityArgParserSpeed
import com.willfp.eco.internal.items.ArgParserColor
import com.willfp.eco.internal.items.ArgParserCustomModelData
import com.willfp.eco.internal.items.ArgParserEnchantment
import com.willfp.eco.internal.items.ArgParserFlag
import com.willfp.eco.internal.items.ArgParserHead
import com.willfp.eco.internal.items.ArgParserName
import com.willfp.eco.internal.items.ArgParserTexture
import com.willfp.eco.internal.items.ArgParserTrim
import com.willfp.eco.internal.items.ArgParserUnbreakable
import com.willfp.eco.internal.lookup.SegmentParserGroup import com.willfp.eco.internal.lookup.SegmentParserGroup
import com.willfp.eco.internal.lookup.SegmentParserUseIfPresent import com.willfp.eco.internal.lookup.SegmentParserUseIfPresent
import com.willfp.eco.internal.particle.ParticleFactoryRGB import com.willfp.eco.internal.particle.ParticleFactoryRGB
@@ -69,37 +43,10 @@ import com.willfp.eco.internal.spigot.eventlisteners.armor.ArmorListener
import com.willfp.eco.internal.spigot.gui.GUIListener import com.willfp.eco.internal.spigot.gui.GUIListener
import com.willfp.eco.internal.spigot.integrations.afk.AFKIntegrationCMI import com.willfp.eco.internal.spigot.integrations.afk.AFKIntegrationCMI
import com.willfp.eco.internal.spigot.integrations.afk.AFKIntegrationEssentials import com.willfp.eco.internal.spigot.integrations.afk.AFKIntegrationEssentials
import com.willfp.eco.internal.spigot.integrations.anticheat.AnticheatAAC import com.willfp.eco.internal.spigot.integrations.anticheat.*
import com.willfp.eco.internal.spigot.integrations.anticheat.AnticheatAlice import com.willfp.eco.internal.spigot.integrations.antigrief.*
import com.willfp.eco.internal.spigot.integrations.anticheat.AnticheatMatrix
import com.willfp.eco.internal.spigot.integrations.anticheat.AnticheatNCP
import com.willfp.eco.internal.spigot.integrations.anticheat.AnticheatSpartan
import com.willfp.eco.internal.spigot.integrations.anticheat.AnticheatVulcan
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefBentoBox
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefCombatLogXV10
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefCombatLogXV11
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefCrashClaim
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefDeluxeCombat
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefFabledSkyBlock
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefFactionsUUID
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefGriefPrevention
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefIridiumSkyblock
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefKingdoms
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefLands
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefPvPManager
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefRPGHorses
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefSuperiorSkyblock2
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefTowny
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefWorldGuard
import com.willfp.eco.internal.spigot.integrations.customentities.CustomEntitiesMythicMobs import com.willfp.eco.internal.spigot.integrations.customentities.CustomEntitiesMythicMobs
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsCustomCrafting import com.willfp.eco.internal.spigot.integrations.customitems.*
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsDenizen
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsExecutableItems
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsHeadDatabase
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsItemsAdder
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsMythicMobs
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsOraxen
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsScyther
import com.willfp.eco.internal.spigot.integrations.customrecipes.CustomRecipeCustomCrafting import com.willfp.eco.internal.spigot.integrations.customrecipes.CustomRecipeCustomCrafting
import com.willfp.eco.internal.spigot.integrations.economy.EconomyVault import com.willfp.eco.internal.spigot.integrations.economy.EconomyVault
import com.willfp.eco.internal.spigot.integrations.entitylookup.EntityLookupModelEngine import com.willfp.eco.internal.spigot.integrations.entitylookup.EntityLookupModelEngine
@@ -149,6 +96,7 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
Items.registerArgParser(ArgParserUnbreakable) Items.registerArgParser(ArgParserUnbreakable)
Items.registerArgParser(ArgParserName) Items.registerArgParser(ArgParserName)
Items.registerArgParser(ArgParserHead) Items.registerArgParser(ArgParserHead)
Items.registerArgParser(ArgParserEntity)
if (Prerequisite.HAS_1_20.isMet) { if (Prerequisite.HAS_1_20.isMet) {
Items.registerArgParser(ArgParserTrim) Items.registerArgParser(ArgParserTrim)
} }
@@ -296,6 +244,8 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
IntegrationLoader("Kingdoms") { AntigriefManager.register(AntigriefKingdoms()) }, IntegrationLoader("Kingdoms") { AntigriefManager.register(AntigriefKingdoms()) },
IntegrationLoader("RPGHorses") { AntigriefManager.register(AntigriefRPGHorses()) }, IntegrationLoader("RPGHorses") { AntigriefManager.register(AntigriefRPGHorses()) },
IntegrationLoader("CrashClaim") { AntigriefManager.register(AntigriefCrashClaim()) }, IntegrationLoader("CrashClaim") { AntigriefManager.register(AntigriefCrashClaim()) },
IntegrationLoader("HuskTowns") { AntigriefManager.register(AntigriefHuskTowns()) },
IntegrationLoader("HuskClaims") { AntigriefManager.register(AntigriefHuskClaims()) },
IntegrationLoader("CombatLogX") { IntegrationLoader("CombatLogX") {
val pluginManager = Bukkit.getPluginManager() val pluginManager = Bukkit.getPluginManager()
val combatLogXPlugin = pluginManager.getPlugin("CombatLogX") ?: return@IntegrationLoader val combatLogXPlugin = pluginManager.getPlugin("CombatLogX") ?: return@IntegrationLoader
@@ -335,6 +285,7 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
IntegrationLoader("MythicMobs") { CustomItemsManager.register(CustomItemsMythicMobs(this)) }, IntegrationLoader("MythicMobs") { CustomItemsManager.register(CustomItemsMythicMobs(this)) },
IntegrationLoader("Scyther") { CustomItemsManager.register(CustomItemsScyther()) }, IntegrationLoader("Scyther") { CustomItemsManager.register(CustomItemsScyther()) },
IntegrationLoader("Denizen") { CustomItemsManager.register(CustomItemsDenizen()) }, IntegrationLoader("Denizen") { CustomItemsManager.register(CustomItemsDenizen()) },
IntegrationLoader("ItemBridge") { CustomItemsManager.register(CustomItemsItemBridge()) },
// Shop // Shop
IntegrationLoader("ShopGUIPlus") { ShopManager.register(ShopShopGuiPlus()) }, IntegrationLoader("ShopGUIPlus") { ShopManager.register(ShopShopGuiPlus()) },

View File

@@ -1,7 +1,7 @@
package com.willfp.eco.internal.spigot.arrows package com.willfp.eco.internal.spigot.arrows
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.items.isEmpty import com.willfp.eco.core.items.isEcoEmpty
import org.bukkit.entity.Arrow import org.bukkit.entity.Arrow
import org.bukkit.entity.LivingEntity import org.bukkit.entity.LivingEntity
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
@@ -29,7 +29,7 @@ class ArrowDataListener(
val item = entity.equipment?.itemInMainHand val item = entity.equipment?.itemInMainHand
if (item.isEmpty || item == null) { if (item.isEcoEmpty || item == null) {
return return
} }

View File

@@ -0,0 +1,135 @@
package com.willfp.eco.internal.spigot.integrations.antigrief
import com.willfp.eco.core.integrations.antigrief.AntigriefIntegration
import net.crashcraft.crashclaim.CrashClaim
import net.crashcraft.crashclaim.permissions.PermissionRoute
import net.william278.huskclaims.api.HuskClaimsAPI
import net.william278.huskclaims.libraries.cloplib.operation.Operation
import net.william278.huskclaims.libraries.cloplib.operation.OperationPosition
import net.william278.huskclaims.libraries.cloplib.operation.OperationType
import net.william278.huskclaims.position.Position
import net.william278.huskclaims.position.World
import org.bukkit.Location
import org.bukkit.block.Block
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Monster
import org.bukkit.entity.Player
import kotlin.jvm.optionals.getOrElse
class AntigriefHuskClaims : AntigriefIntegration {
override fun canBreakBlock(
player: Player,
block: Block
): Boolean {
val api = HuskClaimsAPI.getInstance() ?: return true
val user = api.getOnlineUser(player.uniqueId) ?: return true
return api.isOperationAllowed(
Operation.of(
user,
OperationType.BLOCK_BREAK,
Position.at(
block.x.toDouble(),
block.y.toDouble(),
block.z.toDouble(),
api.getWorld(block.location.world.name)
),
true
)
)
}
override fun canCreateExplosion(
player: Player,
location: Location
): Boolean {
val api = HuskClaimsAPI.getInstance() ?: return true
val user = api.getOnlineUser(player.uniqueId) ?: return true
return api.isOperationAllowed(
Operation.of(
user,
OperationType.EXPLOSION_DAMAGE_ENTITY,
Position.at(
location.x,
location.y,
location.z,
api.getWorld(location.world.name)
),
true
)
)
}
override fun canPlaceBlock(
player: Player,
block: Block
): Boolean {
val api = HuskClaimsAPI.getInstance() ?: return true
val user = api.getOnlineUser(player.uniqueId) ?: return true
return api.isOperationAllowed(
Operation.of(
user,
OperationType.BLOCK_PLACE,
Position.at(
block.x.toDouble(),
block.y.toDouble(),
block.z.toDouble(),
api.getWorld(block.location.world.name)
),
true
)
)
}
override fun canInjure(
player: Player,
victim: LivingEntity
): Boolean {
val api = HuskClaimsAPI.getInstance() ?: return true
val user = api.getOnlineUser(player.uniqueId) ?: return true
return api.isOperationAllowed(
Operation.of(
user,
when (victim) {
is Monster -> OperationType.PLAYER_DAMAGE_MONSTER
is Player -> OperationType.PLAYER_DAMAGE_PLAYER
else -> OperationType.PLAYER_DAMAGE_ENTITY
},
Position.at(
victim.x,
victim.y,
victim.z,
api.getWorld(victim.location.world.name)
),
true
)
)
}
override fun canPickupItem(player: Player, location: Location): Boolean {
return true
}
override fun getPluginName(): String {
return "HuskClaims"
}
override fun equals(other: Any?): Boolean {
if (other !is AntigriefIntegration) {
return false
}
return other.pluginName == this.pluginName
}
override fun hashCode(): Int {
return this.pluginName.hashCode()
}
}

View File

@@ -0,0 +1,129 @@
package com.willfp.eco.internal.spigot.integrations.antigrief
import com.willfp.eco.core.integrations.antigrief.AntigriefIntegration
import net.william278.husktowns.api.HuskTownsAPI
import net.william278.husktowns.claim.Position
import net.william278.husktowns.listener.Operation
import org.bukkit.Location
import org.bukkit.block.Block
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Monster
import org.bukkit.entity.Player
class AntigriefHuskTowns : AntigriefIntegration {
override fun canBreakBlock(
player: Player,
block: Block
): Boolean {
val api = HuskTownsAPI.getInstance() ?: return true
val user = api.getOnlineUser(player) ?: return true
return api.isOperationAllowed(
Operation.of(
user,
Operation.Type.BLOCK_BREAK,
Position.at(
block.location.x,
block.location.y,
block.location.z,
api.getWorld(block.world)
),
true
)
)
}
override fun canCreateExplosion(
player: Player,
location: Location
): Boolean {
val api = HuskTownsAPI.getInstance() ?: return true
val user = api.getOnlineUser(player) ?: return true
return api.isOperationAllowed(
Operation.of(
user,
Operation.Type.EXPLOSION_DAMAGE_ENTITY,
Position.at(
location.x,
location.y,
location.z,
api.getWorld(location.world)
),
true
)
)
}
override fun canPlaceBlock(
player: Player,
block: Block
): Boolean {
val api = HuskTownsAPI.getInstance() ?: return true
val user = api.getOnlineUser(player) ?: return true
return api.isOperationAllowed(
Operation.of(
user,
Operation.Type.BLOCK_PLACE,
Position.at(
block.location.x,
block.location.y,
block.location.z,
api.getWorld(block.world)
),
true
)
)
}
override fun canInjure(
player: Player,
victim: LivingEntity
): Boolean {
val api = HuskTownsAPI.getInstance() ?: return true
val user = api.getOnlineUser(player) ?: return true
return api.isOperationAllowed(
Operation.of(
user,
when(victim) {
is Monster -> Operation.Type.PLAYER_DAMAGE_MONSTER
is Player -> Operation.Type.PLAYER_DAMAGE_PLAYER
else -> Operation.Type.PLACE_HANGING_ENTITY
},
Position.at(
player.location.x,
player.location.y,
player.location.z,
api.getWorld(player.world)
),
true
)
)
}
override fun canPickupItem(player: Player, location: Location): Boolean {
return true
}
override fun getPluginName(): String {
return "HuskTowns"
}
override fun equals(other: Any?): Boolean {
if (other !is AntigriefIntegration) {
return false
}
return other.pluginName == this.pluginName
}
override fun hashCode(): Int {
return this.pluginName.hashCode()
}
}

View File

@@ -0,0 +1,47 @@
package com.willfp.eco.internal.spigot.integrations.customitems
import com.jojodmo.itembridge.ItemBridge
import com.willfp.eco.core.integrations.customitems.CustomItemsIntegration
import com.willfp.eco.core.items.CustomItem
import com.willfp.eco.core.items.Items
import com.willfp.eco.core.items.TestableItem
import com.willfp.eco.core.items.provider.ItemProvider
import com.willfp.eco.util.namespacedKeyOf
import org.bukkit.inventory.ItemStack
class CustomItemsItemBridge : CustomItemsIntegration {
override fun registerProvider() {
Items.registerItemProvider(ItemBridgeProvider())
}
override fun getPluginName(): String {
return "ItemBridge"
}
private class ItemBridgeProvider : ItemProvider("itembridge") {
override fun provideForKey(key: String): TestableItem? {
val split = key.split(":").toMutableList()
if (split.size < 2) {
return null
}
val itemKey = split[0]
val item = split[1]
val stack = ItemBridge.getItemStack(itemKey, item) ?: kotlin.run {
return null
}
return CustomItem(
namespacedKeyOf("eco:${key.lowercase().replace(":", "__")}"),
{ test: ItemStack ->
ItemBridge.isItemStack(test, itemKey, item)
},
stack
)
}
}
}

View File

@@ -5,6 +5,7 @@ import com.github.benmanes.caffeine.cache.Caffeine
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
import com.willfp.eco.core.placeholder.context.PlaceholderContext import com.willfp.eco.core.placeholder.context.PlaceholderContext
import com.willfp.eco.internal.placeholder.PlaceholderParser import com.willfp.eco.internal.placeholder.PlaceholderParser
import com.willfp.eco.util.randDouble
import redempt.crunch.CompiledExpression import redempt.crunch.CompiledExpression
import redempt.crunch.Crunch import redempt.crunch.Crunch
import redempt.crunch.functional.EvaluationEnvironment import redempt.crunch.functional.EvaluationEnvironment
@@ -22,6 +23,10 @@ private val max = Function("max", 2) {
max(it[0], it[1]) max(it[0], it[1])
} }
private val rand = Function("random", 2) {
randDouble(it[0], it[1])
}
interface ExpressionHandler { interface ExpressionHandler {
fun evaluate(expression: String, context: PlaceholderContext): Double? fun evaluate(expression: String, context: PlaceholderContext): Double?
} }
@@ -77,7 +82,7 @@ class ImmediatePlaceholderTranslationExpressionHandler(
.build() .build()
private val env = EvaluationEnvironment().apply { private val env = EvaluationEnvironment().apply {
addFunctions(min, max) addFunctions(min, max, rand)
} }
override fun evaluate(expression: String, context: PlaceholderContext): Double? { override fun evaluate(expression: String, context: PlaceholderContext): Double? {
@@ -106,7 +111,7 @@ class LazyPlaceholderTranslationExpressionHandler(
val compiled = cache.getOrPut(expression) { val compiled = cache.getOrPut(expression) {
val env = EvaluationEnvironment() val env = EvaluationEnvironment()
env.setVariableNames(*placeholders.toTypedArray()) env.setVariableNames(*placeholders.toTypedArray())
env.addFunctions(min, max) env.addFunctions(rand, min, max)
runCatching { Crunch.compileExpression(expression, env) }.getOrNull() runCatching { Crunch.compileExpression(expression, env) }.getOrNull()
} }

View File

@@ -2,7 +2,7 @@ package com.willfp.eco.internal.spigot.recipes
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.items.TestableItem import com.willfp.eco.core.items.TestableItem
import com.willfp.eco.core.items.isEmpty import com.willfp.eco.core.items.isEcoEmpty
import com.willfp.eco.core.recipe.Recipes import com.willfp.eco.core.recipe.Recipes
import com.willfp.eco.core.recipe.parts.GroupedTestableItems import com.willfp.eco.core.recipe.parts.GroupedTestableItems
import com.willfp.eco.core.recipe.parts.TestableStack import com.willfp.eco.core.recipe.parts.TestableStack
@@ -33,7 +33,7 @@ class StackedRecipeListener(
} }
// Just in case // Just in case
if (inventory.getItem(event.slot).isEmpty) { if (inventory.getItem(event.slot).isEcoEmpty) {
return return
} }

View File

@@ -96,6 +96,11 @@ use-immediate-placeholder-translation-for-math: false
# less reactive values. # less reactive values.
math-cache-ttl: 200 math-cache-ttl: 200
# The time (in minutes) for literal patterns to be cached for. Higher values will lead to
# faster evaluation times (less CPU usage) at the expense of slightly more memory usage and
# less reactive values. (Do not change unless you are told to).
literal-cache-ttl: 1
# If anonymous usage statistics should be tracked. This is very valuable information as it # If anonymous usage statistics should be tracked. This is very valuable information as it
# helps understand how eco and other plugins are being used by logging player and server # helps understand how eco and other plugins are being used by logging player and server
# counts. This is completely anonymous and no personal information is logged. This data # counts. This is completely anonymous and no personal information is logged. This data

View File

@@ -2,6 +2,7 @@ multiple-in-craft: '&l&c! &fThis recipe requires &a%amount%&f of this item.'
# Specify default display names for prices made through ConfiguredPrice#create # Specify default display names for prices made through ConfiguredPrice#create
# These will override any custom configured price display names. # These will override any custom configured price display names.
# You can use %value% and %value_commas% as placeholders.
price-display: price-display:
- type: example_type - type: example_type
display: "&e%value% Price" display: "&e%value% Price"

View File

@@ -13,7 +13,15 @@ loadbefore:
- Lands - Lands
- EconomyShopGUI - EconomyShopGUI
- EconomyShopGUI-Premium - EconomyShopGUI-Premium
- CMI
- DeluxeCombat
- SCore
- ExecutableItems
softdepend: softdepend:
- ItemBridge
- HuskClaims
- HuskTowns
- Terra
- ProtocolLib - ProtocolLib
- WorldGuard - WorldGuard
- GriefPrevention - GriefPrevention
@@ -35,18 +43,15 @@ softdepend:
- Alice - Alice
- HolographicDisplays - HolographicDisplays
- GHolo - GHolo
- CMI
- Essentials - Essentials
- Vault - Vault
- BentoBox - BentoBox
- DeluxeCombat
- IridiumSkyblock - IridiumSkyblock
- SuperiorSkyblock2 - SuperiorSkyblock2
- FabledSkyBlock - FabledSkyBlock
- CrashClaim - CrashClaim
- DecentHolograms - DecentHolograms
- MythicMobs - MythicMobs
- ExecutableItems
- RPGHorses - RPGHorses
- zShop - zShop
- DeluxeSellwands - DeluxeSellwands

View File

@@ -1,2 +1,2 @@
version = 6.68.1 version = 6.69.0
kotlin.incremental.useClasspathSnapshot=false kotlin.incremental.useClasspathSnapshot=false

BIN
lib/fabledskyblock3.jar Normal file

Binary file not shown.