diff --git a/build.gradle.kts b/build.gradle.kts index f34711d9..b73897dd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -92,4 +92,6 @@ tasks.runServer { javaLauncher.set(javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(21)) }) + downloadPlugins.modrinth("luckperms", "v5.5.0-bukkit") + downloadPlugins.modrinth("VaultUnlocked", "2.16.0") } diff --git a/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatFormatterPlugin.java b/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatFormatterPlugin.java index 195f50c8..3d4ff69a 100644 --- a/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatFormatterPlugin.java +++ b/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatFormatterPlugin.java @@ -2,8 +2,6 @@ import com.eternalcode.formatter.config.ConfigManager; import com.eternalcode.formatter.config.PluginConfig; -import com.eternalcode.formatter.legacy.LegacyPostProcessor; -import com.eternalcode.formatter.legacy.LegacyPreProcessor; import com.eternalcode.formatter.placeholder.ConfiguredReplacer; import com.eternalcode.formatter.placeholderapi.PlaceholderAPIInitializer; import com.eternalcode.formatter.placeholder.PlaceholderRegistry; @@ -47,11 +45,7 @@ public ChatFormatterPlugin(Plugin plugin) { UpdaterService updaterService = new UpdaterService(plugin.getDescription()); AudienceProvider audienceProvider = BukkitAudiences.create(plugin); - MiniMessage miniMessage = MiniMessage.builder() - .preProcessor(new LegacyPreProcessor()) - .postProcessor(new LegacyPostProcessor()) - .build(); - + MiniMessage miniMessage = MiniMessage.miniMessage(); // bStats metrics new Metrics(plugin, 15199); diff --git a/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatHandlerImpl.java b/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatHandlerImpl.java index a1dc93b1..0b82fb04 100644 --- a/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatHandlerImpl.java +++ b/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatHandlerImpl.java @@ -106,7 +106,6 @@ public ChatRenderedMessage process(ChatMessage chatMessage) { ? this.placeholderRegistry.format(format, sender) : this.placeholderRegistry.format(format, sender, viewer.get()); - format = Legacy.clearSection(format); format = Legacy.legacyToAdventure(format); Component renderedMessage = this.miniMessage.deserialize(format, this.createTags(chatMessage)); @@ -128,16 +127,15 @@ private TagResolver createTags(ChatMessage chatMessage) { } private TagResolver.Single displayNamePlaceholder(Player sender) { - return Placeholder.parsed("displayname", Legacy.clearSection(sender.getDisplayName())); + return Placeholder.parsed("displayname", Legacy.legacyToAdventure(sender.getDisplayName())); } private TagResolver.Single namePlaceholder(Player sender) { - return Placeholder.parsed("name", Legacy.clearSection(sender.getName())); + return Placeholder.parsed("name", sender.getName()); } private TagResolver.Single messagePlaceholder(Player sender, String rawMessage) { TagResolver permittedTags = this.providePermittedTags(sender); - rawMessage = Legacy.clearSection(rawMessage); rawMessage = Legacy.legacyToAdventure(rawMessage, permission -> sender.hasPermission(permission)); Component componentMessage = EMPTY_MESSAGE_DESERIALIZER.deserialize(rawMessage, permittedTags); return Placeholder.component("message", componentMessage); diff --git a/chatformatter-core/src/main/java/com/eternalcode/formatter/legacy/Legacy.java b/chatformatter-core/src/main/java/com/eternalcode/formatter/legacy/Legacy.java index df0b3395..499c0062 100644 --- a/chatformatter-core/src/main/java/com/eternalcode/formatter/legacy/Legacy.java +++ b/chatformatter-core/src/main/java/com/eternalcode/formatter/legacy/Legacy.java @@ -1,11 +1,12 @@ package com.eternalcode.formatter.legacy; import com.google.common.collect.ImmutableMap; +import java.util.Set; import java.util.function.Predicate; -import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import java.util.Map; import java.util.regex.Pattern; +import org.jetbrains.annotations.VisibleForTesting; public final class Legacy { @@ -13,6 +14,15 @@ public final class Legacy { private static final Pattern HEX_LEGACY_PATTERN = Pattern.compile("(?i)&#([0-9A-F]{6})"); private static final Pattern HEX_LEGACY_VANILLA_PATTERN = Pattern.compile("(?i)&x(&[0-9A-F]){6}"); + private static final Set COLORS = Set.of( + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' + ); + + private static final Set DECORATIONS = Set.of( + 'k', 'l', 'm', 'n', 'o' + ); + private static final Map codeTranslations = new ImmutableMap.Builder() .put('0', "") .put('1', "") @@ -66,7 +76,8 @@ public final class Legacy { private Legacy() { } - public static String clearSection(String text) { + @VisibleForTesting + static String clearSection(String text) { return text.replace('ยง', '&'); } @@ -75,7 +86,8 @@ public static String legacyToAdventure(String input) { } public static String legacyToAdventure(String input, Predicate hasPermission) { - String result = HEX_LEGACY_VANILLA_PATTERN.matcher(input).replaceAll(matchResult -> { + String result = clearSection(input); + result = HEX_LEGACY_VANILLA_PATTERN.matcher(result).replaceAll(matchResult -> { String hexColor = matchResult.group().replace("&x", "").replace("&", ""); return "<#" + hexColor + ">"; }); @@ -98,16 +110,17 @@ public static String legacyToAdventure(String input, Predicate hasPermis } private static boolean hasPermissionForLegacyCode(Predicate hasPermission, char code) { - if (hasWildcardPermission(hasPermission)) { + if (hasPermission.test("chatformatter.*")) { + return true; + } + if (COLORS.contains(code) && hasPermission.test("chatformatter.color.*")) { + return true; + } + if (DECORATIONS.contains(code) && hasPermission.test("chatformatter.decorations.*")) { return true; } String permission = legacyCodeToPermission.get(code); return permission != null && hasPermission.test(permission); } - private static boolean hasWildcardPermission(Predicate hasPermission) { - return hasPermission.test("chatformatter.*") - || hasPermission.test("chatformatter.color.*") - || hasPermission.test("chatformatter.decorations.*"); - } } diff --git a/chatformatter-core/src/main/java/com/eternalcode/formatter/legacy/LegacyPostProcessor.java b/chatformatter-core/src/main/java/com/eternalcode/formatter/legacy/LegacyPostProcessor.java deleted file mode 100644 index 4b7f9a03..00000000 --- a/chatformatter-core/src/main/java/com/eternalcode/formatter/legacy/LegacyPostProcessor.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.eternalcode.formatter.legacy; - -import java.util.regex.Pattern; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextReplacementConfig; - -import java.util.function.Consumer; -import java.util.function.UnaryOperator; -import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; - -public final class LegacyPostProcessor implements UnaryOperator { - - private static final LegacyComponentSerializer LEGACY_AMPERSAND_SERIALIZER = LegacyComponentSerializer.builder() - .hexColors() - .character('&') - .hexCharacter('#') - .useUnusualXRepeatedCharacterHexFormat() - .build(); - - private static final Pattern ALL = Pattern.compile(".*"); - private static final Consumer REPLACER = builder -> builder - .match(ALL) - .replacement((matchResult, ignored) -> LEGACY_AMPERSAND_SERIALIZER.deserialize(matchResult.group())); - - @Override - public Component apply(Component component) { - return component.replaceText(REPLACER); - } - -} diff --git a/chatformatter-core/src/main/java/com/eternalcode/formatter/legacy/LegacyPreProcessor.java b/chatformatter-core/src/main/java/com/eternalcode/formatter/legacy/LegacyPreProcessor.java deleted file mode 100644 index 38a64021..00000000 --- a/chatformatter-core/src/main/java/com/eternalcode/formatter/legacy/LegacyPreProcessor.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.eternalcode.formatter.legacy; - -import java.util.function.UnaryOperator; - -public final class LegacyPreProcessor implements UnaryOperator { - - @Override - public String apply(String component) { - return Legacy.clearSection(component); - } - -}