Compare commits

...

9 Commits

Author SHA1 Message Date
Auxilor
2e6463aed9 Fixed global placeholders 2022-01-17 11:15:18 +00:00
Auxilor
2501574eeb Updated to 6.20.0 2022-01-17 11:12:58 +00:00
Auxilor
3c237fd856 Codestyle 2022-01-17 11:12:45 +00:00
Auxilor
7b3fd1d0c2 Moved placeholders to be registered per-plugin 2022-01-17 11:11:46 +00:00
Auxilor
e599add6de Removed arg parsers that were marked for removal several versions ago 2022-01-12 16:27:43 +00:00
Auxilor
1bda970f6b Improved Items performance 2022-01-12 16:17:49 +00:00
Auxilor
eb1f694905 Added item-cache-ttl 2022-01-12 16:14:24 +00:00
Auxilor
efd3403eda Updated to 6.19.1 2022-01-12 16:02:14 +00:00
Auxilor
08b563d528 Improved Items#getCustomItem and Items#isCustomItem performance 2022-01-12 15:59:25 +00:00
13 changed files with 143 additions and 168 deletions

View File

@@ -53,15 +53,6 @@ public class PersistentDataKey<T> {
+ '}'; + '}';
} }
/**
* Get all persistent data keys.
*
* @return The keys.
*/
public static Set<PersistentDataKey<?>> values() {
return Eco.getHandler().getKeyRegistry().getRegisteredKeys();
}
/** /**
* Get the key. * Get the key.
* *
@@ -88,4 +79,13 @@ public class PersistentDataKey<T> {
public PersistentDataKeyType getType() { public PersistentDataKeyType getType() {
return this.type; return this.type;
} }
/**
* Get all persistent data keys.
*
* @return The keys.
*/
public static Set<PersistentDataKey<?>> values() {
return Eco.getHandler().getKeyRegistry().getRegisteredKeys();
}
} }

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.integrations.placeholder; package com.willfp.eco.core.integrations.placeholder;
import com.willfp.eco.core.EcoPlugin;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -28,12 +29,20 @@ public class PlaceholderEntry {
*/ */
private final boolean requiresPlayer; private final boolean requiresPlayer;
/**
* The plugin for the placeholder.
*/
@Nullable
private final EcoPlugin plugin;
/** /**
* Create a placeholder entry that doesn't require a player. * Create a placeholder entry that doesn't require a player.
* *
* @param identifier The identifier of the placeholder. * @param identifier The identifier of the placeholder.
* @param function A lambda to get the result of the placeholder given a player. * @param function A lambda to get the result of the placeholder given a player.
* @deprecated Specify a plugin.
*/ */
@Deprecated
public PlaceholderEntry(@NotNull final String identifier, public PlaceholderEntry(@NotNull final String identifier,
@NotNull final Function<Player, String> function) { @NotNull final Function<Player, String> function) {
this(identifier, function, false); this(identifier, function, false);
@@ -45,10 +54,41 @@ public class PlaceholderEntry {
* @param identifier The identifier of the placeholder. * @param identifier The identifier of the placeholder.
* @param function A lambda to get the result of the placeholder. * @param function A lambda to get the result of the placeholder.
* @param requiresPlayer If the placeholder requires a player. * @param requiresPlayer If the placeholder requires a player.
* @deprecated Specify a plugin.
*/ */
@Deprecated
public PlaceholderEntry(@NotNull final String identifier, public PlaceholderEntry(@NotNull final String identifier,
@NotNull final Function<Player, String> function, @NotNull final Function<Player, String> function,
final boolean requiresPlayer) { final boolean requiresPlayer) {
this(null, identifier, function, requiresPlayer);
}
/**
* Create a placeholder entry that doesn't require a player.
*
* @param plugin The plugin for the placeholder.
* @param identifier The identifier of the placeholder.
* @param function A lambda to get the result of the placeholder given a player.
*/
public PlaceholderEntry(@Nullable final EcoPlugin plugin,
@NotNull final String identifier,
@NotNull final Function<Player, String> function) {
this(plugin, identifier, function, false);
}
/**
* Create a placeholder entry that may require a player.
*
* @param plugin The plugin for the placeholder.
* @param identifier The identifier of the placeholder.
* @param function A lambda to get the result of the placeholder.
* @param requiresPlayer If the placeholder requires a player.
*/
public PlaceholderEntry(@Nullable final EcoPlugin plugin,
@NotNull final String identifier,
@NotNull final Function<Player, String> function,
final boolean requiresPlayer) {
this.plugin = plugin;
this.identifier = identifier; this.identifier = identifier;
this.function = function; this.function = function;
this.requiresPlayer = requiresPlayer; this.requiresPlayer = requiresPlayer;
@@ -85,6 +125,16 @@ public class PlaceholderEntry {
return identifier; return identifier;
} }
/**
* Get the plugin.
*
* @return The plugin.
*/
@Nullable
public EcoPlugin getPlugin() {
return plugin;
}
/** /**
* Register the placeholder. * Register the placeholder.
*/ */

View File

@@ -1,5 +1,7 @@
package com.willfp.eco.core.integrations.placeholder; package com.willfp.eco.core.integrations.placeholder;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -18,7 +20,7 @@ public final class PlaceholderManager {
/** /**
* All registered placeholders. * All registered placeholders.
*/ */
private static final Map<String, PlaceholderEntry> REGISTERED_PLACEHOLDERS = new HashMap<>(); private static final Map<EcoPlugin, Map<String, PlaceholderEntry>> REGISTERED_PLACEHOLDERS = new HashMap<>();
/** /**
* All registered placeholder integrations. * All registered placeholder integrations.
@@ -41,8 +43,11 @@ public final class PlaceholderManager {
* @param expansion The {@link PlaceholderEntry} to register. * @param expansion The {@link PlaceholderEntry} to register.
*/ */
public static void registerPlaceholder(@NotNull final PlaceholderEntry expansion) { public static void registerPlaceholder(@NotNull final PlaceholderEntry expansion) {
REGISTERED_PLACEHOLDERS.remove(expansion.getIdentifier()); EcoPlugin plugin = expansion.getPlugin() == null ? Eco.getHandler().getEcoPlugin() : expansion.getPlugin();
REGISTERED_PLACEHOLDERS.put(expansion.getIdentifier(), expansion); Map<String, PlaceholderEntry> pluginPlaceholders = REGISTERED_PLACEHOLDERS
.getOrDefault(plugin, new HashMap<>());
pluginPlaceholders.put(expansion.getIdentifier(), expansion);
REGISTERED_PLACEHOLDERS.put(plugin, pluginPlaceholders);
} }
/** /**
@@ -51,10 +56,36 @@ public final class PlaceholderManager {
* @param player The player to get the result from. * @param player The player to get the result from.
* @param identifier The placeholder identifier. * @param identifier The placeholder identifier.
* @return The value of the placeholder. * @return The value of the placeholder.
* @deprecated Specify a plugin to get the result from.
*/ */
@Deprecated
public static String getResult(@Nullable final Player player, public static String getResult(@Nullable final Player player,
@NotNull final String identifier) { @NotNull final String identifier) {
PlaceholderEntry entry = REGISTERED_PLACEHOLDERS.get(identifier.toLowerCase()); return getResult(player, identifier, null);
}
/**
* Get the result of a placeholder with respect to a player.
*
* @param player The player to get the result from.
* @param identifier The placeholder identifier.
* @param plugin The plugin for the placeholder.
* @return The value of the placeholder.
*/
public static String getResult(@Nullable final Player player,
@NotNull final String identifier,
@Nullable final EcoPlugin plugin) {
EcoPlugin owner = player == null ? Eco.getHandler().getEcoPlugin() : plugin;
PlaceholderEntry entry = REGISTERED_PLACEHOLDERS.getOrDefault(owner, new HashMap<>()).get(identifier.toLowerCase());
if (entry == null && plugin != null) {
PlaceholderEntry alternate = REGISTERED_PLACEHOLDERS.getOrDefault(Eco.getHandler().getEcoPlugin(), new HashMap<>())
.get(identifier.toLowerCase());
if (alternate != null) {
entry = alternate;
}
}
if (entry == null) { if (entry == null) {
return ""; return "";
} }

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.items; package com.willfp.eco.core.items;
import com.willfp.eco.core.fast.FastItemStack;
import com.willfp.eco.core.items.args.LookupArgParser; import com.willfp.eco.core.items.args.LookupArgParser;
import com.willfp.eco.core.items.provider.ItemProvider; import com.willfp.eco.core.items.provider.ItemProvider;
import com.willfp.eco.core.recipe.parts.EmptyTestableItem; import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
@@ -13,6 +14,7 @@ import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -34,6 +36,11 @@ public final class Items {
*/ */
private static final Map<NamespacedKey, TestableItem> REGISTRY = new ConcurrentHashMap<>(); private static final Map<NamespacedKey, TestableItem> REGISTRY = new ConcurrentHashMap<>();
/**
* Cached custom item lookups, using {@link FastItemStack#hashCode()}.
*/
private static final Map<Integer, TestableItem> CACHE = new ConcurrentHashMap<>();
/** /**
* All item providers. * All item providers.
*/ */
@@ -276,12 +283,7 @@ public final class Items {
* @return If is recipe. * @return If is recipe.
*/ */
public static boolean isCustomItem(@NotNull final ItemStack itemStack) { public static boolean isCustomItem(@NotNull final ItemStack itemStack) {
for (TestableItem item : REGISTRY.values()) { return getCustomItem(itemStack) != null;
if (item.matches(itemStack)) {
return true;
}
}
return false;
} }
/** /**
@@ -292,12 +294,30 @@ public final class Items {
*/ */
@Nullable @Nullable
public static CustomItem getCustomItem(@NotNull final ItemStack itemStack) { public static CustomItem getCustomItem(@NotNull final ItemStack itemStack) {
int hash = FastItemStack.wrap(itemStack).hashCode();
TestableItem cached = CACHE.get(hash);
if (cached != null) {
return getOrWrap(cached);
} else {
CACHE.remove(hash);
}
TestableItem match = null;
for (TestableItem item : REGISTRY.values()) { for (TestableItem item : REGISTRY.values()) {
if (item.matches(itemStack)) { if (item.matches(itemStack)) {
return getOrWrap(item); match = item;
break;
} }
} }
return null;
if (match == null) {
return null;
}
CACHE.put(hash, match);
return getOrWrap(match);
} }
/** /**
@@ -331,6 +351,14 @@ public final class Items {
} }
} }
/**
* Clear the lookup cache.
*/
@ApiStatus.Internal
public static void clearCache() {
CACHE.clear();
}
private Items() { private Items() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }

View File

@@ -1,36 +0,0 @@
package com.willfp.eco.core.items.args;
import org.bukkit.Bukkit;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Predicate;
/**
* Parse leather armor colors.
*
* @deprecated Moved to internals.
*/
@Deprecated(since = "6.16.0", forRemoval = true)
@ApiStatus.ScheduledForRemoval(inVersion = "6.18.2")
public class ColorArgParser implements LookupArgParser {
/**
* Instantiate arg parser.
*/
public ColorArgParser() {
Bukkit.getLogger().severe("Instantiation of class marked for removal! (" + this.getClass().getName() + "), this will throw an error in a future release!");
}
@Override
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
@NotNull final ItemMeta meta) {
return null;
}
static {
Bukkit.getLogger().severe("Referencing a class marked for removal! (" + ColorArgParser.class.getName() + "), this will throw an error in the next release!");
}
}

View File

@@ -1,36 +0,0 @@
package com.willfp.eco.core.items.args;
import org.bukkit.Bukkit;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Predicate;
/**
* Parse custom model data.
*
* @deprecated Moved to internals.
*/
@Deprecated(since = "6.16.0", forRemoval = true)
@ApiStatus.ScheduledForRemoval(inVersion = "6.18.2")
public class CustomModelDataArgParser implements LookupArgParser {
/**
* Instantiate arg parser.
*/
public CustomModelDataArgParser() {
Bukkit.getLogger().severe("Instantiation of class marked for removal! (" + this.getClass().getName() + "), this will throw an error in a future release!");
}
@Override
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
@NotNull final ItemMeta meta) {
return null;
}
static {
Bukkit.getLogger().severe("Referencing a class marked for removal! (" + CustomModelDataArgParser.class.getName() + "), this will throw an error in the next release!");
}
}

View File

@@ -1,36 +0,0 @@
package com.willfp.eco.core.items.args;
import org.bukkit.Bukkit;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Predicate;
/**
* Parses enchantment arguments.
*
* @deprecated Moved to internals.
*/
@Deprecated(since = "6.16.0", forRemoval = true)
@ApiStatus.ScheduledForRemoval(inVersion = "6.18.2")
public class EnchantmentArgParser implements LookupArgParser {
/**
* Instantiate arg parser.
*/
public EnchantmentArgParser() {
Bukkit.getLogger().severe("Instantiation of class marked for removal! (" + this.getClass().getName() + "), this will throw an error in a future release!");
}
@Override
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
@NotNull final ItemMeta meta) {
return null;
}
static {
Bukkit.getLogger().severe("Referencing a class marked for removal! (" + EnchantmentArgParser.class.getName() + "), this will throw an error in the next release!");
}
}

View File

@@ -1,36 +0,0 @@
package com.willfp.eco.core.items.args;
import org.bukkit.Bukkit;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Predicate;
/**
* Parse skull textures.
*
* @deprecated Moved to internals.
*/
@Deprecated(since = "6.16.0", forRemoval = true)
@ApiStatus.ScheduledForRemoval(inVersion = "6.18.2")
public class TextureArgParser implements LookupArgParser {
/**
* Instantiate arg parser.
*/
public TextureArgParser() {
Bukkit.getLogger().severe("Instantiation of class marked for removal! (" + this.getClass().getName() + "), this will throw an error in a future release!");
}
@Override
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
@NotNull final ItemMeta meta) {
return null;
}
static {
Bukkit.getLogger().severe("Referencing a class marked for removal! (" + TextureArgParser.class.getName() + "), this will throw an error in the next release!");
}
}

View File

@@ -32,7 +32,7 @@ class PlaceholderIntegrationPAPI(private val plugin: EcoPlugin) : PlaceholderExp
player: Player?, player: Player?,
identifier: String identifier: String
): String { ): String {
return PlaceholderManager.getResult(player, identifier) return PlaceholderManager.getResult(player, identifier, plugin)
} }
override fun registerIntegration() { override fun registerIntegration() {

View File

@@ -190,6 +190,11 @@ abstract class EcoSpigotPlugin : EcoPlugin(
CollatedRunnable(this) CollatedRunnable(this)
DropManager.update(this) DropManager.update(this)
ProfileSaver(this) ProfileSaver(this)
this.scheduler.runTimer(
{ Items.clearCache() },
this.configYml.getInt("item-cache-ttl").toLong(),
this.configYml.getInt("item-cache-ttl").toLong()
)
this.scheduler.runTimer( this.scheduler.runTimer(
{ clearFrames() }, { clearFrames() },
this.configYml.getInt("display-frame-ttl").toLong(), this.configYml.getInt("display-frame-ttl").toLong(),

View File

@@ -12,7 +12,7 @@ private val goToZero = Crunch.compileExpression("0")
fun evaluateExpression(expression: String, player: Player?): Double { fun evaluateExpression(expression: String, player: Player?): Double {
val placeholderValues = PlaceholderManager.findPlaceholdersIn(expression) val placeholderValues = PlaceholderManager.findPlaceholdersIn(expression)
.map { PlaceholderManager.getResult(player, expression) } .map { PlaceholderManager.translatePlaceholders(expression, player) }
.map { runCatching { FastNumberParsing.parseDouble(it) }.getOrDefault(0.0) } .map { runCatching { FastNumberParsing.parseDouble(it) }.getOrDefault(0.0) }
.toDoubleArray() .toDoubleArray()

View File

@@ -41,6 +41,11 @@ use-display-frame: true
# that display frames will be cleared / deleted. # that display frames will be cleared / deleted.
display-frame-ttl: 17 display-frame-ttl: 17
# Time to live for storing hashes against custom item keys. Increasing this value
# can benefit performance under load (e.g. from ShopGUI+ sells) but can increase
# memory use.
item-cache-ttl: 6000
# Window items packets have the option to be run asynchronously. This may cause # Window items packets have the option to be run asynchronously. This may cause
# some bugs and is considered experimental, however it has been tested without # some bugs and is considered experimental, however it has been tested without
# any apparent issues. Enable this if performance is absolutely crucial or if you # any apparent issues. Enable this if performance is absolutely crucial or if you

View File

@@ -1,3 +1,3 @@
version = 6.19.0 version = 6.20.0
plugin-name = eco plugin-name = eco
kotlin.code.style = official kotlin.code.style = official