#2893: Refactored Hover Code for Maintainability

This commit is contained in:
Mystiflow 2020-07-07 09:08:04 +10:00 committed by md_5
parent 4794fccfb8
commit bcc3460dda
No known key found for this signature in database
GPG Key ID: E8E901AC7C617C11
14 changed files with 384 additions and 373 deletions

View File

@ -1,28 +1,18 @@
package net.md_5.bungee.api.chat;
import com.google.common.base.Preconditions;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import net.md_5.bungee.api.chat.hover.content.Content;
import net.md_5.bungee.api.chat.hover.content.Entity;
import net.md_5.bungee.api.chat.hover.content.Item;
import net.md_5.bungee.api.chat.hover.content.Text;
@Getter
@ToString
@ -53,7 +43,8 @@ public final class HoverEvent
*/
public HoverEvent(Action action, Content... contents)
{
Preconditions.checkArgument( contents.length != 0, "Must contain at least one content" );
Preconditions.checkArgument( contents.length != 0,
"Must contain at least one content" );
this.action = action;
this.contents = new ArrayList<>();
for ( Content it : contents )
@ -75,7 +66,7 @@ public final class HoverEvent
// Old plugins may have somehow hacked BaseComponent[] into
// anything other than SHOW_TEXT action. Ideally continue support.
this.action = action;
this.contents = new ArrayList<>( Collections.singletonList( new ContentText( value ) ) );
this.contents = new ArrayList<>( Collections.singletonList( new Text( value ) ) );
this.legacy = true;
}
@ -90,249 +81,12 @@ public final class HoverEvent
*/
public void addContent(Content content) throws UnsupportedOperationException
{
Preconditions.checkArgument( !legacy || contents.size() == 0, "Legacy HoverEvent may not have more than one content" );
Preconditions.checkArgument( !legacy || contents.size() == 0,
"Legacy HoverEvent may not have more than one content" );
content.assertAction( action );
contents.add( content );
}
@ToString
@EqualsAndHashCode
public abstract static class Content
{
/**
* Required action for this content type.
*
* @return action
*/
abstract Action requiredAction();
/**
* Tests this content against an action
*
* @param input input to test
* @throws UnsupportedOperationException if action incompatible
*/
void assertAction(Action input) throws UnsupportedOperationException
{
if ( input != requiredAction() )
{
throw new UnsupportedOperationException( "Action " + input + " not compatible! Expected " + requiredAction() );
}
}
}
@Data
@ToString
public static class ContentText extends Content
{
/**
* The value.
*
* May be a component or raw text depending on constructor used.
*/
private Object value;
public ContentText(BaseComponent[] value)
{
this.value = value;
}
public ContentText(String value)
{
this.value = value;
}
@Override
Action requiredAction()
{
return Action.SHOW_TEXT;
}
@Override
public boolean equals(Object o)
{
if ( value instanceof BaseComponent[] )
{
return o instanceof ContentText
&& ( (ContentText) o ).value instanceof BaseComponent[]
&& Arrays.equals( (BaseComponent[]) value, (BaseComponent[]) ( (ContentText) o ).value );
} else
{
return value.equals( o );
}
}
@Override
public int hashCode()
{
return ( value instanceof BaseComponent[] ) ? Arrays.hashCode( (BaseComponent[]) value ) : value.hashCode();
}
public static class Serializer implements JsonSerializer<ContentText>, JsonDeserializer<ContentText>
{
@Override
public ContentText deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException
{
if ( element.isJsonArray() )
{
return new ContentText( context.<BaseComponent[]>deserialize( element, BaseComponent[].class ) );
} else if ( element.getAsJsonObject().isJsonPrimitive() )
{
return new ContentText( element.getAsJsonObject().getAsJsonPrimitive().getAsString() );
} else
{
return new ContentText( new BaseComponent[]
{
context.deserialize( element, BaseComponent.class )
} );
}
}
@Override
public JsonElement serialize(ContentText content, Type type, JsonSerializationContext context)
{
return context.serialize( content.getValue() );
}
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@EqualsAndHashCode(callSuper = true)
public static class ContentEntity extends Content
{
/**
* Namespaced entity ID.
*
* Will use 'minecraft:pig' if null.
*/
private String type;
/**
* Entity UUID in hyphenated hexadecimal format.
*
* Should be valid UUID. TODO : validate?
*/
@NonNull
private String id;
/**
* Name to display as the entity.
*
* This is optional and will be hidden if null.
*/
private BaseComponent name;
@Override
Action requiredAction()
{
return Action.SHOW_ENTITY;
}
public static class Serializer implements JsonSerializer<ContentEntity>, JsonDeserializer<ContentEntity>
{
@Override
public ContentEntity deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException
{
JsonObject value = element.getAsJsonObject();
return new ContentEntity(
( value.has( "type" ) ) ? value.get( "type" ).getAsString() : null,
value.get( "id" ).getAsString(),
( value.has( "name" ) ) ? context.deserialize( value.get( "name" ), BaseComponent.class ) : null
);
}
@Override
public JsonElement serialize(ContentEntity content, Type type, JsonSerializationContext context)
{
JsonObject object = new JsonObject();
object.addProperty( "type", ( content.getType() != null ) ? content.getType() : "minecraft:pig" );
object.addProperty( "id", content.getId() );
if ( content.getName() != null )
{
object.add( "name", context.serialize( content.getName() ) );
}
return object;
}
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@EqualsAndHashCode(callSuper = true)
public static class ContentItem extends Content
{
/**
* Namespaced item ID. Will use 'minecraft:air' if null.
*/
private String id;
/**
* Optional. Size of the item stack.
*/
private int count = -1;
/**
* Optional. Item tag.
*/
private ItemTag tag;
@Override
Action requiredAction()
{
return Action.SHOW_ITEM;
}
public static class Serializer implements JsonSerializer<ContentItem>, JsonDeserializer<ContentItem>
{
@Override
public ContentItem deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException
{
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(
( value.has( "id" ) ) ? value.get( "id" ).getAsString() : null,
count,
( value.has( "tag" ) ) ? context.deserialize( value.get( "tag" ), ItemTag.class ) : null
);
}
@Override
public JsonElement serialize(ContentItem content, Type type, JsonSerializationContext context)
{
JsonObject object = new JsonObject();
object.addProperty( "id", ( content.getId() == null ) ? "minecraft:air" : content.getId() );
if ( content.getCount() != -1 )
{
object.addProperty( "Count", content.getCount() );
}
if ( content.getTag() != null )
{
object.add( "tag", context.serialize( content.getTag() ) );
}
return object;
}
}
}
public enum Action
{
@ -363,11 +117,11 @@ public final class HoverEvent
switch ( action )
{
case SHOW_TEXT:
return ( array ) ? HoverEvent.ContentText[].class : HoverEvent.ContentText.class;
return ( array ) ? Text[].class : Text.class;
case SHOW_ENTITY:
return ( array ) ? HoverEvent.ContentEntity[].class : HoverEvent.ContentEntity.class;
return ( array ) ? Entity[].class : Entity.class;
case SHOW_ITEM:
return ( array ) ? HoverEvent.ContentItem[].class : HoverEvent.ContentItem.class;
return ( array ) ? Item[].class : Item.class;
default:
throw new UnsupportedOperationException( "Action '" + action.name() + " not supported" );
}

View File

@ -1,20 +1,18 @@
package net.md_5.bungee.api.chat;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.Singular;
@ -23,23 +21,32 @@ import lombok.ToString;
/**
* Metadata for use in conjunction with {@link HoverEvent.Action#SHOW_ITEM}
*/
@ToString(callSuper = true)
@Builder(builderClassName = "Builder", access = AccessLevel.PRIVATE)
@ToString(of = "nbt")
@EqualsAndHashCode(of = "nbt")
@Setter
@Builder(builderClassName = "Builder", access = AccessLevel.PUBLIC)
@AllArgsConstructor
@EqualsAndHashCode
public final class ItemTag
{
@Getter
private final String nbt;
private BaseComponent name;
@Singular("ench")
private List<Enchantment> enchantments = new ArrayList<>();
private List<Enchantment> enchantments;
@Singular("lore")
private List<BaseComponent[]> lore = new ArrayList<>();
private List<BaseComponent[]> lore;
private Boolean unbreakable;
private ItemTag()
private ItemTag(String nbt)
{
this.nbt = nbt;
}
public static ItemTag ofNbt(String nbt)
{
return new ItemTag( nbt );
}
@RequiredArgsConstructor
@ -56,103 +63,13 @@ public final class ItemTag
@Override
public ItemTag deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException
{
ItemTag itemTag = new ItemTag();
JsonObject object = element.getAsJsonObject();
if ( object.has( "ench" ) )
{
for ( JsonElement jsonElement : object.get( "ench" ).getAsJsonArray() )
{
JsonObject next = jsonElement.getAsJsonObject();
itemTag.enchantments.add( new Enchantment( next.get( "id" ).getAsInt(), next.get( "lvl" ).getAsInt() ) );
}
}
if ( object.has( "Unbreakable" ) )
{
int status = object.get( "Unbreakable" ).getAsInt();
if ( status == 1 )
{
itemTag.unbreakable = true;
} else if ( status == 0 )
{
itemTag.unbreakable = false;
}
}
if ( object.has( "display" ) )
{
JsonObject display = object.get( "display" ).getAsJsonObject();
if ( display.has( "Name" ) )
{
itemTag.name = context.deserialize( display.get( "Name" ).getAsJsonObject(), BaseComponent.class );
}
if ( display.has( "Lore" ) )
{
JsonElement lore = display.get( "Lore" );
if ( lore.isJsonArray() )
{
for ( JsonElement loreIt : lore.getAsJsonArray() )
{
if ( loreIt.isJsonArray() )
{
itemTag.lore.add( context.deserialize( loreIt, BaseComponent[].class ) );
} else
{
itemTag.lore.add( new BaseComponent[]
{
context.deserialize( loreIt, BaseComponent.class )
} );
}
}
} else
{
itemTag.lore.add( context.deserialize( display.get( "Lore" ), BaseComponent[].class ) );
}
}
}
return itemTag;
return ofNbt( element.toString().replace( "\"", "" ) );
}
@Override
public JsonElement serialize(ItemTag itemTag, Type type, JsonSerializationContext context)
{
JsonObject object = new JsonObject();
if ( !itemTag.enchantments.isEmpty() )
{
JsonArray enchArray = new JsonArray();
for ( Enchantment ench : itemTag.enchantments )
{
JsonObject enchObj = new JsonObject();
enchObj.addProperty( "id", ench.id );
enchObj.addProperty( "lvl", ench.level );
enchArray.add( enchObj );
}
object.add( "ench", enchArray );
}
if ( itemTag.unbreakable != null )
{
object.addProperty( "Unbreakable", ( itemTag.unbreakable ) ? 1 : 0 );
}
JsonObject display = new JsonObject();
if ( itemTag.name != null )
{
display.add( "Name", context.serialize( itemTag.name ) );
}
if ( !itemTag.lore.isEmpty() )
{
display.add( "Lore", context.serialize( itemTag.lore ) );
}
if ( display.size() != 0 )
{
object.add( "display", display );
}
return object;
return context.serialize( itemTag.getNbt() );
}
}
}

View File

@ -0,0 +1,32 @@
package net.md_5.bungee.api.chat.hover.content;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import net.md_5.bungee.api.chat.HoverEvent;
@ToString
@EqualsAndHashCode
public abstract class Content
{
/**
* Required action for this content type.
*
* @return action
*/
public abstract HoverEvent.Action requiredAction();
/**
* Tests this content against an action
*
* @param input input to test
* @throws UnsupportedOperationException if action incompatible
*/
public void assertAction(HoverEvent.Action input) throws UnsupportedOperationException
{
if ( input != requiredAction() )
{
throw new UnsupportedOperationException( "Action " + input + " not compatible! Expected " + requiredAction() );
}
}
}

View File

@ -0,0 +1,43 @@
package net.md_5.bungee.api.chat.hover.content;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.ToString;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.HoverEvent;
@Data
@AllArgsConstructor
@ToString
@EqualsAndHashCode(callSuper = true)
public class Entity extends Content
{
/**
* Namespaced entity ID.
*
* Will use 'minecraft:pig' if null.
*/
private String type;
/**
* Entity UUID in hyphenated hexadecimal format.
*
* Should be valid UUID. TODO : validate?
*/
@NonNull
private String id;
/**
* Name to display as the entity.
*
* This is optional and will be hidden if null.
*/
private BaseComponent name;
@Override
public HoverEvent.Action requiredAction()
{
return HoverEvent.Action.SHOW_ENTITY;
}
}

View File

@ -0,0 +1,40 @@
package net.md_5.bungee.api.chat.hover.content;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
import net.md_5.bungee.api.chat.BaseComponent;
public class EntitySerializer implements JsonSerializer<Entity>, JsonDeserializer<Entity>
{
@Override
public Entity deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException
{
JsonObject value = element.getAsJsonObject();
return new Entity(
( value.has( "type" ) ) ? value.get( "type" ).getAsString() : null,
value.get( "id" ).getAsString(),
( value.has( "name" ) ) ? context.deserialize( value.get( "name" ), BaseComponent.class ) : null
);
}
@Override
public JsonElement serialize(Entity content, Type type, JsonSerializationContext context)
{
JsonObject object = new JsonObject();
object.addProperty( "type", ( content.getType() != null ) ? content.getType() : "minecraft:pig" );
object.addProperty( "id", content.getId() );
if ( content.getName() != null )
{
object.add( "name", context.serialize( content.getName() ) );
}
return object;
}
}

View File

@ -0,0 +1,35 @@
package net.md_5.bungee.api.chat.hover.content;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.ItemTag;
@Data
@AllArgsConstructor
@ToString
@EqualsAndHashCode(callSuper = false)
public class Item extends Content
{
/**
* Namespaced item ID. Will use 'minecraft:air' if null.
*/
private String id;
/**
* Optional. Size of the item stack.
*/
private int count = -1;
/**
* Optional. Item tag.
*/
private ItemTag tag;
@Override
public HoverEvent.Action requiredAction()
{
return HoverEvent.Action.SHOW_ITEM;
}
}

View File

@ -0,0 +1,69 @@
package net.md_5.bungee.api.chat.hover.content;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
import net.md_5.bungee.api.chat.ItemTag;
public class ItemSerializer implements JsonSerializer<Item>, JsonDeserializer<Item>
{
@Override
public Item deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException
{
JsonObject value = element.getAsJsonObject();
int count = -1;
if ( value.has( "Count" ) )
{
JsonPrimitive countObj = value.get( "Count" ).getAsJsonPrimitive();
if ( countObj.isNumber() )
{
count = countObj.getAsInt();
} else if ( countObj.isString() )
{
String cString = countObj.getAsString();
if ( cString.endsWith( "b" ) )
{
cString = cString.substring( 0, cString.length() - 1 );
}
try
{
count = Integer.parseInt( cString );
} catch ( NumberFormatException ex )
{
throw new JsonParseException( "Could not parse count: " + ex );
}
}
}
return new Item(
( value.has( "id" ) ) ? value.get( "id" ).getAsString() : null,
count,
( value.has( "tag" ) ) ? context.deserialize( value.get( "tag" ), ItemTag.class ) : null
);
}
@Override
public JsonElement serialize(Item content, Type type, JsonSerializationContext context)
{
JsonObject object = new JsonObject();
object.addProperty( "id", ( content.getId() == null ) ? "minecraft:air" : content.getId() );
if ( content.getCount() != -1 )
{
object.addProperty( "Count", content.getCount() );
}
if ( content.getTag() != null )
{
object.add( "tag", context.serialize( content.getTag() ) );
}
return object;
}
}

View File

@ -0,0 +1,56 @@
package net.md_5.bungee.api.chat.hover.content;
import java.util.Arrays;
import lombok.Getter;
import lombok.ToString;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.HoverEvent;
@Getter
@ToString
public class Text extends Content
{
/**
* The value.
*
* May be a component or raw text depending on constructor used.
*/
private final Object value;
public Text(BaseComponent[] value)
{
this.value = value;
}
public Text(String value)
{
this.value = value;
}
@Override
public HoverEvent.Action requiredAction()
{
return HoverEvent.Action.SHOW_TEXT;
}
@Override
public boolean equals(Object o)
{
if ( value instanceof BaseComponent[] )
{
return o instanceof Text
&& ( (Text) o ).value instanceof BaseComponent[]
&& Arrays.equals( (BaseComponent[]) value, (BaseComponent[]) ( (Text) o ).value );
} else
{
return value.equals( o );
}
}
@Override
public int hashCode()
{
return ( value instanceof BaseComponent[] ) ? Arrays.hashCode( (BaseComponent[]) value ) : value.hashCode();
}
}

View File

@ -0,0 +1,38 @@
package net.md_5.bungee.api.chat.hover.content;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
import net.md_5.bungee.api.chat.BaseComponent;
public class TextSerializer implements JsonSerializer<Text>, JsonDeserializer<Text>
{
@Override
public Text deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException
{
if ( element.isJsonArray() )
{
return new Text( context.<BaseComponent[]>deserialize( element, BaseComponent[].class ) );
} else if ( element.getAsJsonObject().isJsonPrimitive() )
{
return new Text( element.getAsJsonObject().getAsJsonPrimitive().getAsString() );
} else
{
return new Text( new BaseComponent[]
{
context.deserialize( element, BaseComponent.class )
} );
}
}
@Override
public JsonElement serialize(Text content, Type type, JsonSerializationContext context)
{
return context.serialize( content.getValue() );
}
}

View File

@ -14,6 +14,7 @@ import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.hover.content.Content;
public class BaseComponentSerializer
{
@ -77,14 +78,14 @@ public class BaseComponentSerializer
{
continue;
}
HoverEvent.Content[] list;
Content[] list;
JsonElement contents = event.get( type );
if ( contents.isJsonArray() )
{
list = context.deserialize( contents, HoverEvent.getClass( action, true ) );
} else
{
list = new HoverEvent.Content[]
list = new Content[]
{
context.deserialize( contents, HoverEvent.getClass( action, false ) )
};

View File

@ -11,13 +11,18 @@ import com.google.gson.JsonParser;
import java.lang.reflect.Type;
import java.util.Set;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.ItemTag;
import net.md_5.bungee.api.chat.KeybindComponent;
import net.md_5.bungee.api.chat.ScoreComponent;
import net.md_5.bungee.api.chat.SelectorComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.TranslatableComponent;
import net.md_5.bungee.api.chat.hover.content.Entity;
import net.md_5.bungee.api.chat.hover.content.EntitySerializer;
import net.md_5.bungee.api.chat.hover.content.Item;
import net.md_5.bungee.api.chat.hover.content.ItemSerializer;
import net.md_5.bungee.api.chat.hover.content.Text;
import net.md_5.bungee.api.chat.hover.content.TextSerializer;
public class ComponentSerializer implements JsonDeserializer<BaseComponent>
{
@ -30,9 +35,9 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent>
registerTypeAdapter( KeybindComponent.class, new KeybindComponentSerializer() ).
registerTypeAdapter( ScoreComponent.class, new ScoreComponentSerializer() ).
registerTypeAdapter( SelectorComponent.class, new SelectorComponentSerializer() ).
registerTypeAdapter( HoverEvent.ContentEntity.class, new HoverEvent.ContentEntity.Serializer() ).
registerTypeAdapter( HoverEvent.ContentText.class, new HoverEvent.ContentText.Serializer() ).
registerTypeAdapter( HoverEvent.ContentItem.class, new HoverEvent.ContentItem.Serializer() ).
registerTypeAdapter( Entity.class, new EntitySerializer() ).
registerTypeAdapter( Text.class, new TextSerializer() ).
registerTypeAdapter( Item.class, new ItemSerializer() ).
registerTypeAdapter( ItemTag.class, new ItemTag.Serializer() ).
create();

View File

@ -20,8 +20,12 @@ public class TextComponentSerializer extends BaseComponentSerializer implements
{
TextComponent component = new TextComponent();
JsonObject object = json.getAsJsonObject();
deserialize( object, component, context );
if ( !object.has( "text" ) )
{
throw new JsonParseException( "Could not parse JSON: missing 'text' property" );
}
component.setText( object.get( "text" ).getAsString() );
deserialize( object, component, context );
return component;
}

View File

@ -5,6 +5,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.hover.content.Item;
import net.md_5.bungee.api.chat.hover.content.Text;
import net.md_5.bungee.chat.ComponentSerializer;
import org.junit.Assert;
import org.junit.Test;
@ -20,6 +22,19 @@ public class ComponentsTest
String serialised = ComponentSerializer.toString( component );
BaseComponent[] deserialised = ComponentSerializer.parse( serialised );
Assert.assertEquals( TextComponent.toLegacyText( deserialised ), TextComponent.toLegacyText( component ) );
//////////
TextComponent component1 = new TextComponent( "HoverableText" );
String nbt = "{display:{Name:{text:Hello},Lore:[{text:Line_1},{text:Line_2}]},ench:[{id:49,lvl:5}],Unbreakable:1}}";
Item contentItem = new Item( "minecraft:wood", 1, ItemTag.ofNbt( nbt ) );
HoverEvent hoverEvent = new HoverEvent( HoverEvent.Action.SHOW_ITEM, contentItem );
component1.setHoverEvent( hoverEvent );
json = ComponentSerializer.toString( component1 );
component = ComponentSerializer.parse( json );
Item parsedContentItem = ( (Item) component[0].getHoverEvent().getContents().get( 0 ) );
Assert.assertEquals( contentItem, parsedContentItem );
Assert.assertEquals( contentItem.getCount(), parsedContentItem.getCount() );
Assert.assertEquals( contentItem.getId(), parsedContentItem.getId() );
Assert.assertEquals( nbt, parsedContentItem.getTag().getNbt() );
}
@Test
@ -134,6 +149,7 @@ public class ComponentsTest
);
}
/*
@Test
public void testItemTag()
{
@ -154,6 +170,7 @@ public class ComponentsTest
BaseComponent[] deserialised = ComponentSerializer.parse( serialised );
Assert.assertEquals( TextComponent.toLegacyText( deserialised ), TextComponent.toLegacyText( component ) );
}
*/
@Test
public void testModernShowAdvancement()
@ -162,13 +179,13 @@ public class ComponentsTest
// First do the text using the newer contents system
HoverEvent hoverEvent = new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
new HoverEvent.ContentText( advancement )
new Text( advancement )
);
TextComponent component = new TextComponent( "test" );
component.setHoverEvent( hoverEvent );
Assert.assertEquals( component.getHoverEvent().getContents().size(), 1 );
Assert.assertTrue( component.getHoverEvent().getContents().get( 0 ) instanceof HoverEvent.ContentText );
Assert.assertEquals( ( (HoverEvent.ContentText) component.getHoverEvent().getContents().get( 0 ) ).getValue(), advancement );
Assert.assertTrue( component.getHoverEvent().getContents().get( 0 ) instanceof Text );
Assert.assertEquals( ( (Text) component.getHoverEvent().getContents().get( 0 ) ).getValue(), advancement );
}
@Test
@ -177,8 +194,8 @@ public class ComponentsTest
// First do the text using the newer contents system
HoverEvent hoverEvent = new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
new HoverEvent.ContentText( new ComponentBuilder( "First" ).create() ),
new HoverEvent.ContentText( new ComponentBuilder( "Second" ).create() )
new Text( new ComponentBuilder( "First" ).create() ),
new Text( new ComponentBuilder( "Second" ).create() )
);
TextComponent component = new TextComponent( "Sample text" );

View File

@ -7,9 +7,9 @@ import java.util.regex.Pattern;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.ScoreComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.hover.content.Content;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.score.Score;
import net.md_5.bungee.protocol.ProtocolConstants;
@ -49,7 +49,7 @@ public final class ChatComponentTransformer
next.getHoverEvent().setLegacy( true );
if ( next.getHoverEvent().getContents().size() > 1 )
{
HoverEvent.Content exception = next.getHoverEvent().getContents().get( 0 );
Content exception = next.getHoverEvent().getContents().get( 0 );
next.getHoverEvent().getContents().clear();
next.getHoverEvent().getContents().add( exception );
}