diff --git a/api/src/main/java/net/md_5/bungee/chat/BaseComponentSerializer.java b/api/src/main/java/net/md_5/bungee/chat/BaseComponentSerializer.java index 344cb38a..d4afbd42 100644 --- a/api/src/main/java/net/md_5/bungee/chat/BaseComponentSerializer.java +++ b/api/src/main/java/net/md_5/bungee/chat/BaseComponentSerializer.java @@ -10,6 +10,7 @@ import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.HoverEvent; import java.util.Arrays; +import java.util.HashSet; public class BaseComponentSerializer { @@ -73,52 +74,66 @@ public class BaseComponentSerializer protected void serialize(JsonObject object, BaseComponent component, JsonSerializationContext context) { - Preconditions.checkArgument( !ComponentSerializer.serializedComponents.get().contains( component ), "Component loop" ); - ComponentSerializer.serializedComponents.get().add( component ); - if ( component.getColorRaw() != null ) - { - object.addProperty( "color", component.getColorRaw().getName() ); + boolean first = false; + if ( ComponentSerializer.serializedComponents.get() == null ) { + first = true; + ComponentSerializer.serializedComponents.set( new HashSet( ) ); } - if ( component.isBoldRaw() != null ) + try { - object.addProperty( "bold", component.isBoldRaw() ); - } - if ( component.isItalicRaw() != null ) - { - object.addProperty( "italic", component.isItalicRaw() ); - } - if ( component.isUnderlinedRaw() != null ) - { - object.addProperty( "underlined", component.isUnderlinedRaw() ); - } - if ( component.isStrikethroughRaw() != null ) - { - object.addProperty( "strikethrough", component.isStrikethroughRaw() ); - } - if ( component.isObfuscatedRaw() != null ) - { - object.addProperty( "obfuscated", component.isObfuscatedRaw() ); - } + Preconditions.checkArgument( !ComponentSerializer.serializedComponents.get().contains( component ), "Component loop" ); + ComponentSerializer.serializedComponents.get().add( component ); + if ( component.getColorRaw() != null ) + { + object.addProperty( "color", component.getColorRaw().getName() ); + } + if ( component.isBoldRaw() != null ) + { + object.addProperty( "bold", component.isBoldRaw() ); + } + if ( component.isItalicRaw() != null ) + { + object.addProperty( "italic", component.isItalicRaw() ); + } + if ( component.isUnderlinedRaw() != null ) + { + object.addProperty( "underlined", component.isUnderlinedRaw() ); + } + if ( component.isStrikethroughRaw() != null ) + { + object.addProperty( "strikethrough", component.isStrikethroughRaw() ); + } + if ( component.isObfuscatedRaw() != null ) + { + object.addProperty( "obfuscated", component.isObfuscatedRaw() ); + } - if ( component.getExtra() != null ) - { - object.add( "extra", context.serialize( component.getExtra() ) ); - } + if ( component.getExtra() != null ) + { + object.add( "extra", context.serialize( component.getExtra() ) ); + } - //Events - if ( component.getClickEvent() != null ) + //Events + if ( component.getClickEvent() != null ) + { + JsonObject clickEvent = new JsonObject(); + clickEvent.addProperty( "action", component.getClickEvent().getAction().toString().toLowerCase() ); + clickEvent.addProperty( "value", component.getClickEvent().getValue() ); + object.add( "clickEvent", clickEvent ); + } + if ( component.getHoverEvent() != null ) + { + JsonObject hoverEvent = new JsonObject(); + hoverEvent.addProperty( "action", component.getHoverEvent().getAction().toString().toLowerCase() ); + hoverEvent.add( "value", context.serialize( component.getHoverEvent().getValue() ) ); + object.add( "hoverEvent", hoverEvent ); + } + } finally { - JsonObject clickEvent = new JsonObject(); - clickEvent.addProperty( "action", component.getClickEvent().getAction().toString().toLowerCase() ); - clickEvent.addProperty( "value", component.getClickEvent().getValue() ); - object.add( "clickEvent", clickEvent ); - } - if ( component.getHoverEvent() != null ) - { - JsonObject hoverEvent = new JsonObject(); - hoverEvent.addProperty( "action", component.getHoverEvent().getAction().toString().toLowerCase() ); - hoverEvent.add( "value", context.serialize( component.getHoverEvent().getValue() ) ); - object.add( "hoverEvent", hoverEvent ); + ComponentSerializer.serializedComponents.get().remove( component ); + if (first) { + ComponentSerializer.serializedComponents.set( null ); + } } } } diff --git a/api/src/main/java/net/md_5/bungee/chat/ComponentSerializer.java b/api/src/main/java/net/md_5/bungee/chat/ComponentSerializer.java index d847fabd..cb663bdb 100644 --- a/api/src/main/java/net/md_5/bungee/chat/ComponentSerializer.java +++ b/api/src/main/java/net/md_5/bungee/chat/ComponentSerializer.java @@ -16,7 +16,7 @@ import net.md_5.bungee.api.chat.TranslatableComponent; import java.lang.reflect.Type; import java.util.HashSet; -public class ComponentSerializer implements JsonSerializer, JsonDeserializer +public class ComponentSerializer implements JsonDeserializer { private final static Gson gson = new GsonBuilder(). @@ -25,14 +25,7 @@ public class ComponentSerializer implements JsonSerializer, JsonD registerTypeAdapter( TranslatableComponent.class, new TranslatableComponentSerializer() ). create(); - public final static ThreadLocal> serializedComponents = new ThreadLocal>() - { - @Override - protected HashSet initialValue() - { - return new HashSet<>(); - } - }; + public final static ThreadLocal> serializedComponents = new ThreadLocal<>(); public static BaseComponent[] parse(String json) { @@ -70,15 +63,4 @@ public class ComponentSerializer implements JsonSerializer, JsonD } return context.deserialize( json, TextComponent.class ); } - - @Override - public JsonElement serialize(BaseComponent src, Type typeOfSrc, JsonSerializationContext context) - { - try { - return context.serialize( src, src.getClass() ); - } finally - { - serializedComponents.get().clear(); - } - } } diff --git a/proxy/src/test/java/net/md_5/bungee/chat/ComponentsTest.java b/proxy/src/test/java/net/md_5/bungee/chat/ComponentsTest.java index 8ba0d3c6..118972e8 100644 --- a/proxy/src/test/java/net/md_5/bungee/chat/ComponentsTest.java +++ b/proxy/src/test/java/net/md_5/bungee/chat/ComponentsTest.java @@ -81,21 +81,50 @@ public class ComponentsTest } @Test(expected = IllegalArgumentException.class) - public void testLoopSimple() { + public void testLoopSimple() + { TextComponent component = new TextComponent( "Testing" ); component.addExtra( component ); ComponentSerializer.toString( component ); } @Test(expected = IllegalArgumentException.class) - public void testLoopComplex() { + public void testLoopComplex() + { TextComponent a = new TextComponent( "A" ); TextComponent b = new TextComponent( "B" ); + b.setColor( ChatColor.AQUA ); TextComponent c = new TextComponent( "C" ); + c.setColor( ChatColor.RED ); a.addExtra( b ); b.addExtra( c ); c.addExtra( a ); ComponentSerializer.toString( a ); } + @Test + public void testRepeated() + { + TextComponent a = new TextComponent( "A" ); + TextComponent b = new TextComponent( "B" ); + b.setColor( ChatColor.AQUA ); + a.addExtra( b ); + a.addExtra( b ); + ComponentSerializer.toString( a ); + } + + @Test(expected = IllegalArgumentException.class) + public void testRepeatedError() + { + TextComponent a = new TextComponent( "A" ); + TextComponent b = new TextComponent( "B" ); + b.setColor( ChatColor.AQUA ); + TextComponent c = new TextComponent( "C" ); + c.setColor( ChatColor.RED ); + a.addExtra( b ); + a.addExtra( c ); + c.addExtra( a ); + a.addExtra( b ); + ComponentSerializer.toString( a ); + } }