Initial refactoring for relative placeholders

This commit is contained in:
filoghost 2021-05-26 23:29:08 +02:00
parent 864f76eac6
commit b2989814b8
10 changed files with 124 additions and 126 deletions

View File

@ -6,9 +6,6 @@
package me.filoghost.holographicdisplays.core.hologram;
import me.filoghost.holographicdisplays.core.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.core.placeholder.RelativePlaceholder;
import java.util.Collection;
public interface StandardTextLine extends StandardTouchableLine {
@ -16,8 +13,6 @@ public interface StandardTextLine extends StandardTouchableLine {
boolean isAllowPlaceholders();
Collection<RelativePlaceholder> getRelativePlaceholders();
NMSArmorStand getNMSArmorStand();
}

View File

@ -1,55 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.core.placeholder;
import org.bukkit.entity.Player;
import java.util.Collection;
import java.util.HashSet;
public class RelativePlaceholder implements RelativePlaceholderReplacer {
private static final Collection<RelativePlaceholder> registry = new HashSet<>();
// The placeholder itself, something like {player}
private final String textPlaceholder;
private final RelativePlaceholderReplacer replacer;
public RelativePlaceholder(String textPlaceholder, RelativePlaceholderReplacer replacer) {
this.textPlaceholder = textPlaceholder;
this.replacer = replacer;
}
public String getTextPlaceholder() {
return textPlaceholder;
}
@Override
public String getReplacement(Player player) {
return replacer.getReplacement(player);
}
public static void register(String textPlaceholder, RelativePlaceholderReplacer replacer) {
for (RelativePlaceholder existingPlaceholder : registry) {
if (existingPlaceholder.getTextPlaceholder().equals(textPlaceholder)) {
throw new IllegalArgumentException("Relative placeholder already registered");
}
}
registry.add(new RelativePlaceholder(textPlaceholder, replacer));
}
public static Collection<RelativePlaceholder> getRegistry() {
return registry;
}
static {
register("{player}", Player::getName);
register("{displayname}", Player::getDisplayName);
}
}

View File

@ -22,18 +22,22 @@ import me.filoghost.holographicdisplays.core.nms.NMSManager;
import me.filoghost.holographicdisplays.core.nms.ProtocolPacketSettings;
import me.filoghost.holographicdisplays.core.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.core.nms.entity.NMSEntity;
import me.filoghost.holographicdisplays.core.placeholder.RelativePlaceholder;
import me.filoghost.holographicdisplays.placeholder.RelativePlaceholder;
import me.filoghost.holographicdisplays.placeholder.PlaceholdersUpdateTask;
import me.filoghost.holographicdisplays.placeholder.TrackedLine;
import me.filoghost.holographicdisplays.placeholder.parsing.StringWithPlaceholders;
import me.filoghost.holographicdisplays.placeholder.registry.PlaceholderRegistry;
import me.filoghost.holographicdisplays.util.NMSVersion;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.Collection;
class PacketListener extends PacketAdapter {
private final NMSManager nmsManager;
private final MetadataHelper metadataHelper;
private final ProtocolPacketSettings packetSettings;
PlaceholdersUpdateTask placeholdersUpdateTask;
PlaceholderRegistry placeholderRegistry;
PacketListener(Plugin plugin, NMSManager nmsManager, MetadataHelper metadataHelper, ProtocolPacketSettings packetSettings) {
super(PacketAdapter.params()
@ -143,18 +147,23 @@ class PacketListener extends PacketAdapter {
}
private String replaceRelativePlaceholders(StandardTextLine textLine, String text, Player player) {
Collection<RelativePlaceholder> relativePlaceholders = textLine.getRelativePlaceholders();
if (relativePlaceholders != null && !relativePlaceholders.isEmpty()) {
for (RelativePlaceholder relativePlaceholder : relativePlaceholders) {
if (text.contains(relativePlaceholder.getTextPlaceholder())) {
text = text.replace(
relativePlaceholder.getTextPlaceholder(),
relativePlaceholder.getReplacement(player));
}
}
TrackedLine trackedLine = placeholdersUpdateTask.getTrackedLine(textLine);
if (trackedLine == null) {
return text;
}
if (trackedLine.containsRelativePlaceholders()) {
StringWithPlaceholders textWithPlaceholders = new StringWithPlaceholders(text);
textWithPlaceholders.replacePlaceholders(placeholderOccurrence -> {
RelativePlaceholder relativePlaceholder = placeholderRegistry.findRelative(placeholderOccurrence);
if (relativePlaceholder != null) {
return relativePlaceholder.getReplacement(player);
} else {
return null;
}
});
}
if (PlaceholderAPIHook.isEnabled() && PlaceholderAPIHook.containsPlaceholders(text)) {
text = PlaceholderAPIHook.replacePlaceholders(player, text);
}

View File

@ -8,24 +8,19 @@ package me.filoghost.holographicdisplays.object.base;
import me.filoghost.holographicdisplays.core.hologram.StandardTextLine;
import me.filoghost.holographicdisplays.core.nms.SpawnFailedException;
import me.filoghost.holographicdisplays.core.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.core.placeholder.RelativePlaceholder;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public abstract class BaseTextLine extends BaseTouchableLine implements StandardTextLine {
private final List<RelativePlaceholder> relativePlaceholders;
private String text;
private NMSArmorStand textEntity;
public BaseTextLine(BaseHologram<?> hologram, String text) {
super(hologram);
this.relativePlaceholders = new ArrayList<>();
setText(text);
}
@ -41,15 +36,6 @@ public abstract class BaseTextLine extends BaseTouchableLine implements Standard
textEntity.setCustomNameNMS(text);
getPlaceholderManager().updateTracking(this);
}
relativePlaceholders.clear();
if (text != null) {
for (RelativePlaceholder relativePlaceholder : RelativePlaceholder.getRegistry()) {
if (text.contains(relativePlaceholder.getTextPlaceholder())) {
relativePlaceholders.add(relativePlaceholder);
}
}
}
}
@Override
@ -84,11 +70,6 @@ public abstract class BaseTextLine extends BaseTouchableLine implements Standard
}
}
@Override
public Collection<RelativePlaceholder> getRelativePlaceholders() {
return relativePlaceholders;
}
@Override
public double getHeight() {
return 0.23;

View File

@ -18,7 +18,7 @@ public class PlaceholderManager {
public PlaceholderManager() {
this.placeholderRegistry = new PlaceholderRegistry();
PlaceholdersReplacementTracker placeholdersReplacementTracker = new PlaceholdersReplacementTracker(placeholderRegistry);
this.placeholdersUpdateTask = new PlaceholdersUpdateTask(placeholdersReplacementTracker);
this.placeholdersUpdateTask = new PlaceholdersUpdateTask(placeholdersReplacementTracker, placeholderRegistry);
placeholderRegistry.setChangeListener(placeholdersReplacementTracker::clearOutdatedSources);
}

View File

@ -11,6 +11,7 @@ import me.filoghost.holographicdisplays.core.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.placeholder.parsing.PlaceholderOccurrence;
import me.filoghost.holographicdisplays.placeholder.parsing.StringWithPlaceholders;
import me.filoghost.holographicdisplays.placeholder.registry.PlaceholderExpansion;
import me.filoghost.holographicdisplays.placeholder.registry.PlaceholderRegistry;
import org.jetbrains.annotations.Nullable;
import java.util.Iterator;
@ -21,13 +22,15 @@ import java.util.WeakHashMap;
public class PlaceholdersUpdateTask implements Runnable {
private final PlaceholdersReplacementTracker placeholdersReplacementTracker;
private final PlaceholderRegistry placeholderRegistry;
private final Map<StandardTextLine, TrackedLine> trackedLines;
private final Map<PlaceholderExpansion, Long> lastErrorLogByPlaceholderExpansion;
private long currentTick;
public PlaceholdersUpdateTask(PlaceholdersReplacementTracker placeholdersReplacementTracker) {
public PlaceholdersUpdateTask(PlaceholdersReplacementTracker placeholdersReplacementTracker, PlaceholderRegistry placeholderRegistry) {
this.placeholdersReplacementTracker = placeholdersReplacementTracker;
this.placeholderRegistry = placeholderRegistry;
this.trackedLines = new LinkedHashMap<>();
this.lastErrorLogByPlaceholderExpansion = new WeakHashMap<>();
}
@ -38,7 +41,7 @@ public class PlaceholdersUpdateTask implements Runnable {
while (iterator.hasNext()) {
TrackedLine trackedLine = iterator.next();
if (trackedLine.entity.isDeadNMS()) {
if (trackedLine.shouldBeUntracked()) {
iterator.remove();
continue;
}
@ -48,6 +51,10 @@ public class PlaceholdersUpdateTask implements Runnable {
currentTick++;
}
public TrackedLine getTrackedLine(StandardTextLine line) {
return trackedLines.get(line);
}
public void updateTracking(StandardTextLine line) {
TrackedLine trackedLine = createTrackedLineIfNeeded(line);
@ -83,10 +90,10 @@ public class PlaceholdersUpdateTask implements Runnable {
return null;
}
return new TrackedLine(textLine, entity, textWithPlaceholders);
return new TrackedLine(this, placeholderRegistry, textLine, entity, textWithPlaceholders);
}
private String getCurrentReplacement(PlaceholderOccurrence placeholderOccurrence) {
protected String getCurrentReplacement(PlaceholderOccurrence placeholderOccurrence) {
try {
return placeholdersReplacementTracker.getOrUpdateReplacement(placeholderOccurrence, currentTick);
} catch (PlaceholderException e) {
@ -110,31 +117,5 @@ public class PlaceholdersUpdateTask implements Runnable {
+ " Please contact the author of " + placeholderExpansion.getPluginName(),
exception.getCause());
}
private class TrackedLine {
final StandardTextLine textLine;
final NMSArmorStand entity;
final StringWithPlaceholders nameWithPlaceholders;
TrackedLine(StandardTextLine textLine, NMSArmorStand entity, StringWithPlaceholders nameWithPlaceholders) {
this.textLine = textLine;
this.entity = entity;
this.nameWithPlaceholders = nameWithPlaceholders;
}
void updateNameWithPlaceholders() {
String newName = nameWithPlaceholders.replacePlaceholders(PlaceholdersUpdateTask.this::getCurrentReplacement);
entity.setCustomNameNMS(newName);
}
void restoreOriginalName() {
if (!entity.isDeadNMS()) {
entity.setCustomNameNMS(textLine.getText());
}
}
}
}

View File

@ -3,11 +3,11 @@
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.core.placeholder;
package me.filoghost.holographicdisplays.placeholder;
import org.bukkit.entity.Player;
public interface RelativePlaceholderReplacer {
public interface RelativePlaceholder {
String getReplacement(Player player);

View File

@ -0,0 +1,52 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.placeholder;
import me.filoghost.holographicdisplays.core.hologram.StandardTextLine;
import me.filoghost.holographicdisplays.core.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.placeholder.parsing.StringWithPlaceholders;
import me.filoghost.holographicdisplays.placeholder.registry.PlaceholderRegistry;
public class TrackedLine {
private final PlaceholdersUpdateTask placeholdersUpdateTask;
private final PlaceholderRegistry placeholderRegistry;
private final StandardTextLine textLine;
private final NMSArmorStand entity;
private final StringWithPlaceholders nameWithPlaceholders;
private final boolean containsRelativePlaceholders;
TrackedLine(PlaceholdersUpdateTask placeholdersUpdateTask, PlaceholderRegistry placeholderRegistry, StandardTextLine textLine, NMSArmorStand entity, StringWithPlaceholders nameWithPlaceholders) {
this.placeholdersUpdateTask = placeholdersUpdateTask;
this.placeholderRegistry = placeholderRegistry;
this.textLine = textLine;
this.entity = entity;
this.nameWithPlaceholders = nameWithPlaceholders;
this.containsRelativePlaceholders = nameWithPlaceholders.containsPlaceholdersMatching(
occurrence -> this.placeholderRegistry.findRelative(occurrence) != null
);
}
void updateNameWithPlaceholders() {
String newName = nameWithPlaceholders.replacePlaceholders(placeholdersUpdateTask::getCurrentReplacement);
entity.setCustomNameNMS(newName);
}
void restoreOriginalName() {
if (!entity.isDeadNMS()) {
entity.setCustomNameNMS(textLine.getText());
}
}
public boolean containsRelativePlaceholders() {
return containsRelativePlaceholders;
}
public boolean shouldBeUntracked() {
return entity.isDeadNMS();
}
}

View File

@ -10,6 +10,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
public class StringWithPlaceholders {
@ -28,6 +29,23 @@ public class StringWithPlaceholders {
return stringParts != null;
}
public boolean containsPlaceholdersMatching(Predicate<PlaceholderOccurrence> filter) {
if (stringParts == null) {
return false;
}
for (StringPart stringPart : stringParts) {
if (stringPart instanceof PlaceholderStringPart) {
PlaceholderStringPart placeholderStringPart = (PlaceholderStringPart) stringPart;
if (filter.test(placeholderStringPart.content)) {
return true;
}
}
}
return false;
}
public String replacePlaceholders(Function<PlaceholderOccurrence, String> replaceFunction) {
if (!containsPlaceholders()) {
return string;

View File

@ -11,27 +11,39 @@ import com.google.common.collect.Table;
import me.filoghost.holographicdisplays.api.placeholder.Placeholder;
import me.filoghost.holographicdisplays.api.placeholder.PlaceholderFactory;
import me.filoghost.holographicdisplays.api.placeholder.PlaceholderReplacer;
import me.filoghost.holographicdisplays.placeholder.RelativePlaceholder;
import me.filoghost.holographicdisplays.placeholder.parsing.PlaceholderIdentifier;
import me.filoghost.holographicdisplays.placeholder.parsing.PlaceholderOccurrence;
import me.filoghost.holographicdisplays.placeholder.parsing.PluginName;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PlaceholderRegistry {
private final Table<PlaceholderIdentifier, PluginName, PlaceholderExpansion> placeholderExpansions;
private final Map<PlaceholderIdentifier, RelativePlaceholder> relativePlaceholders;
private Runnable changeListener;
public PlaceholderRegistry() {
this.placeholderExpansions = HashBasedTable.create();
relativePlaceholders = new HashMap<>();
registerRelative("player", Player::getName);
registerRelative("displayName", Player::getDisplayName);
}
public void setChangeListener(Runnable changeListener) {
this.changeListener = changeListener;
}
public void registerRelative(String identifier, RelativePlaceholder relativePlaceholder) {
relativePlaceholders.put(new PlaceholderIdentifier(identifier), relativePlaceholder);
}
public void registerReplacer(Plugin plugin, String identifier, int refreshIntervalTicks, PlaceholderReplacer placeholderReplacer) {
register(plugin, identifier, new SimplePlaceholder(refreshIntervalTicks, placeholderReplacer));
@ -89,4 +101,9 @@ public class PlaceholderRegistry {
return placeholderExpansions.contains(new PlaceholderIdentifier(identifier), new PluginName(plugin));
}
public @Nullable RelativePlaceholder findRelative(PlaceholderOccurrence textOccurrence) {
PlaceholderIdentifier identifier = textOccurrence.getIdentifier();
return relativePlaceholders.get(identifier);
}
}