Updated Placeholder API, added ability to parse placeholders without PAPI installed
This commit is contained in:
@@ -3,7 +3,6 @@ package com.willfp.eco.core.integrations.placeholder;
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.placeholder.AdditionalPlayer;
|
||||
import com.willfp.eco.core.placeholder.DynamicPlaceholder;
|
||||
@@ -16,6 +15,7 @@ import com.willfp.eco.core.placeholder.PlayerStaticPlaceholder;
|
||||
import com.willfp.eco.core.placeholder.PlayerlessPlaceholder;
|
||||
import com.willfp.eco.core.placeholder.StaticPlaceholder;
|
||||
import com.willfp.eco.util.StringUtils;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -110,14 +110,12 @@ public final class PlaceholderManager {
|
||||
throw new IllegalArgumentException("Static placeholders cannot be registered!");
|
||||
}
|
||||
|
||||
EcoPlugin plugin = placeholder.getPlugin() == null ? Eco.get().getEcoPlugin() : placeholder.getPlugin();
|
||||
|
||||
Map<Pattern, Placeholder> pluginPlaceholders = REGISTERED_PLACEHOLDERS
|
||||
.getOrDefault(plugin, new HashMap<>());
|
||||
.getOrDefault(placeholder.getPlugin(), new HashMap<>());
|
||||
|
||||
pluginPlaceholders.put(placeholder.getPattern(), placeholder);
|
||||
|
||||
REGISTERED_PLACEHOLDERS.put(plugin, pluginPlaceholders);
|
||||
REGISTERED_PLACEHOLDERS.put(placeholder.getPlugin(), pluginPlaceholders);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,10 +137,11 @@ public final class PlaceholderManager {
|
||||
* @return The value of the placeholder.
|
||||
* @deprecated Specify a plugin to get the result from.
|
||||
*/
|
||||
@Deprecated
|
||||
@Deprecated(forRemoval = true)
|
||||
@SuppressWarnings("unused")
|
||||
public static String getResult(@Nullable final Player player,
|
||||
@NotNull final String identifier) {
|
||||
return getResult(player, identifier, null);
|
||||
throw new UnsupportedOperationException("Please specify a plugin to get the result from!");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,34 +155,21 @@ public final class PlaceholderManager {
|
||||
@NotNull
|
||||
public static String getResult(@Nullable final Player player,
|
||||
@NotNull final String identifier,
|
||||
@Nullable final EcoPlugin plugin) {
|
||||
@NotNull final EcoPlugin plugin) {
|
||||
Validate.notNull(plugin, "Plugin cannot be null!");
|
||||
|
||||
// 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(identifier, plugin),
|
||||
(it) -> {
|
||||
EcoPlugin owner = plugin == null ? Eco.get().getEcoPlugin() : plugin;
|
||||
|
||||
// I hate the streams API.
|
||||
Optional<Placeholder> found = REGISTERED_PLACEHOLDERS
|
||||
.getOrDefault(owner, new HashMap<>())
|
||||
return REGISTERED_PLACEHOLDERS
|
||||
.getOrDefault(plugin, new HashMap<>())
|
||||
.entrySet()
|
||||
.stream().filter(entry -> entry.getKey().matcher(identifier).matches())
|
||||
.map(Map.Entry::getValue)
|
||||
.findFirst();
|
||||
|
||||
if (found.isEmpty() && plugin != null) {
|
||||
// Here we go again! Something about legacy support? I don't remember.
|
||||
// I won't touch it though, I'm scared of the placeholder system.
|
||||
found = REGISTERED_PLACEHOLDERS
|
||||
.getOrDefault(Eco.get().getEcoPlugin(), new HashMap<>())
|
||||
.entrySet()
|
||||
.stream().filter(entry -> entry.getKey().matcher(identifier).matches())
|
||||
.map(Map.Entry::getValue)
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
).orElse(null);
|
||||
|
||||
@@ -326,6 +312,11 @@ public final class PlaceholderManager {
|
||||
}
|
||||
}
|
||||
|
||||
// Only run jank code if there are no integrations.
|
||||
if (REGISTERED_INTEGRATIONS.isEmpty()) {
|
||||
processed = setWithoutIntegration(processed, player);
|
||||
}
|
||||
|
||||
for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) {
|
||||
processed = integration.translate(processed, player);
|
||||
}
|
||||
@@ -350,12 +341,9 @@ public final class PlaceholderManager {
|
||||
public static List<String> findPlaceholdersIn(@NotNull final String text) {
|
||||
Set<String> found = new HashSet<>();
|
||||
|
||||
// Mock PAPI for those without it installed
|
||||
if (REGISTERED_INTEGRATIONS.isEmpty()) {
|
||||
Matcher matcher = PATTERN.matcher(text);
|
||||
while (matcher.find()) {
|
||||
found.add(matcher.group());
|
||||
}
|
||||
Matcher matcher = PATTERN.matcher(text);
|
||||
while (matcher.find()) {
|
||||
found.add(matcher.group());
|
||||
}
|
||||
|
||||
for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) {
|
||||
@@ -365,6 +353,95 @@ public final class PlaceholderManager {
|
||||
return new ArrayList<>(found);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set placeholders without any integrations.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* Original source
|
||||
* <a href="https://github.com/PlaceholderAPI/PlaceholderAPI/blob/master/src/main/java/me/clip/placeholderapi/replacer/CharsReplacer.java">here</a>.
|
||||
*
|
||||
* @param text The text.
|
||||
* @param player The player.
|
||||
* @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();
|
||||
|
||||
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 (true) {
|
||||
i++;
|
||||
if (i >= chars.length) {
|
||||
break;
|
||||
}
|
||||
|
||||
char p = chars[i];
|
||||
if (p == ' ' && !identified) {
|
||||
hadSpace = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (p == '%') {
|
||||
badPlaceholder = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (p == '_' && !identified) {
|
||||
identified = true;
|
||||
} else if (identified) {
|
||||
parameters.append(p);
|
||||
} else {
|
||||
identifier.append(p);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private record PlaceholderLookup(@NotNull String identifier,
|
||||
@Nullable EcoPlugin plugin) {
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.willfp.eco.core.placeholder;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -16,7 +15,7 @@ public sealed interface Placeholder permits PlayerPlaceholder, PlayerlessPlaceho
|
||||
*
|
||||
* @return The plugin.
|
||||
*/
|
||||
@Nullable
|
||||
@NotNull
|
||||
EcoPlugin getPlugin();
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user