diff --git a/Spigot-Server-Patches/0534-Fix-serialization-of-colors-from-components.patch b/Spigot-Server-Patches/0534-Fix-serialization-of-colors-from-components.patch index 0cfae32a75..c3ced25056 100644 --- a/Spigot-Server-Patches/0534-Fix-serialization-of-colors-from-components.patch +++ b/Spigot-Server-Patches/0534-Fix-serialization-of-colors-from-components.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: wea_ondara -Date: Sat, 2 Nov 2019 22:25:40 +0100 +From: Aikar +Date: Sun, 31 May 2020 21:55:52 -0400 Subject: [PATCH] Fix serialization of colors from components This patch fixes the serialization of display names, item lores and @@ -13,8 +13,11 @@ saving an ItemStack in a Yaml config). Spigot has now made the issue worse and expanded the scope to more places. +Original work by (but impl pretty much fully changed): +Co-Authored-By: wea_ondara + diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java -index 2e162b9ea31c8bf81cfa5282566b37fc29537f51..e2fbbfdd5b678f632ddbd68ec33a7cd9adfd4955 100644 +index 2e162b9ea31c8bf81cfa5282566b37fc29537f51..7edb88d515e3dab0d81b8f7a545ab614b4b51489 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java @@ -67,7 +67,7 @@ public final class CraftChatMessage { @@ -26,35 +29,43 @@ index 2e162b9ea31c8bf81cfa5282566b37fc29537f51..e2fbbfdd5b678f632ddbd68ec33a7cd9 } else if (format.isFormat()) { switch (format) { case BOLD: -@@ -172,9 +172,26 @@ public final class CraftChatMessage { +@@ -94,7 +94,11 @@ public final class CraftChatMessage { + break; + case 2: + if (keepNewlines) { +- currentChatComponent.addSibling(new ChatComponentText("\n")); ++ // Paper start - retain formatting for new lines ++ ChatComponentText ichatbasecomponent = new ChatComponentText("\n"); ++ ichatbasecomponent.setChatModifier(modifier.clone()); ++ currentChatComponent.addSibling(ichatbasecomponent); ++ // Paper end + } else { + currentChatComponent = null; + } +@@ -172,9 +176,21 @@ public final class CraftChatMessage { if (component == null) return ""; StringBuilder out = new StringBuilder(); + // Paper start - fix deletion of color codes at the beginning of result string -+ boolean first = true; ++ boolean hadColor = false; for (IChatBaseComponent c : (Iterable) component) { ChatModifier modi = c.getChatModifier(); - out.append(modi.getColor() == null ? defaultColor : modi.getColor()); + EnumChatFormat color = modi.getColor(); -+ if (first) { ++ if (!c.getText().isEmpty() || color != null) { + if (color != null) { + out.append(color); -+ } -+ if (!c.getText().isEmpty() || color != null) { -+ first = false; -+ } -+ } else if (!c.getText().isEmpty() || color != null) { -+ if (color != null) { -+ out.append(color); -+ } else if (defaultColor != null) { -+ out.append(defaultColor); ++ hadColor = true; ++ } else if (hadColor) { ++ out.append(ChatColor.RESET); ++ hadColor = false; + } + } + // Paper end if (modi.isBold()) { out.append(EnumChatFormat.BOLD); } -@@ -192,7 +209,7 @@ public final class CraftChatMessage { +@@ -192,7 +208,7 @@ public final class CraftChatMessage { } out.append(c.getText()); } @@ -65,15 +76,13 @@ index 2e162b9ea31c8bf81cfa5282566b37fc29537f51..e2fbbfdd5b678f632ddbd68ec33a7cd9 public static IChatBaseComponent fixComponent(IChatBaseComponent component) { diff --git a/src/test/java/org/bukkit/craftbukkit/CraftChatMessageTest.java b/src/test/java/org/bukkit/craftbukkit/CraftChatMessageTest.java new file mode 100644 -index 0000000000000000000000000000000000000000..4a3b3ef168415ec8813afaa9f0c1657b078f8bf4 +index 0000000000000000000000000000000000000000..759049174d2113837aa06faea82ddcc683b4d9c6 --- /dev/null +++ b/src/test/java/org/bukkit/craftbukkit/CraftChatMessageTest.java -@@ -0,0 +1,56 @@ +@@ -0,0 +1,61 @@ +package org.bukkit.craftbukkit; + -+import net.minecraft.server.EnumChatFormat; +import net.minecraft.server.IChatBaseComponent; -+import org.bukkit.ChatColor; +import org.bukkit.craftbukkit.util.CraftChatMessage; +import org.bukkit.support.AbstractTestingBase; +import org.junit.Test; @@ -83,21 +92,25 @@ index 0000000000000000000000000000000000000000..4a3b3ef168415ec8813afaa9f0c1657b +public class CraftChatMessageTest extends AbstractTestingBase { + @Test + public void testSimpleStrings() { -+ testString("&fFoo", EnumChatFormat.WHITE); -+ testString("Foo", EnumChatFormat.WHITE); -+ testString("Foo&bBar", EnumChatFormat.WHITE); -+ testString("Foo&bBar", EnumChatFormat.AQUA); -+ testString("&fFoo&bBar", EnumChatFormat.WHITE); -+ testString("&rFoo", EnumChatFormat.WHITE); ++ testString("§fFoo"); ++ testString("Foo"); ++ testString("Foo§bBar"); ++ testString("Foo§bBar"); ++ testString("§fFoo§bBar"); ++ testString("§fFoo§bBar§rBaz"); ++ testString("§rFoo"); ++ testString("Test§0\n§0\n§5Test"); + } + + @Test + public void testComponents() { -+ testComponent("Foo&bBar&fBaz", EnumChatFormat.WHITE, create("Foo", "&bBar", "Baz")); -+ testComponent("&fFoo&bBar&fBaz", EnumChatFormat.WHITE, create("", "&fFoo", "&bBar", "Baz")); -+ testComponent("Foo&bBar&fBaz", EnumChatFormat.WHITE, create("", "Foo", "&bBar", "Baz")); -+ testComponent("&fFoo&bBar&fBaz", EnumChatFormat.WHITE, create("&fFoo", "&bBar", "Baz")); -+ testComponent("F&foo&bBar&fBaz", EnumChatFormat.WHITE, create("F&foo", "&bBar", "Baz")); ++ testComponent("Foo§bBar§rBaz", create("Foo", "§bBar", "Baz")); ++ testComponent("§fFoo§bBar§rBaz", create("", "§fFoo", "§bBar", "Baz")); ++ testComponent("§fFoo§bBar§rBaz", create("", "§fFoo", "§bBar", "", "Baz")); ++ testComponent("§fFoo§bBar§rBaz", create("§fFoo", "§bBar", "Baz")); ++ testComponent("Foo§bBar§rBaz", create("", "Foo", "§bBar", "Baz")); ++ testComponent("§fFoo§bBar§rBaz", create("§fFoo", "§bBar", "Baz")); ++ testComponent("F§foo§bBar§rBaz", create("F§foo", "§bBar", "Baz")); + } + + private IChatBaseComponent create(String txt, String ...rest) { @@ -110,18 +123,21 @@ index 0000000000000000000000000000000000000000..4a3b3ef168415ec8813afaa9f0c1657b + } + + private IChatBaseComponent toComp(String txt) { -+ return CraftChatMessage.fromString(ChatColor.translateAlternateColorCodes('&', txt))[0]; ++ return CraftChatMessage.fromString(txt, true)[0]; + } + -+ private void testString(String expected, EnumChatFormat defColor) { -+ expected = ChatColor.translateAlternateColorCodes('&', expected); -+ IChatBaseComponent cmp = CraftChatMessage.fromStringOrNull(expected); -+ testComponent(expected, defColor, cmp); -+ } -+ -+ private void testComponent(String expected, EnumChatFormat defColor, IChatBaseComponent components) { -+ expected = ChatColor.translateAlternateColorCodes('&', expected); -+ String actual = CraftChatMessage.fromComponent(components, defColor); ++ private void testString(String expected) { ++ IChatBaseComponent cmp = toComp(expected); ++ String actual = CraftChatMessage.fromComponent(cmp); + assertEquals(expected, actual); + } ++ ++ private void testComponent(String expected, IChatBaseComponent components) { ++ String actual = CraftChatMessage.fromComponent(components); ++ assertEquals(expected, actual); ++ ++ IChatBaseComponent expectedCmp = toComp(expected); ++ String actualExpectedCmp = CraftChatMessage.fromComponent(expectedCmp); ++ assertEquals(expected, actualExpectedCmp); ++ } +}