From 27a9998432add5cb85961a4ebfb36f730a452b0e Mon Sep 17 00:00:00 2001 From: Diogo Correia Date: Thu, 23 Jan 2025 16:40:40 +0100 Subject: [PATCH] feat: support 1.21.4+ shadowColor in component parser Closes #470 --- .../language/parser/AdvancedComponent.java | 17 +++++++++++++ .../triton/utils/ComponentUtils.java | 11 +++++++++ .../parser/AdvancedComponentTest.java | 24 +++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/core/src/main/java/com/rexcantor64/triton/language/parser/AdvancedComponent.java b/core/src/main/java/com/rexcantor64/triton/language/parser/AdvancedComponent.java index a3f7135f..6fc7e8cf 100644 --- a/core/src/main/java/com/rexcantor64/triton/language/parser/AdvancedComponent.java +++ b/core/src/main/java/com/rexcantor64/triton/language/parser/AdvancedComponent.java @@ -7,7 +7,9 @@ import lombok.val; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.*; +import net.md_5.bungee.api.chat.TextComponent; +import java.awt.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -48,6 +50,16 @@ public static AdvancedComponent fromBaseComponent(boolean onlyText, BaseComponen boolean hasHover = false; boolean hasFont = false; builder.append(ComponentUtils.getColorFromBaseComponent(comp).toString()); + try { + Color shadowColor = comp.getShadowColor(); + if (shadowColor != null) { + // getRGB also includes alpha information + builder.append("§s"); + builder.append(String.format("%08x", shadowColor.getRGB())); + } + } catch (NoSuchMethodError ignore) { + // old versions of Spigot don't have getShadowColor() + } if (comp.isBold()) builder.append(ChatColor.BOLD.toString()); if (comp.isItalic()) @@ -159,6 +171,11 @@ private List toBaseComponent(String text) { val color = text.substring(i + 1, i + 13); format = ChatColor.of("#" + color.replace("\u00A7", "")); i += 12; + } else if (lowercaseChar == 's' && i + 8 < text.length()) { + val color = text.substring(i + 1, i + 9); + component.setShadowColor(new Color(Integer.parseUnsignedInt(color, 16), true)); + i += 8; + continue; } else { format = ChatColor.getByChar(lowercaseChar); } diff --git a/core/src/main/java/com/rexcantor64/triton/utils/ComponentUtils.java b/core/src/main/java/com/rexcantor64/triton/utils/ComponentUtils.java index 4b6116df..97dd21a6 100644 --- a/core/src/main/java/com/rexcantor64/triton/utils/ComponentUtils.java +++ b/core/src/main/java/com/rexcantor64/triton/utils/ComponentUtils.java @@ -73,6 +73,11 @@ public static void copyFormatting(BaseComponent origin, BaseComponent target) { } catch (NoSuchMethodError ignore) { // Ignore, it's an outdated server } + try { + target.setShadowColor(origin.getShadowColorRaw()); + } catch (NoSuchMethodError ignore) { + // Ignore, it's an outdated server + } } public static ChatColor getColorFromBaseComponent(BaseComponent bc) { @@ -100,6 +105,12 @@ public static boolean haveSameFormatting(BaseComponent c1, BaseComponent c2) { } catch (NoSuchMethodError ignore) { // Ignore, it's an outdated server } + try { + if (!Objects.equals(c1.getShadowColorRaw(), c2.getShadowColorRaw())) + return false; + } catch (NoSuchMethodError ignore) { + // Ignore, it's an outdated server + } return c1.getColorRaw() == c2.getColorRaw() && c1.isBoldRaw() == c2.isBoldRaw() && c1.isItalicRaw() == c2.isItalicRaw() && diff --git a/core/src/test/java/com/rexcantor64/triton/language/parser/AdvancedComponentTest.java b/core/src/test/java/com/rexcantor64/triton/language/parser/AdvancedComponentTest.java index 7332f369..8b4e0b0d 100644 --- a/core/src/test/java/com/rexcantor64/triton/language/parser/AdvancedComponentTest.java +++ b/core/src/test/java/com/rexcantor64/triton/language/parser/AdvancedComponentTest.java @@ -8,6 +8,8 @@ import net.md_5.bungee.chat.ComponentSerializer; import org.junit.jupiter.api.Test; +import java.awt.*; + import static org.junit.jupiter.api.Assertions.assertEquals; public class AdvancedComponentTest { @@ -33,4 +35,26 @@ public void testColorCodeBetweenClickEvent() { String expectedResultJson = "{\"extra\":[{\"strikethrough\":true,\"color\":\"gray\",\"hoverEvent\":{\"action\":\"show_text\",\"contents\":\"\"},\"extra\":[{\"text\":\"Testing\"}],\"text\":\"\"},{\"color\":\"gray\",\"hoverEvent\":{\"action\":\"show_text\",\"contents\":\"\"},\"extra\":[{\"text\":\"another test\"}],\"text\":\"\"}],\"text\":\"\"}"; assertEquals(expectedResultJson, ComponentSerializer.toString(components)); } + + @Test + public void testShadowColor() { + BaseComponent root = new TextComponent(); + BaseComponent child1 = new TextComponent("Testing"); + child1.setColor(ChatColor.GRAY); + child1.setStrikethrough(true); + child1.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(""))); + root.addExtra(child1); + BaseComponent child2 = new TextComponent("another test"); + child2.setColor(ChatColor.GRAY); + child2.setShadowColor(new Color(0x33, 0x44, 0x55, 0x88)); + root.addExtra(child2); + + AdvancedComponent advancedComponent = AdvancedComponent.fromBaseComponent(root); + advancedComponent.setText(advancedComponent.getTextClean()); + + BaseComponent[] components = advancedComponent.toBaseComponent(); + + String expectedResultJson = "{\"extra\":[{\"strikethrough\":true,\"color\":\"gray\",\"hoverEvent\":{\"action\":\"show_text\",\"contents\":\"\"},\"extra\":[{\"text\":\"Testing\"}],\"text\":\"\"},{\"color\":\"gray\",\"shadow_color\":-2009906091,\"text\":\"another test\"}],\"text\":\"\"}"; + assertEquals(expectedResultJson, ComponentSerializer.toString(components)); + } }