diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitImageManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitImageManager.java index d8570fd66..b636ef95c 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitImageManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitImageManager.java @@ -1,20 +1,20 @@ package net.momirealms.craftengine.bukkit.font; -import com.google.gson.JsonElement; import io.papermc.paper.event.player.AsyncChatCommandDecorateEvent; import io.papermc.paper.event.player.AsyncChatDecorateEvent; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.util.Reflections; import net.momirealms.craftengine.core.font.AbstractImageManager; -import net.momirealms.craftengine.core.util.AdventureHelper; import net.momirealms.craftengine.core.util.CharacterUtils; import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerCommandPreprocessEvent; import java.lang.reflect.InvocationTargetException; +import java.util.function.Consumer; public class BukkitImageManager extends AbstractImageManager implements Listener { private final BukkitCraftEngine plugin; @@ -42,52 +42,63 @@ public class BukkitImageManager extends AbstractImageManager implements Listener HandlerList.unregisterAll(this); } - @EventHandler + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) @SuppressWarnings("UnstableApiUsage") public void onChat(AsyncChatDecorateEvent event) { if (event.player() == null) return; + if (!this.isDefaultFontInUse()) return; this.processChatMessages(event); } - @EventHandler + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) @SuppressWarnings("UnstableApiUsage") public void onChatCommand(AsyncChatCommandDecorateEvent event) { if (event.player() == null) return; + if (!this.isDefaultFontInUse()) return; this.processChatMessages(event); } - @EventHandler + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void onCommand(PlayerCommandPreprocessEvent event) { - event.setMessage(processIllegalString(event.getMessage())); + if (!this.isDefaultFontInUse()) return; + runIfContainsIllegalCharacter(event.getMessage(), event::setMessage); } @SuppressWarnings("UnstableApiUsage") private void processChatMessages(AsyncChatDecorateEvent event) { try { - Object originalMessage = Reflections.clazz$AdventureComponent.cast(Reflections.field$AsyncChatDecorateEvent$originalMessage.get(event)); - JsonElement json = (JsonElement) Reflections.method$GsonComponentSerializer$serializeToTree.invoke(serializer, originalMessage); - String jsonMessage = AdventureHelper.jsonElementToStringJson(json); - if (!this.isDefaultFontInUse()) return; - String str = processIllegalString(jsonMessage); - Object component = Reflections.method$ComponentSerializer$deserialize.invoke(serializer, str); - Reflections.method$AsyncChatDecorateEvent$result.invoke(event, component); + Object originalMessage = Reflections.field$AsyncChatDecorateEvent$originalMessage.get(event); + String jsonMessage = (String) Reflections.method$ComponentSerializer$serialize.invoke(serializer, originalMessage); + runIfContainsIllegalCharacter(jsonMessage, (json) -> { + try { + Object component = Reflections.method$ComponentSerializer$deserialize.invoke(serializer, json); + Reflections.method$AsyncChatDecorateEvent$result.invoke(event, component); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + }); } catch (IllegalAccessException | InvocationTargetException e) { throw new RuntimeException(e); } } - private String processIllegalString(String string) { + private void runIfContainsIllegalCharacter(String string, Consumer callback) { + //noinspection DuplicatedCode char[] chars = string.toCharArray(); int[] codepoints = CharacterUtils.charsToCodePoints(chars); int[] newCodepoints = new int[codepoints.length]; + boolean hasIllegal = false; for (int i = 0; i < codepoints.length; i++) { int codepoint = codepoints[i]; - if (!this.isIllegalCharacter(codepoint)) { + if (!isIllegalCharacter(codepoint)) { newCodepoints[i] = codepoint; } else { newCodepoints[i] = '*'; + hasIllegal = true; } } - return new String(newCodepoints, 0, newCodepoints.length); + if (hasIllegal) { + callback.accept(new String(newCodepoints, 0, newCodepoints.length)); + } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java index 60566bdc6..7b07b6151 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java @@ -1,7 +1,6 @@ package net.momirealms.craftengine.bukkit.util; import com.google.common.collect.ImmutableList; -import com.google.gson.JsonElement; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; @@ -5204,9 +5203,15 @@ public class Reflections { ) ); + public static final Class clazz$AdventureComponent = requireNonNull( + ReflectionUtils.getClazz( + "net{}kyori{}adventure{}text{}Component".replace("{}", ".") + ) + ); + @SuppressWarnings("UnstableApiUsage") public static final Field field$AsyncChatDecorateEvent$originalMessage = requireNonNull( - ReflectionUtils.getDeclaredField(AsyncChatDecorateEvent.class, "originalMessage") + ReflectionUtils.getDeclaredField(AsyncChatDecorateEvent.class, clazz$AdventureComponent, 0) ); public static final Class clazz$ComponentSerializer = requireNonNull( @@ -5227,12 +5232,6 @@ public class Reflections { ) ); - public static final Class clazz$AdventureComponent = requireNonNull( - ReflectionUtils.getClazz( - "net{}kyori{}adventure{}text{}Component".replace("{}", ".") - ) - ); - public static final Method method$GsonComponentSerializer$builder = requireNonNull( ReflectionUtils.getMethod( clazz$GsonComponentSerializer, clazz$GsonComponentSerializer$Builder @@ -5245,15 +5244,15 @@ public class Reflections { ) ); - public static final Method method$GsonComponentSerializer$serializeToTree = requireNonNull( + public static final Method method$ComponentSerializer$serialize = requireNonNull( ReflectionUtils.getMethod( - clazz$GsonComponentSerializer, JsonElement.class, clazz$AdventureComponent + clazz$ComponentSerializer, Object.class, new String[] {"serialize"}, clazz$AdventureComponent ) ); public static final Method method$ComponentSerializer$deserialize = requireNonNull( ReflectionUtils.getMethod( - clazz$ComponentSerializer, Object.class, Object.class + clazz$ComponentSerializer, Object.class, new String[] {"deserialize"}, Object.class ) ); diff --git a/gradle.properties b/gradle.properties index 23d43ebf5..120f0f982 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.36 +project_version=0.0.37 config_version=15 lang_version=3 project_group=net.momirealms @@ -38,7 +38,7 @@ geantyref_version=1.3.16 zstd_version=1.5.6-9 commons_io_version=2.17.0 sparrow_nbt_version=0.3 -sparrow_util_version=0.30 +sparrow_util_version=0.31 fastutil_version=8.5.15 netty_version=4.1.119.Final joml_version=1.10.8