#2884: Mojangson in hover events cannot be parsed

This commit is contained in:
Mystiflow 2020-07-05 19:09:59 +10:00 committed by md_5
parent 2e4b08e5ab
commit 637e7e93e0
No known key found for this signature in database
GPG Key ID: E8E901AC7C617C11
3 changed files with 34 additions and 10 deletions

View File

@ -6,6 +6,7 @@ import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer; import com.google.gson.JsonSerializer;
import java.lang.reflect.Type; import java.lang.reflect.Type;
@ -297,9 +298,19 @@ public final class HoverEvent
{ {
JsonObject value = element.getAsJsonObject(); JsonObject value = element.getAsJsonObject();
int count = -1;
if ( value.has( "Count" ) )
{
JsonPrimitive countObj = value.get( "Count" ).getAsJsonPrimitive();
count = ( countObj.isString() )
// NBT can serialize as {#int"b"} so remove the b
? Integer.parseInt( countObj.getAsString().substring( countObj.getAsString().length() - 1 ) )
: countObj.getAsInt();
}
return new ContentItem( return new ContentItem(
( value.has( "id" ) ) ? value.get( "id" ).getAsString() : null, ( value.has( "id" ) ) ? value.get( "id" ).getAsString() : null,
( value.has( "Count" ) ) ? value.get( "Count" ).getAsInt() : -1, count,
( value.has( "tag" ) ) ? context.deserialize( value.get( "tag" ), ItemTag.class ) : null ( value.has( "tag" ) ) ? context.deserialize( value.get( "tag" ), ItemTag.class ) : null
); );
} }

View File

@ -71,17 +71,14 @@ public class BaseComponentSerializer
HoverEvent hoverEvent = null; HoverEvent hoverEvent = null;
HoverEvent.Action action = HoverEvent.Action.valueOf( event.get( "action" ).getAsString().toUpperCase( Locale.ROOT ) ); HoverEvent.Action action = HoverEvent.Action.valueOf( event.get( "action" ).getAsString().toUpperCase( Locale.ROOT ) );
if ( event.has( "value" ) ) for ( String type : Arrays.asList( "value", "contents" ) )
{ {
HoverEvent.Content[] ret = new HoverEvent.Content[] if ( !event.has( type ) )
{ {
context.deserialize( event.get( "value" ), HoverEvent.getClass( action, false ) ) continue;
}; }
hoverEvent = new HoverEvent( action, ret );
} else if ( event.has( "contents" ) )
{
HoverEvent.Content[] list; HoverEvent.Content[] list;
JsonElement contents = event.get( "contents" ); JsonElement contents = event.get( type );
if ( contents.isJsonArray() ) if ( contents.isJsonArray() )
{ {
list = context.deserialize( contents, HoverEvent.getClass( action, true ) ); list = context.deserialize( contents, HoverEvent.getClass( action, true ) );
@ -94,8 +91,14 @@ public class BaseComponentSerializer
} }
hoverEvent = new HoverEvent( action, new ArrayList<>( Arrays.asList( list ) ) ); hoverEvent = new HoverEvent( action, new ArrayList<>( Arrays.asList( list ) ) );
// stop the loop as soon as either one is found
break;
}
if ( hoverEvent != null )
{
component.setHoverEvent( hoverEvent );
} }
component.setHoverEvent( hoverEvent );
} }
} }

View File

@ -12,6 +12,16 @@ import org.junit.Test;
public class ComponentsTest public class ComponentsTest
{ {
@Test
public void testItemParse()
{
String json = "{\"extra\":[{\"text\":\"[\"},{\"extra\":[{\"translate\":\"block.minecraft.dirt\"}],\"text\":\"\"},{\"text\":\"]\"}],\"hoverEvent\":{\"action\":\"show_item\",\"value\":[{\"text\":\"{id:\\\"minecraft:dirt\\\",Count:1b}\"}]},\"text\":\"\"}";
BaseComponent[] component = ComponentSerializer.parse( json );
String serialised = ComponentSerializer.toString( component );
BaseComponent[] deserialised = ComponentSerializer.parse( serialised );
Assert.assertEquals( TextComponent.toLegacyText( deserialised ), TextComponent.toLegacyText( component ) );
}
@Test @Test
public void testEmptyComponentBuilder() public void testEmptyComponentBuilder()
{ {