Correct component loop detector

This commit is contained in:
Thinkofdeath 2014-02-21 20:56:10 +00:00
parent 941450b4e4
commit 38f12840ca
3 changed files with 89 additions and 63 deletions

View File

@ -10,6 +10,7 @@ import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.HoverEvent;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet;
public class BaseComponentSerializer public class BaseComponentSerializer
{ {
@ -73,52 +74,66 @@ public class BaseComponentSerializer
protected void serialize(JsonObject object, BaseComponent component, JsonSerializationContext context) protected void serialize(JsonObject object, BaseComponent component, JsonSerializationContext context)
{ {
Preconditions.checkArgument( !ComponentSerializer.serializedComponents.get().contains( component ), "Component loop" ); boolean first = false;
ComponentSerializer.serializedComponents.get().add( component ); if ( ComponentSerializer.serializedComponents.get() == null ) {
if ( component.getColorRaw() != null ) first = true;
{ ComponentSerializer.serializedComponents.set( new HashSet<BaseComponent>( ) );
object.addProperty( "color", component.getColorRaw().getName() );
} }
if ( component.isBoldRaw() != null ) try
{ {
object.addProperty( "bold", component.isBoldRaw() ); Preconditions.checkArgument( !ComponentSerializer.serializedComponents.get().contains( component ), "Component loop" );
} ComponentSerializer.serializedComponents.get().add( component );
if ( component.isItalicRaw() != null ) if ( component.getColorRaw() != null )
{ {
object.addProperty( "italic", component.isItalicRaw() ); object.addProperty( "color", component.getColorRaw().getName() );
} }
if ( component.isUnderlinedRaw() != null ) if ( component.isBoldRaw() != null )
{ {
object.addProperty( "underlined", component.isUnderlinedRaw() ); object.addProperty( "bold", component.isBoldRaw() );
} }
if ( component.isStrikethroughRaw() != null ) if ( component.isItalicRaw() != null )
{ {
object.addProperty( "strikethrough", component.isStrikethroughRaw() ); object.addProperty( "italic", component.isItalicRaw() );
} }
if ( component.isObfuscatedRaw() != null ) if ( component.isUnderlinedRaw() != null )
{ {
object.addProperty( "obfuscated", component.isObfuscatedRaw() ); 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 ) if ( component.getExtra() != null )
{ {
object.add( "extra", context.serialize( component.getExtra() ) ); object.add( "extra", context.serialize( component.getExtra() ) );
} }
//Events //Events
if ( component.getClickEvent() != null ) 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(); ComponentSerializer.serializedComponents.get().remove( component );
clickEvent.addProperty( "action", component.getClickEvent().getAction().toString().toLowerCase() ); if (first) {
clickEvent.addProperty( "value", component.getClickEvent().getValue() ); ComponentSerializer.serializedComponents.set( null );
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 );
} }
} }
} }

View File

@ -16,7 +16,7 @@ import net.md_5.bungee.api.chat.TranslatableComponent;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.HashSet; import java.util.HashSet;
public class ComponentSerializer implements JsonSerializer<BaseComponent>, JsonDeserializer<BaseComponent> public class ComponentSerializer implements JsonDeserializer<BaseComponent>
{ {
private final static Gson gson = new GsonBuilder(). private final static Gson gson = new GsonBuilder().
@ -25,14 +25,7 @@ public class ComponentSerializer implements JsonSerializer<BaseComponent>, JsonD
registerTypeAdapter( TranslatableComponent.class, new TranslatableComponentSerializer() ). registerTypeAdapter( TranslatableComponent.class, new TranslatableComponentSerializer() ).
create(); create();
public final static ThreadLocal<HashSet<BaseComponent>> serializedComponents = new ThreadLocal<HashSet<BaseComponent>>() public final static ThreadLocal<HashSet<BaseComponent>> serializedComponents = new ThreadLocal<>();
{
@Override
protected HashSet<BaseComponent> initialValue()
{
return new HashSet<>();
}
};
public static BaseComponent[] parse(String json) public static BaseComponent[] parse(String json)
{ {
@ -70,15 +63,4 @@ public class ComponentSerializer implements JsonSerializer<BaseComponent>, JsonD
} }
return context.deserialize( json, TextComponent.class ); 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();
}
}
} }

View File

@ -81,21 +81,50 @@ public class ComponentsTest
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void testLoopSimple() { public void testLoopSimple()
{
TextComponent component = new TextComponent( "Testing" ); TextComponent component = new TextComponent( "Testing" );
component.addExtra( component ); component.addExtra( component );
ComponentSerializer.toString( component ); ComponentSerializer.toString( component );
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void testLoopComplex() { public void testLoopComplex()
{
TextComponent a = new TextComponent( "A" ); TextComponent a = new TextComponent( "A" );
TextComponent b = new TextComponent( "B" ); TextComponent b = new TextComponent( "B" );
b.setColor( ChatColor.AQUA );
TextComponent c = new TextComponent( "C" ); TextComponent c = new TextComponent( "C" );
c.setColor( ChatColor.RED );
a.addExtra( b ); a.addExtra( b );
b.addExtra( c ); b.addExtra( c );
c.addExtra( a ); c.addExtra( a );
ComponentSerializer.toString( 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 );
}
} }