diff --git a/src/main/java/net/william278/velocitab/hook/miniconditions/MiniConditionManager.java b/src/main/java/net/william278/velocitab/hook/miniconditions/MiniConditionManager.java index 7f01c78..6d736a3 100644 --- a/src/main/java/net/william278/velocitab/hook/miniconditions/MiniConditionManager.java +++ b/src/main/java/net/william278/velocitab/hook/miniconditions/MiniConditionManager.java @@ -42,19 +42,19 @@ import java.util.regex.Pattern; public class MiniConditionManager { - public final static Map REPLACE = Map.of( + public static final Map REPLACE = Map.of( "\"", "-q-", "'", "-a-" ); - public final static Map REPLACE_2 = Map.of( + public static final Map REPLACE_2 = Map.of( "*LESS3*", "<", "*GREATER3*", ">", "*LESS2*", "<", "*GREATER2*", ">" ); - private final static Map REPLACE_3 = Map.of( + private static final Map REPLACE_3 = Map.of( "?dp?", ":" ); diff --git a/src/main/java/net/william278/velocitab/placeholder/Placeholder.java b/src/main/java/net/william278/velocitab/placeholder/Placeholder.java index aa136f8..f9d5aa4 100644 --- a/src/main/java/net/william278/velocitab/placeholder/Placeholder.java +++ b/src/main/java/net/william278/velocitab/placeholder/Placeholder.java @@ -19,18 +19,13 @@ package net.william278.velocitab.placeholder; -import com.google.common.collect.Maps; import com.velocitypowered.api.proxy.ServerConnection; import com.velocitypowered.api.proxy.server.RegisteredServer; -import it.unimi.dsi.fastutil.Pair; +import lombok.Getter; import net.william278.velocitab.Velocitab; -import net.william278.velocitab.config.Formatter; -import net.william278.velocitab.hook.miniconditions.MiniConditionManager; import net.william278.velocitab.player.TabPlayer; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.function.TriFunction; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.time.LocalDateTime; import java.time.LocalTime; @@ -39,10 +34,10 @@ import java.time.format.FormatStyle; import java.util.*; import java.util.function.BiFunction; import java.util.function.Function; -import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +@Getter public enum Placeholder { PLAYERS_ONLINE((plugin, player) -> Integer.toString(plugin.getServer().getPlayerCount())), @@ -113,24 +108,11 @@ public enum Placeholder { .map(hook -> hook.getMeta(player.getPlayer(), param)) .orElse(getPlaceholderFallback(plugin, "%luckperms_meta_" + param + "%"))); - private final static Pattern VELOCITAB_PATTERN = Pattern.compile(""); - private final static Pattern TEST = Pattern.compile("<.*?>"); - private final static Pattern CONDITION_REPLACER = Pattern.compile(" SYMBOL_SUBSTITUTES = Map.of( - "<", "*LESS*", - ">", "*GREATER*" - ); - private final static Map SYMBOL_SUBSTITUTES_2 = Map.of( - "*LESS*", "*LESS2*", - "*GREATER*", "*GREATER2*" - ); - private final static String VEL_PLACEHOLDER = " VALUES = Arrays.asList(values()); - private final static Map BY_NAME = VALUES.stream().collect(Collectors.toMap(p -> p.name().toLowerCase(), Function.identity())); - private final static List PARAMETERISED = VALUES.stream().filter(p -> p.parameterised).toList(); + + private static final List VALUES = Arrays.asList(values()); + private static final Map BY_NAME = VALUES.stream().collect(Collectors.toMap(p -> p.name().toLowerCase(), Function.identity())); + @Getter + private static final List PARAMETERISED = VALUES.stream().filter(p -> p.parameterised).toList(); /** * Function to replace placeholders with a real value @@ -159,115 +141,7 @@ public enum Placeholder { return ""; } - @NotNull - public static Pair> replaceInternal(@NotNull String format, @NotNull Velocitab plugin, @Nullable TabPlayer player) { - format = processRelationalPlaceholders(format, plugin); - return replacePlaceholders(format, plugin, player); - } - - public static String processRelationalPlaceholders(@NotNull String format, @NotNull Velocitab plugin) { - if (plugin.getFormatter().equals(Formatter.MINIMESSAGE) && format.contains(VEL_PLACEHOLDER)) { - final Matcher conditionReplacer = CONDITION_REPLACER.matcher(format); - while (conditionReplacer.find()) { - - final String search = conditionReplacer.group().split(":")[1]; - String condition = search; - for (Map.Entry entry : MiniConditionManager.REPLACE.entrySet()) { - condition = condition.replace(entry.getKey(), entry.getValue()); - } - for (Map.Entry entry : MiniConditionManager.REPLACE_2.entrySet()) { - condition = condition.replace(entry.getValue(), entry.getKey()); - } - format = format.replace(search, condition); - } - - final Matcher testMatcher = TEST.matcher(format); - while (testMatcher.find()) { - if (testMatcher.group().startsWith(VELOCITAB_PLACEHOLDER)) { - final Matcher second = TEST.matcher(testMatcher.group().substring(1)); - while (second.find()) { - String s = second.group(); - for (Map.Entry entry : SYMBOL_SUBSTITUTES.entrySet()) { - s = s.replace(entry.getKey(), entry.getValue()); - } - format = format.replace(second.group(), s); - } - continue; - } - String s = testMatcher.group(); - for (Map.Entry entry : SYMBOL_SUBSTITUTES.entrySet()) { - s = s.replace(entry.getKey(), entry.getValue()); - } - format = format.replace(testMatcher.group(), s); - } - - final Matcher velocitabRelationalMatcher = VELOCITAB_PATTERN.matcher(format); - while (velocitabRelationalMatcher.find()) { - final String relationalPlaceholder = velocitabRelationalMatcher.group().substring(1, velocitabRelationalMatcher.group().length() - 1); - String fixedString = relationalPlaceholder; - for (Map.Entry entry : SYMBOL_SUBSTITUTES_2.entrySet()) { - fixedString = fixedString.replace(entry.getKey(), entry.getValue()); - } - format = format.replace(relationalPlaceholder, fixedString); - } - - for (Map.Entry entry : SYMBOL_SUBSTITUTES.entrySet()) { - format = format.replace(entry.getValue(), entry.getKey()); - } - - } - return format; - } - - @NotNull - private static Pair> replacePlaceholders(@NotNull String format, @NotNull Velocitab plugin, - @Nullable TabPlayer player) { - final Map replacedPlaceholders = Maps.newHashMap(); - for (Placeholder placeholder : VALUES) { - final Matcher matcher = placeholder.pattern.matcher(format); - if (placeholder.parameterised) { - format = matcher.replaceAll(matchResult -> { - final String replacement = placeholder.replacer.apply(StringUtils.chop(matchResult.group().replace("%" + placeholder.name().toLowerCase(), "") - .replaceFirst("_", "")), plugin, player); - replacedPlaceholders.put(matchResult.group(), replacement); - return Matcher.quoteReplacement(replacement); - }); - } else { - format = matcher.replaceAll(matchResult -> { - final String replacement = placeholder.replacer.apply(null, plugin, player); - replacedPlaceholders.put(matchResult.group(), replacement); - return Matcher.quoteReplacement(replacement); - }); - } - } - return Pair.of(format, replacedPlaceholders); - } - public static Optional byName(@NotNull String name) { return Optional.ofNullable(BY_NAME.get(name.toLowerCase().replace("%", ""))); } - - protected static Optional replaceSingle(@NotNull String placeholder, @NotNull Velocitab plugin, @NotNull TabPlayer player) { - final Optional optionalPlaceholder = byName(placeholder); - if (optionalPlaceholder.isEmpty()) { - //check if it's parameterised - for (Placeholder placeholderType : PARAMETERISED) { - final Matcher matcher = placeholderType.pattern.matcher(placeholder); - if (matcher.find()) { - final String s = StringUtils.chop(matcher.group().replace("%" + placeholderType.name().toLowerCase(), "") - .replaceFirst("_", "")); - return Optional.of(placeholderType.replacer.apply(s, plugin, player)); - } - } - - return Optional.empty(); - } - - if(optionalPlaceholder.get().parameterised) { - throw new IllegalArgumentException("Placeholder " + placeholder + " is parameterised"); - } - - final Placeholder placeholderType = optionalPlaceholder.get(); - return Optional.of(placeholderType.replacer.apply(null, plugin, player)); - } } diff --git a/src/main/java/net/william278/velocitab/placeholder/PlaceholderManager.java b/src/main/java/net/william278/velocitab/placeholder/PlaceholderManager.java index 1ff29f8..70eedc5 100644 --- a/src/main/java/net/william278/velocitab/placeholder/PlaceholderManager.java +++ b/src/main/java/net/william278/velocitab/placeholder/PlaceholderManager.java @@ -23,9 +23,12 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.velocitypowered.api.proxy.Player; import net.william278.velocitab.Velocitab; +import net.william278.velocitab.config.Formatter; import net.william278.velocitab.config.Group; +import net.william278.velocitab.hook.miniconditions.MiniConditionManager; import net.william278.velocitab.player.Role; import net.william278.velocitab.player.TabPlayer; +import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -37,8 +40,21 @@ import java.util.regex.Pattern; public class PlaceholderManager { - private static final Pattern PLACEHOLDER_PATTERN = Placeholder.PLACEHOLDER_PATTERN; - private final static String ELSE_PLACEHOLDER = "ELSE"; + private static final String ELSE_PLACEHOLDER = "ELSE"; + private static final Pattern VELOCITAB_PATTERN = Pattern.compile(""); + private static final Pattern TEST = Pattern.compile("<.*?>"); + private static final Pattern CONDITION_REPLACER = Pattern.compile(" SYMBOL_SUBSTITUTES = Map.of( + "<", "*LESS*", + ">", "*GREATER*" + ); + private static final Map SYMBOL_SUBSTITUTES_2 = Map.of( + "*LESS*", "*LESS2*", + "*GREATER*", "*GREATER2*" + ); + private static final String VEL_PLACEHOLDER = "> placeholders; @@ -68,7 +84,7 @@ public class PlaceholderManager { .map(s -> s.replace("%target_", "%")) .toList(); - placeholders.forEach(placeholder -> Placeholder.replaceSingle(placeholder, plugin, tabPlayer) + placeholders.forEach(placeholder -> replaceSingle(placeholder, plugin, tabPlayer) .ifPresentOrElse(replacement -> parsed.put(placeholder, replacement), () -> plugin.getPAPIProxyBridgeHook().ifPresent(hook -> hook.formatPlaceholders(placeholder, player).thenAccept(replacement -> { @@ -83,18 +99,18 @@ public class PlaceholderManager { public String applyPlaceholders(@NotNull TabPlayer player, @NotNull String text) { final Map parsed = placeholders.computeIfAbsent(player.getPlayer().getUniqueId(), uuid -> Maps.newConcurrentMap()); final String applied = applyPlaceholderReplacements(text, player, parsed); - return Placeholder.processRelationalPlaceholders(applied, plugin); + return processRelationalPlaceholders(applied, plugin); } @NotNull public String applyPlaceholders(@NotNull TabPlayer player, @NotNull String text, @NotNull TabPlayer target) { final Map parsed = placeholders.computeIfAbsent(player.getPlayer().getUniqueId(), uuid -> Maps.newConcurrentMap()); final String applied = applyPlaceholderReplacements(text, player, parsed); - final String relational = Placeholder.processRelationalPlaceholders(applied, plugin); + final String relational = processRelationalPlaceholders(applied, plugin); final Map targetParsed = placeholders.computeIfAbsent(target.getPlayer().getUniqueId(), uuid -> Maps.newConcurrentMap()); final String targetApplied = applyPlaceholderReplacements(relational.replace("%target_", "%"), target, targetParsed); - return Placeholder.processRelationalPlaceholders(targetApplied, plugin); + return processRelationalPlaceholders(targetApplied, plugin); } public void clearPlaceholders(@NotNull UUID uuid) { @@ -155,4 +171,82 @@ public class PlaceholderManager { return Optional.ofNullable(placeholders.get(uuid).get(text)); } + + private Optional replaceSingle(@NotNull String placeholder, @NotNull Velocitab plugin, @NotNull TabPlayer player) { + final Optional optionalPlaceholder = Placeholder.byName(placeholder); + if (optionalPlaceholder.isEmpty()) { + //check if it's parameterised + for (Placeholder placeholderType : Placeholder.getPARAMETERISED()) { + final Matcher matcher = placeholderType.getPattern().matcher(placeholder); + if (matcher.find()) { + final String s = StringUtils.chop(matcher.group().replace("%" + placeholderType.name().toLowerCase(), "") + .replaceFirst("_", "")); + return Optional.of(placeholderType.getReplacer().apply(s, plugin, player)); + } + } + + return Optional.empty(); + } + + if(optionalPlaceholder.get().isParameterised()) { + throw new IllegalArgumentException("Placeholder " + placeholder + " is parameterised"); + } + + final Placeholder placeholderType = optionalPlaceholder.get(); + return Optional.of(placeholderType.getReplacer().apply(null, plugin, player)); + } + + private String processRelationalPlaceholders(@NotNull String format, @NotNull Velocitab plugin) { + if (plugin.getFormatter().equals(Formatter.MINIMESSAGE) && format.contains(VEL_PLACEHOLDER)) { + final Matcher conditionReplacer = CONDITION_REPLACER.matcher(format); + while (conditionReplacer.find()) { + + final String search = conditionReplacer.group().split(":")[1]; + String condition = search; + for (Map.Entry entry : MiniConditionManager.REPLACE.entrySet()) { + condition = condition.replace(entry.getKey(), entry.getValue()); + } + for (Map.Entry entry : MiniConditionManager.REPLACE_2.entrySet()) { + condition = condition.replace(entry.getValue(), entry.getKey()); + } + format = format.replace(search, condition); + } + + final Matcher testMatcher = TEST.matcher(format); + while (testMatcher.find()) { + if (testMatcher.group().startsWith(VELOCITAB_PLACEHOLDER)) { + final Matcher second = TEST.matcher(testMatcher.group().substring(1)); + while (second.find()) { + String s = second.group(); + for (Map.Entry entry : SYMBOL_SUBSTITUTES.entrySet()) { + s = s.replace(entry.getKey(), entry.getValue()); + } + format = format.replace(second.group(), s); + } + continue; + } + String s = testMatcher.group(); + for (Map.Entry entry : SYMBOL_SUBSTITUTES.entrySet()) { + s = s.replace(entry.getKey(), entry.getValue()); + } + format = format.replace(testMatcher.group(), s); + } + + final Matcher velocitabRelationalMatcher = VELOCITAB_PATTERN.matcher(format); + while (velocitabRelationalMatcher.find()) { + final String relationalPlaceholder = velocitabRelationalMatcher.group().substring(1, velocitabRelationalMatcher.group().length() - 1); + String fixedString = relationalPlaceholder; + for (Map.Entry entry : SYMBOL_SUBSTITUTES_2.entrySet()) { + fixedString = fixedString.replace(entry.getKey(), entry.getValue()); + } + format = format.replace(relationalPlaceholder, fixedString); + } + + for (Map.Entry entry : SYMBOL_SUBSTITUTES.entrySet()) { + format = format.replace(entry.getValue(), entry.getKey()); + } + + } + return format; + } } diff --git a/src/main/java/net/william278/velocitab/sorting/SortingManager.java b/src/main/java/net/william278/velocitab/sorting/SortingManager.java index c0e722d..37ab5cc 100644 --- a/src/main/java/net/william278/velocitab/sorting/SortingManager.java +++ b/src/main/java/net/william278/velocitab/sorting/SortingManager.java @@ -22,13 +22,10 @@ package net.william278.velocitab.sorting; import com.google.common.collect.Lists; import com.velocitypowered.api.network.ProtocolVersion; import net.william278.velocitab.Velocitab; -import net.william278.velocitab.placeholder.Placeholder; import net.william278.velocitab.player.TabPlayer; import org.jetbrains.annotations.NotNull; -import java.util.Arrays; import java.util.List; -import java.util.concurrent.CompletableFuture; import java.util.regex.Pattern; import java.util.stream.Collectors; diff --git a/src/main/java/net/william278/velocitab/tab/Nametag.java b/src/main/java/net/william278/velocitab/tab/Nametag.java index ffad243..e62cc52 100644 --- a/src/main/java/net/william278/velocitab/tab/Nametag.java +++ b/src/main/java/net/william278/velocitab/tab/Nametag.java @@ -32,14 +32,12 @@ public record Nametag(@NotNull String prefix, @NotNull String suffix) { @NotNull public Component getPrefixComponent(@NotNull Velocitab plugin, @NotNull TabPlayer tabPlayer, @NotNull TabPlayer target) { -// final String formatted = Placeholder.replaceInternal(prefix, plugin, tabPlayer).first(); final String formatted = plugin.getPlaceholderManager().applyPlaceholders(tabPlayer, prefix, target); return plugin.getFormatter().format(formatted, tabPlayer, target, plugin); } @NotNull public Component getSuffixComponent(@NotNull Velocitab plugin, @NotNull TabPlayer tabPlayer, @NotNull TabPlayer target) { -// final String formatted = Placeholder.replaceInternal(suffix, plugin, tabPlayer).first(); final String formatted = plugin.getPlaceholderManager().applyPlaceholders(tabPlayer, suffix, target); return plugin.getFormatter().format(formatted, tabPlayer, target, plugin); } diff --git a/src/main/java/net/william278/velocitab/util/SerializationUtil.java b/src/main/java/net/william278/velocitab/util/SerializationUtil.java index 4c0ed73..4dc1b66 100644 --- a/src/main/java/net/william278/velocitab/util/SerializationUtil.java +++ b/src/main/java/net/william278/velocitab/util/SerializationUtil.java @@ -23,7 +23,7 @@ import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; public final class SerializationUtil { - public final static LegacyComponentSerializer LEGACY_SERIALIZER = LegacyComponentSerializer.builder() + public static final LegacyComponentSerializer LEGACY_SERIALIZER = LegacyComponentSerializer.builder() .hexCharacter('#') .character('&') .hexColors()