Add compatibility format for placeholders registered with API v2

This commit is contained in:
filoghost 2022-01-21 22:22:58 +01:00
parent 4a8fd6a6fa
commit 58907f075f
5 changed files with 115 additions and 16 deletions

View File

@ -10,8 +10,8 @@ import com.gmail.filoghost.holographicdisplays.api.internal.HologramsAPIProvider
import com.gmail.filoghost.holographicdisplays.api.placeholder.PlaceholderReplacer;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.fcommons.collection.CollectionUtils;
import me.filoghost.holographicdisplays.api.beta.placeholder.RegisteredPlaceholder;
import me.filoghost.holographicdisplays.plugin.hologram.base.ImmutablePosition;
import me.filoghost.holographicdisplays.plugin.placeholder.registry.LegacyGlobalPlaceholderExpansion;
import me.filoghost.holographicdisplays.plugin.placeholder.registry.PlaceholderRegistry;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
@ -65,10 +65,10 @@ public class V2HologramsAPIProvider extends HologramsAPIProvider {
Preconditions.notNull(replacer, "replacer");
int refreshIntervalTicks = Math.min((int) (refreshRate * 20.0), 1);
boolean alreadyRegistered = placeholderRegistry.isRegisteredIdentifier(plugin, textPlaceholder);
boolean alreadyRegistered = placeholderRegistry.isRegisteredLegacyPlaceholder(plugin, textPlaceholder);
if (!alreadyRegistered) {
placeholderRegistry.registerGlobalPlaceholder(
placeholderRegistry.registerLegacyPlaceholder(
plugin,
textPlaceholder,
refreshIntervalTicks,
@ -83,8 +83,9 @@ public class V2HologramsAPIProvider extends HologramsAPIProvider {
public Collection<String> getRegisteredPlaceholders(Plugin plugin) {
Preconditions.notNull(plugin, "plugin");
List<RegisteredPlaceholder> registeredPlaceholders = placeholderRegistry.getRegisteredPlaceholders(plugin);
return CollectionUtils.toArrayList(registeredPlaceholders, RegisteredPlaceholder::getIdentifier);
return CollectionUtils.toArrayList(
placeholderRegistry.getRegisteredLegacyPlaceholders(plugin),
LegacyGlobalPlaceholderExpansion::getTextPlaceholder);
}
@Override
@ -92,10 +93,10 @@ public class V2HologramsAPIProvider extends HologramsAPIProvider {
Preconditions.notNull(plugin, "plugin");
Preconditions.notNull(textPlaceholder, "textPlaceholder");
boolean registered = placeholderRegistry.isRegisteredIdentifier(plugin, textPlaceholder);
boolean registered = placeholderRegistry.isRegisteredLegacyPlaceholder(plugin, textPlaceholder);
if (registered) {
placeholderRegistry.unregister(plugin, textPlaceholder);
placeholderRegistry.unregisterLegacyPlaceholder(plugin, textPlaceholder);
return true;
} else {
return false;
@ -106,7 +107,7 @@ public class V2HologramsAPIProvider extends HologramsAPIProvider {
public void unregisterPlaceholders(Plugin plugin) {
Preconditions.notNull(plugin, "plugin");
placeholderRegistry.unregisterAll(plugin);
placeholderRegistry.unregisterAllLegacyPlaceholders(plugin);
}
@Override

View File

@ -6,6 +6,7 @@
package me.filoghost.holographicdisplays.plugin.placeholder;
import me.filoghost.fcommons.Strings;
import me.filoghost.fcommons.collection.CaseInsensitiveString;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -13,7 +14,7 @@ import java.util.Objects;
public class PlaceholderOccurrence {
private final String unparsedContent;
private final CaseInsensitiveString unparsedContent;
private final PluginName pluginName;
private final PlaceholderIdentifier identifier;
private final String argument;
@ -21,14 +22,14 @@ public class PlaceholderOccurrence {
private final int hashCode; // Cached for performance reasons
private PlaceholderOccurrence(String unparsedContent, PluginName pluginName, PlaceholderIdentifier identifier, String argument) {
this.unparsedContent = unparsedContent;
this.unparsedContent = new CaseInsensitiveString(unparsedContent);
this.pluginName = pluginName;
this.identifier = identifier;
this.argument = argument;
this.hashCode = Objects.hash(pluginName, identifier, argument);
}
public String getUnparsedContent() {
public CaseInsensitiveString getUnparsedContent() {
return unparsedContent;
}

View File

@ -0,0 +1,28 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.plugin.placeholder.registry;
import me.filoghost.holographicdisplays.api.beta.placeholder.GlobalPlaceholderFactory;
import org.bukkit.plugin.Plugin;
public class LegacyGlobalPlaceholderExpansion extends GlobalPlaceholderExpansion {
private final String textPlaceholder;
LegacyGlobalPlaceholderExpansion(
Plugin plugin,
String identifier,
GlobalPlaceholderFactory placeholderFactory,
String textPlaceholder) {
super(plugin, identifier, placeholderFactory);
this.textPlaceholder = textPlaceholder;
}
public String getTextPlaceholder() {
return textPlaceholder;
}
}

View File

@ -8,6 +8,8 @@ package me.filoghost.holographicdisplays.plugin.placeholder.registry;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Iterables;
import com.google.common.collect.Table;
import me.filoghost.fcommons.collection.CaseInsensitiveString;
import me.filoghost.fcommons.logging.Log;
import me.filoghost.holographicdisplays.api.beta.placeholder.GlobalPlaceholder;
import me.filoghost.holographicdisplays.api.beta.placeholder.GlobalPlaceholderFactory;
import me.filoghost.holographicdisplays.api.beta.placeholder.GlobalPlaceholderReplacementSupplier;
@ -22,16 +24,19 @@ import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
public class PlaceholderRegistry {
private final Table<PlaceholderIdentifier, PluginName, PlaceholderExpansion> placeholderExpansions;
private final Table<CaseInsensitiveString, PluginName, LegacyGlobalPlaceholderExpansion> legacyPlaceholderExpansions;
private final AtomicLong version;
public PlaceholderRegistry() {
this.placeholderExpansions = HashBasedTable.create();
this.legacyPlaceholderExpansions = HashBasedTable.create();
this.version = new AtomicLong();
}
@ -88,15 +93,20 @@ public class PlaceholderRegistry {
public @Nullable PlaceholderExpansion find(PlaceholderOccurrence textOccurrence) {
PluginName pluginName = textOccurrence.getPluginName();
PlaceholderIdentifier identifier = textOccurrence.getIdentifier();
PlaceholderExpansion result;
if (pluginName != null) {
// Find exact entry if plugin name is specified
return placeholderExpansions.get(identifier, pluginName);
result = placeholderExpansions.get(identifier, pluginName);
} else {
// Otherwise find any match with the given identifier
return Iterables.getFirst(placeholderExpansions.row(identifier).values(), null);
result = Iterables.getFirst(placeholderExpansions.row(identifier).values(), null);
}
if (result == null && !legacyPlaceholderExpansions.isEmpty()) {
result = Iterables.getFirst(legacyPlaceholderExpansions.row(textOccurrence.getUnparsedContent()).values(), null);
}
return result;
}
public List<RegisteredPlaceholder> getRegisteredPlaceholders(Plugin plugin) {
@ -109,4 +119,62 @@ public class PlaceholderRegistry {
return placeholderExpansions.contains(new PlaceholderIdentifier(identifier), new PluginName(plugin));
}
public void registerLegacyPlaceholder(
Plugin plugin,
String textPlaceholder,
int refreshIntervalTicks,
GlobalPlaceholderReplacementSupplier replacementSupplier) {
String identifier = convertToNewFormat(textPlaceholder);
if (!identifier.equals(textPlaceholder)) {
Log.warning("The plugin " + plugin.getName() + " registered the placeholder " + textPlaceholder
+ " with the old v2 API, but it doesn't comply with the new format. In order to display it,"
+ " you must use {" + textPlaceholder + "} instead.");
}
GlobalPlaceholder placeholder = new SimpleGlobalPlaceholder(refreshIntervalTicks, replacementSupplier);
GlobalPlaceholderFactory placeholderFactory = (String argument) -> placeholder;
LegacyGlobalPlaceholderExpansion expansion = new LegacyGlobalPlaceholderExpansion(
plugin,
identifier,
placeholderFactory,
textPlaceholder);
legacyPlaceholderExpansions.put(new CaseInsensitiveString(identifier), new PluginName(plugin), expansion);
version.incrementAndGet();
}
public void unregisterLegacyPlaceholder(Plugin plugin, String textPlaceholder) {
String identifier = convertToNewFormat(textPlaceholder);
legacyPlaceholderExpansions.remove(new CaseInsensitiveString(identifier), new PluginName(plugin));
version.incrementAndGet();
}
public void unregisterAllLegacyPlaceholders(Plugin plugin) {
legacyPlaceholderExpansions.column(new PluginName(plugin)).clear();
version.incrementAndGet();
}
public boolean isRegisteredLegacyPlaceholder(Plugin plugin, String textPlaceholder) {
String identifier = convertToNewFormat(textPlaceholder);
return legacyPlaceholderExpansions.contains(new CaseInsensitiveString(identifier), new PluginName(plugin));
}
public Collection<LegacyGlobalPlaceholderExpansion> getRegisteredLegacyPlaceholders(Plugin plugin) {
return legacyPlaceholderExpansions.column(new PluginName(plugin)).values();
}
private String convertToNewFormat(String textPlaceholder) {
String identifier;
if (textPlaceholder.startsWith("{") && textPlaceholder.endsWith("}")) {
// The placeholder already had the correct format, remove the curly braces
identifier = textPlaceholder.substring(1, textPlaceholder.length() - 1);
} else {
// The placeholder will be wrapped with curly braces to partially maintain compatibility
identifier = textPlaceholder;
}
return identifier;
}
}

View File

@ -5,6 +5,7 @@
*/
package me.filoghost.holographicdisplays.plugin.placeholder.tracking;
import me.filoghost.fcommons.collection.CaseInsensitiveString;
import me.filoghost.fcommons.logging.Log;
import me.filoghost.holographicdisplays.plugin.placeholder.PlaceholderException;
import me.filoghost.holographicdisplays.plugin.placeholder.PlaceholderOccurrence;
@ -16,7 +17,7 @@ import java.util.WeakHashMap;
class PlaceholderExceptionHandler {
private final TickClock tickClock;
private final Map<String, Long> lastErrorLogByPlaceholderContent;
private final Map<CaseInsensitiveString, Long> lastErrorLogByPlaceholderContent;
PlaceholderExceptionHandler(TickClock tickClock) {
this.tickClock = tickClock;
@ -24,7 +25,7 @@ class PlaceholderExceptionHandler {
}
void handle(PlaceholderException exception, PlaceholderOccurrence placeholderOccurrence) {
String unparsedContent = placeholderOccurrence.getUnparsedContent();
CaseInsensitiveString unparsedContent = placeholderOccurrence.getUnparsedContent();
Long lastErrorLog = lastErrorLogByPlaceholderContent.get(unparsedContent);
long currentTick = tickClock.getCurrentTick();