Skip to content

Commit

Permalink
Improve legacy format serialization more
Browse files Browse the repository at this point in the history
This should now complete legacy serialization to avoid ever
changing the output content.

This removes the concept of "Default Color" from the method as
that entire concept was flawed and broke the intent of chat components.

Going to actually PR this patch to Spigot soon.

This now puts us back at a point where any data saved pre Spigot
breaking things will still save back the exact same way as before,

but new component -> legacy will now be fixed to not insert undesirable
default colors (such as black) into the legacy string, and instead use
the proper reset code.

This means you can now safety get the text from a book and
put it in chat or an entity display name without worry about black
color codes or other undesired color codes leaking into the new
context where that color doesn't make sense.
  • Loading branch information
aikar committed Jun 1, 2020
1 parent d6eda56 commit d7cfa4f
Showing 1 changed file with 55 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: wea_ondara <[email protected]>
Date: Sat, 2 Nov 2019 22:25:40 +0100
From: Aikar <[email protected]>
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
Expand All @@ -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 <[email protected]>

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 {
Expand All @@ -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<IChatBaseComponent>) 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());
}
Expand All @@ -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;
Expand All @@ -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) {
Expand All @@ -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 testString(String expected) {
+ IChatBaseComponent cmp = toComp(expected);
+ String actual = CraftChatMessage.fromComponent(cmp);
+ assertEquals(expected, actual);
+ }
+
+ private void testComponent(String expected, EnumChatFormat defColor, IChatBaseComponent components) {
+ expected = ChatColor.translateAlternateColorCodes('&', expected);
+ String actual = CraftChatMessage.fromComponent(components, defColor);
+ 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);
+ }
+}

0 comments on commit d7cfa4f

Please sign in to comment.