From b1f63d8a316ec72f51abe3b209c6d16972979ad1 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Fri, 11 Apr 2025 23:03:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=8D=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/font/BukkitFontManager.java | 60 +------------------ .../plugin/network/PacketConsumers.java | 49 +++++---------- .../core/font/AbstractFontManager.java | 53 +++++++++++----- .../craftengine/core/font/FontManager.java | 8 ++- .../font/IllegalCharacterProcessResult.java | 12 ++++ 5 files changed, 73 insertions(+), 109 deletions(-) create mode 100644 core/src/main/java/net/momirealms/craftengine/core/font/IllegalCharacterProcessResult.java diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java index 3d31a83e4..676e8909f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java @@ -10,10 +10,7 @@ import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.util.ComponentUtils; import net.momirealms.craftengine.bukkit.util.LegacyInventoryUtils; import net.momirealms.craftengine.bukkit.util.Reflections; -import net.momirealms.craftengine.core.font.AbstractFontManager; -import net.momirealms.craftengine.core.font.EmojiComponentProcessResult; -import net.momirealms.craftengine.core.font.EmojiTextProcessResult; -import net.momirealms.craftengine.core.font.FontManager; +import net.momirealms.craftengine.core.font.*; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.util.AdventureHelper; @@ -95,7 +92,7 @@ public class BukkitFontManager extends AbstractFontManager implements Listener { if (!event.getPlayer().hasPermission(FontManager.BYPASS_COMMAND)) { IllegalCharacterProcessResult result = processIllegalCharacters(event.getMessage()); if (result.has()) { - event.setMessage(result.newText()); + event.setMessage(result.text()); } } } @@ -125,10 +122,6 @@ public class BukkitFontManager extends AbstractFontManager implements Listener { } if (renameText == null || renameText.isEmpty()) return; - IllegalCharacterProcessResult processResult = processIllegalCharacters(renameText); - if (processResult.has()) { - renameText = processResult.newText(); - } Component itemName = Component.text(renameText); EmojiComponentProcessResult replaceProcessResult = replaceComponentEmoji(itemName, plugin.adapt(player), renameText); if (replaceProcessResult.changed()) { @@ -203,7 +196,7 @@ public class BukkitFontManager extends AbstractFontManager implements Listener { if (!player.hasPermission(FontManager.BYPASS_CHAT)) { IllegalCharacterProcessResult result = processIllegalCharacters(processResult.text()); if (result.has()) { - Object component = ComponentUtils.jsonToPaperAdventure(result.newText()); + Object component = ComponentUtils.jsonToPaperAdventure(result.text()); Reflections.method$AsyncChatDecorateEvent$result.invoke(event, component); } else if (hasChanged) { Object component = ComponentUtils.jsonToPaperAdventure(processResult.text()); @@ -217,51 +210,4 @@ public class BukkitFontManager extends AbstractFontManager implements Listener { throw new RuntimeException(e); } } - - private IllegalCharacterProcessResult processIllegalCharacters(String raw) { - boolean hasIllegal = false; - // replace illegal image usage - Map tokens = matchTags(raw); - if (!tokens.isEmpty()) { - for (Map.Entry entry : tokens.entrySet()) { - raw = raw.replace(entry.getKey(), "*"); - hasIllegal = true; - } - } - - if (this.isDefaultFontInUse()) { - // replace illegal codepoint - char[] chars = raw.toCharArray(); - int[] codepoints = CharacterUtils.charsToCodePoints(chars); - int[] newCodepoints = new int[codepoints.length]; - - for (int i = 0; i < codepoints.length; i++) { - int codepoint = codepoints[i]; - if (!isIllegalCodepoint(codepoint)) { - newCodepoints[i] = codepoint; - } else { - newCodepoints[i] = '*'; - hasIllegal = true; - } - } - - if (hasIllegal) { - return IllegalCharacterProcessResult.has(new String(newCodepoints, 0, newCodepoints.length)); - } - } else if (hasIllegal) { - return IllegalCharacterProcessResult.has(raw); - } - return IllegalCharacterProcessResult.not(); - } - - public record IllegalCharacterProcessResult(boolean has, String newText) { - - public static IllegalCharacterProcessResult has(String newText) { - return new IllegalCharacterProcessResult(true, newText); - } - - public static IllegalCharacterProcessResult not() { - return new IllegalCharacterProcessResult(false, null); - } - } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index 6fd9b5a9d..85708dc2a 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -20,6 +20,7 @@ import net.momirealms.craftengine.bukkit.util.*; import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.entity.player.InteractionHand; import net.momirealms.craftengine.core.font.FontManager; +import net.momirealms.craftengine.core.font.IllegalCharacterProcessResult; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.plugin.network.ConnectionState; @@ -1640,21 +1641,21 @@ public class PacketConsumers { public static final TriConsumer RENAME_ITEM = (user, event, packet) -> { try { if (!Config.filterAnvil()) return; + if (((BukkitServerPlayer) user).hasPermission(FontManager.BYPASS_ANVIL)) { + return; + } String message = (String) Reflections.field$ServerboundRenameItemPacket$name.get(packet); if (message != null && !message.isEmpty()) { - FontManager manager = CraftEngine.instance().imageManager(); - if (!manager.isDefaultFontInUse()) return; // check bypass - if (((BukkitServerPlayer) user).hasPermission(FontManager.BYPASS_ANVIL)) { - return; - } - runIfContainsIllegalCharacter(message, manager, (s) -> { + FontManager manager = CraftEngine.instance().imageManager(); + IllegalCharacterProcessResult result = manager.processIllegalCharacters(message); + if (result.has()) { try { - Reflections.field$ServerboundRenameItemPacket$name.set(packet, s); + Reflections.field$ServerboundRenameItemPacket$name.set(packet, result.text()); } catch (ReflectiveOperationException e) { CraftEngine.instance().logger().warn("Failed to replace chat", e); } - }); + } } } catch (Exception e) { CraftEngine.instance().logger().warn("Failed to handle ServerboundRenameItemPacket", e); @@ -1665,20 +1666,19 @@ public class PacketConsumers { public static final TriConsumer SIGN_UPDATE = (user, event, packet) -> { try { if (!Config.filterSign()) return; - String[] lines = (String[]) Reflections.field$ServerboundSignUpdatePacket$lines.get(packet); - FontManager manager = CraftEngine.instance().imageManager(); - if (!manager.isDefaultFontInUse()) return; // check bypass if (((BukkitServerPlayer) user).hasPermission(FontManager.BYPASS_SIGN)) { return; } + String[] lines = (String[]) Reflections.field$ServerboundSignUpdatePacket$lines.get(packet); + FontManager manager = CraftEngine.instance().imageManager(); + if (!manager.isDefaultFontInUse()) return; for (int i = 0; i < lines.length; i++) { String line = lines[i]; if (line != null && !line.isEmpty()) { - try { - int lineIndex = i; - runIfContainsIllegalCharacter(line, manager, (s) -> lines[lineIndex] = s); - } catch (Exception ignore) { + IllegalCharacterProcessResult result = manager.processIllegalCharacters(line); + if (result.has()) { + lines[i] = result.text(); } } } @@ -1763,25 +1763,6 @@ public class PacketConsumers { return hasIllegal ? Pair.of(true, new String(newCodepoints, 0, newCodepoints.length)) : Pair.of(false, original); } - private static void runIfContainsIllegalCharacter(String string, FontManager manager, Consumer callback) { - if (string.isEmpty()) return; - int[] codepoints = CharacterUtils.charsToCodePoints(string.toCharArray()); - int[] newCodepoints = new int[codepoints.length]; - boolean hasIllegal = false; - for (int i = 0; i < codepoints.length; i++) { - int codepoint = codepoints[i]; - if (!manager.isIllegalCodepoint(codepoint)) { - newCodepoints[i] = codepoint; - } else { - newCodepoints[i] = '*'; - hasIllegal = true; - } - } - if (hasIllegal) { - callback.accept(new String(newCodepoints, 0, newCodepoints.length)); - } - } - public static final TriConsumer CUSTOM_PAYLOAD = (user, event, packet) -> { try { if (!VersionHelper.isVersionNewerThan1_20_5()) return; diff --git a/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java b/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java index a98476665..d2dd94945 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java @@ -91,22 +91,6 @@ public abstract class AbstractFontManager implements FontManager { return tags; } - @Override - public String stripTags(String text) { - if (this.imageTagTrie == null) { - return text; - } - StringBuilder builder = new StringBuilder(); - for (Token token : this.imageTagTrie.tokenize(text)) { - if (token.isMatch()) { - builder.append("*"); - } else { - builder.append(token.getFragment()); - } - } - return builder.toString(); - } - @Override public EmojiTextProcessResult replaceMiniMessageEmoji(@NotNull String miniMessage, Player player, int maxTimes) { if (this.emojiKeywordTrie == null || maxTimes <= 0) { @@ -221,6 +205,43 @@ public abstract class AbstractFontManager implements FontManager { return EmojiComponentProcessResult.success(text); } + @Override + public IllegalCharacterProcessResult processIllegalCharacters(String raw, char replacement) { + boolean hasIllegal = false; + // replace illegal image usage + Map tokens = matchTags(raw); + if (!tokens.isEmpty()) { + for (Map.Entry entry : tokens.entrySet()) { + raw = raw.replace(entry.getKey(), String.valueOf(replacement)); + hasIllegal = true; + } + } + + if (this.isDefaultFontInUse()) { + // replace illegal codepoint + char[] chars = raw.toCharArray(); + int[] codepoints = CharacterUtils.charsToCodePoints(chars); + int[] newCodepoints = new int[codepoints.length]; + + for (int i = 0; i < codepoints.length; i++) { + int codepoint = codepoints[i]; + if (!isIllegalCodepoint(codepoint)) { + newCodepoints[i] = codepoint; + } else { + newCodepoints[i] = replacement; + hasIllegal = true; + } + } + + if (hasIllegal) { + return IllegalCharacterProcessResult.has(new String(newCodepoints, 0, newCodepoints.length)); + } + } else if (hasIllegal) { + return IllegalCharacterProcessResult.has(raw); + } + return IllegalCharacterProcessResult.not(); + } + @Override public ConfigSectionParser[] parsers() { return new ConfigSectionParser[] {this.imageParser, this.emojiParser}; diff --git a/core/src/main/java/net/momirealms/craftengine/core/font/FontManager.java b/core/src/main/java/net/momirealms/craftengine/core/font/FontManager.java index 62f4eafe6..8da06423e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/font/FontManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/font/FontManager.java @@ -25,8 +25,6 @@ public interface FontManager extends Manageable { String BYPASS_COMMAND = "craftengine.filter.bypass.command"; String BYPASS_ANVIL = "craftengine.filter.bypass.anvil"; - String stripTags(String text); - default EmojiComponentProcessResult replaceComponentEmoji(@NotNull Component text, @Nullable Player player) { return replaceComponentEmoji(text, player, Config.maxEmojisPerParse()); } @@ -41,6 +39,12 @@ public interface FontManager extends Manageable { EmojiComponentProcessResult replaceComponentEmoji(@NotNull Component text, @Nullable Player player, @NotNull String raw, int maxTimes); + default IllegalCharacterProcessResult processIllegalCharacters(String raw) { + return processIllegalCharacters(raw, '*'); + } + + IllegalCharacterProcessResult processIllegalCharacters(String raw, char replacement); + ConfigSectionParser[] parsers(); default EmojiTextProcessResult replaceMiniMessageEmoji(@NotNull String miniMessage, @Nullable Player player) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/font/IllegalCharacterProcessResult.java b/core/src/main/java/net/momirealms/craftengine/core/font/IllegalCharacterProcessResult.java new file mode 100644 index 000000000..f2568de6e --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/font/IllegalCharacterProcessResult.java @@ -0,0 +1,12 @@ +package net.momirealms.craftengine.core.font; + +public record IllegalCharacterProcessResult(boolean has, String text) { + + public static IllegalCharacterProcessResult has(String text) { + return new IllegalCharacterProcessResult(true, text); + } + + public static IllegalCharacterProcessResult not() { + return new IllegalCharacterProcessResult(false, ""); + } +} \ No newline at end of file