Improve placeholder handling

This commit is contained in:
filoghost 2021-07-25 22:17:28 +02:00
parent ed73b8e098
commit 88b260ffb9
3 changed files with 48 additions and 62 deletions

View File

@ -10,6 +10,7 @@ import me.filoghost.holographicdisplays.plugin.placeholder.parsing.PlaceholderOc
import me.filoghost.holographicdisplays.plugin.placeholder.parsing.StringWithPlaceholders; import me.filoghost.holographicdisplays.plugin.placeholder.parsing.StringWithPlaceholders;
import me.filoghost.holographicdisplays.plugin.placeholder.tracking.PlaceholderTracker; import me.filoghost.holographicdisplays.plugin.placeholder.tracking.PlaceholderTracker;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Objects; import java.util.Objects;
@ -17,24 +18,41 @@ import java.util.Objects;
class DisplayText { class DisplayText {
private final PlaceholderTracker placeholderTracker; private final PlaceholderTracker placeholderTracker;
private @Nullable StringWithPlaceholders textWithoutReplacements; private @NotNull StringWithPlaceholders textWithoutReplacements;
private @Nullable StringWithPlaceholders textWithGlobalReplacements; private @NotNull StringWithPlaceholders textWithGlobalReplacements;
DisplayText(PlaceholderTracker placeholderTracker) { DisplayText(PlaceholderTracker placeholderTracker) {
this.placeholderTracker = placeholderTracker; this.placeholderTracker = placeholderTracker;
this.textWithoutReplacements = StringWithPlaceholders.of(null);
this.textWithGlobalReplacements = StringWithPlaceholders.of(null);
} }
void set(@Nullable String textString) { void setWithoutReplacements(@Nullable String textString) {
textWithoutReplacements = StringWithPlaceholders.of(textString); textWithoutReplacements = StringWithPlaceholders.of(textString);
textWithGlobalReplacements = textWithoutReplacements; textWithGlobalReplacements = textWithoutReplacements;
} }
String get() { String getWithoutReplacements() {
return textWithoutReplacements != null ? textWithoutReplacements.getUnreplacedString() : null; return textWithoutReplacements.getUnreplacedString();
}
String getWithGlobalReplacements() {
return textWithGlobalReplacements.getUnreplacedString();
}
String getWithIndividualReplacements(Player player) {
String textWithIndividualReplacements = textWithGlobalReplacements.replacePlaceholders((PlaceholderOccurrence occurrence) ->
placeholderTracker.updateAndGetIndividualReplacement(occurrence, player));
if (PlaceholderAPIHook.isEnabled() && PlaceholderAPIHook.containsPlaceholders(textWithIndividualReplacements)) {
textWithIndividualReplacements = PlaceholderAPIHook.replacePlaceholders(player, textWithIndividualReplacements);
}
return textWithIndividualReplacements;
} }
boolean updateGlobalReplacements() { boolean updateGlobalReplacements() {
if (textWithoutReplacements == null || !textWithoutReplacements.containsPlaceholders()) { if (!textWithoutReplacements.containsPlaceholders()) {
return false; return false;
} }
@ -49,42 +67,7 @@ class DisplayText {
return true; return true;
} }
String getWithGlobalReplacements() {
if (containsIndividualPlaceholders()) {
throw new IllegalStateException("contains individual placeholders");
}
if (textWithoutReplacements == null || !textWithoutReplacements.containsPlaceholders()) {
return textWithoutReplacements.getUnreplacedString();
}
return textWithGlobalReplacements.getUnreplacedString();
}
String getWithIndividualReplacements(Player player) {
if (!containsIndividualPlaceholders()) {
throw new IllegalStateException("does not contain individual placeholders");
}
if (textWithoutReplacements == null || !textWithoutReplacements.containsPlaceholders()) {
return textWithoutReplacements.getUnreplacedString();
}
String text = textWithGlobalReplacements.replacePlaceholders((PlaceholderOccurrence occurrence) ->
placeholderTracker.updateAndGetIndividualReplacement(occurrence, player));
if (PlaceholderAPIHook.isEnabled() && PlaceholderAPIHook.containsPlaceholders(text)) {
text = PlaceholderAPIHook.replacePlaceholders(player, text);
}
return text;
}
boolean containsIndividualPlaceholders() { boolean containsIndividualPlaceholders() {
if (textWithoutReplacements == null) {
return false;
}
return placeholderTracker.containsIndividualPlaceholders(textWithoutReplacements) return placeholderTracker.containsIndividualPlaceholders(textWithoutReplacements)
|| PlaceholderAPIHook.containsPlaceholders(textWithoutReplacements.getUnreplacedString()); || PlaceholderAPIHook.containsPlaceholders(textWithoutReplacements.getUnreplacedString());
} }

View File

@ -47,8 +47,8 @@ public class TextLineTracker extends TouchableLineTracker<StandardTextLine> {
super.detectChanges(); super.detectChanges();
String displayText = line.getText(); String displayText = line.getText();
if (!Objects.equals(this.displayText.get(), displayText)) { if (!Objects.equals(this.displayText.getWithoutReplacements(), displayText)) {
this.displayText.set(displayText); this.displayText.setWithoutReplacements(displayText);
this.displayTextChanged = true; this.displayTextChanged = true;
} }
@ -72,7 +72,7 @@ public class TextLineTracker extends TouchableLineTracker<StandardTextLine> {
super.addSpawnPackets(packetList); super.addSpawnPackets(packetList);
if (!allowPlaceholders) { if (!allowPlaceholders) {
packetList.addArmorStandSpawnPackets(armorStandEntityID, locationX, getArmorStandLocationY(), locationZ, displayText.get()); packetList.addArmorStandSpawnPackets(armorStandEntityID, locationX, getArmorStandLocationY(), locationZ, displayText.getWithoutReplacements());
} else if (displayText.containsIndividualPlaceholders()) { } else if (displayText.containsIndividualPlaceholders()) {
packetList.addArmorStandSpawnPackets(armorStandEntityID, locationX, getArmorStandLocationY(), locationZ, displayText::getWithIndividualReplacements); packetList.addArmorStandSpawnPackets(armorStandEntityID, locationX, getArmorStandLocationY(), locationZ, displayText::getWithIndividualReplacements);
} else { } else {
@ -93,7 +93,7 @@ public class TextLineTracker extends TouchableLineTracker<StandardTextLine> {
if (displayTextChanged) { if (displayTextChanged) {
if (!allowPlaceholders) { if (!allowPlaceholders) {
packetList.addArmorStandNameChangePackets(armorStandEntityID, displayText.get()); packetList.addArmorStandNameChangePackets(armorStandEntityID, displayText.getWithoutReplacements());
} else if (displayText.containsIndividualPlaceholders()) { } else if (displayText.containsIndividualPlaceholders()) {
packetList.addArmorStandNameChangePackets(armorStandEntityID, displayText::getWithIndividualReplacements); packetList.addArmorStandNameChangePackets(armorStandEntityID, displayText::getWithIndividualReplacements);
} else { } else {

View File

@ -5,38 +5,41 @@
*/ */
package me.filoghost.holographicdisplays.plugin.placeholder.parsing; package me.filoghost.holographicdisplays.plugin.placeholder.parsing;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.function.Predicate; import java.util.function.Predicate;
public final class StringWithPlaceholders { public final class StringWithPlaceholders {
private static final StringWithPlaceholders NULL_INSTANCE = new StringWithPlaceholders(null, null);
private static final char PLACEHOLDER_END_CHAR = '}'; private static final char PLACEHOLDER_END_CHAR = '}';
private static final char PLACEHOLDER_START_CHAR = '{'; private static final char PLACEHOLDER_START_CHAR = '{';
private final @NotNull String string; private final @Nullable String string;
private final List<StringPart> stringParts; private final @Nullable List<StringPart> stringParts;
@Contract("null -> null; !null -> !null") public static @NotNull StringWithPlaceholders of(@Nullable String string) {
public static StringWithPlaceholders of(@Nullable String string) { if (string == null) {
return string != null ? new StringWithPlaceholders(string) : null; return NULL_INSTANCE;
}
return new StringWithPlaceholders(string);
} }
public StringWithPlaceholders(@NotNull String string) { private StringWithPlaceholders(@NotNull String string) {
this.string = string; this(string, splitToParts(string));
this.stringParts = splitToParts(string);
} }
private StringWithPlaceholders(@NotNull String string, @Nullable List<StringPart> stringParts) { private StringWithPlaceholders(@Nullable String string, @Nullable List<StringPart> stringParts) {
this.string = string; this.string = string;
this.stringParts = stringParts; this.stringParts = stringParts;
} }
public String getUnreplacedString() { public @Nullable String getUnreplacedString() {
return string; return string;
} }
@ -45,7 +48,7 @@ public final class StringWithPlaceholders {
} }
public boolean anyMatch(Predicate<PlaceholderOccurrence> filter) { public boolean anyMatch(Predicate<PlaceholderOccurrence> filter) {
if (stringParts == null) { if (!containsPlaceholders()) {
return false; return false;
} }
@ -61,7 +64,7 @@ public final class StringWithPlaceholders {
return false; return false;
} }
public StringWithPlaceholders partiallyReplacePlaceholders(PlaceholderReplaceFunction replaceFunction) { public @NotNull StringWithPlaceholders partiallyReplacePlaceholders(PlaceholderReplaceFunction replaceFunction) {
if (!containsPlaceholders()) { if (!containsPlaceholders()) {
return this; return this;
} }
@ -104,7 +107,7 @@ public final class StringWithPlaceholders {
return new StringWithPlaceholders(fullOutput.toString(), newStringParts); return new StringWithPlaceholders(fullOutput.toString(), newStringParts);
} }
public String replacePlaceholders(PlaceholderReplaceFunction replaceFunction) { public @Nullable String replacePlaceholders(PlaceholderReplaceFunction replaceFunction) {
if (!containsPlaceholders()) { if (!containsPlaceholders()) {
return string; return string;
} }
@ -117,7 +120,7 @@ public final class StringWithPlaceholders {
return output.toString(); return output.toString();
} }
private @Nullable List<StringPart> splitToParts(String string) { private static @Nullable List<StringPart> splitToParts(@NotNull String string) {
int placeholderStartIndex = -1; int placeholderStartIndex = -1;
int lastAppendIndex = 0; int lastAppendIndex = 0;
List<StringPart> stringParts = null; // Lazy initialization List<StringPart> stringParts = null; // Lazy initialization
@ -181,12 +184,12 @@ public final class StringWithPlaceholders {
} }
StringWithPlaceholders other = (StringWithPlaceholders) obj; StringWithPlaceholders other = (StringWithPlaceholders) obj;
return this.string.equals(other.string); return Objects.equals(this.string, other.string);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return string.hashCode(); return Objects.hashCode(string);
} }