@@ -3,9 +3,7 @@ package net.md_5.bungee.api.chat;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@@ -25,13 +23,6 @@ public final class ClickEvent
|
||||
*/
|
||||
private final String value;
|
||||
|
||||
/**
|
||||
* Returns whether this click event is used for version above 1.21.4
|
||||
*/
|
||||
@Setter
|
||||
@ApiStatus.Internal
|
||||
private boolean v1_21_5 = false;
|
||||
|
||||
public enum Action
|
||||
{
|
||||
|
||||
|
@@ -13,7 +13,7 @@ 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;
|
||||
import net.md_5.bungee.chat.ComponentSerializer;
|
||||
import net.md_5.bungee.chat.VersionedComponentSerializer;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@Getter
|
||||
@@ -38,30 +38,6 @@ public final class HoverEvent
|
||||
@ApiStatus.Internal
|
||||
private boolean legacy = false;
|
||||
|
||||
/**
|
||||
* Returns whether this hover event is used for version above 1.21.4
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
private boolean v1_21_5 = false;
|
||||
|
||||
/**
|
||||
* Set the compatibility to 1.21.5, also modifies the underlying entities.
|
||||
*
|
||||
* @param v1_21_5 the compatibility to set
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public void setV1_21_5(boolean v1_21_5)
|
||||
{
|
||||
this.v1_21_5 = v1_21_5;
|
||||
for ( Content content : contents )
|
||||
{
|
||||
if ( content instanceof Entity )
|
||||
{
|
||||
( (Entity) content ).setV1_21_5( v1_21_5 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates event with an action and a list of contents.
|
||||
*
|
||||
@@ -106,7 +82,7 @@ public final class HoverEvent
|
||||
return (BaseComponent[]) ( (Text) content ).getValue();
|
||||
}
|
||||
|
||||
TextComponent component = new TextComponent( ComponentSerializer.toString( content ) );
|
||||
TextComponent component = new TextComponent( VersionedComponentSerializer.getDefault().toString( content ) );
|
||||
return new BaseComponent[]
|
||||
{
|
||||
component
|
||||
|
@@ -7,7 +7,6 @@ import lombok.NonNull;
|
||||
import lombok.ToString;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@@ -16,18 +15,6 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
public class Entity extends Content
|
||||
{
|
||||
|
||||
/**
|
||||
* Required for backwards compatibility.
|
||||
*
|
||||
* @param type the type of the entity, for example 'minecraft:pig'
|
||||
* @param id for example '6cb1b229-ce5c-4179-af8d-eea185c25963'
|
||||
* @param name the name of the entity
|
||||
*/
|
||||
public Entity(String type, @NonNull String id, BaseComponent name)
|
||||
{
|
||||
this( type, id, name, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Namespaced entity ID.
|
||||
*
|
||||
@@ -48,12 +35,6 @@ public class Entity extends Content
|
||||
*/
|
||||
private BaseComponent name;
|
||||
|
||||
/**
|
||||
* True if this entity is for 1.21.5 or later
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
private boolean v1_21_5;
|
||||
|
||||
@Override
|
||||
public HoverEvent.Action requiredAction()
|
||||
{
|
||||
|
@@ -10,10 +10,17 @@ import com.google.gson.JsonSerializer;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.UUID;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.chat.BaseComponentSerializer;
|
||||
import net.md_5.bungee.chat.VersionedComponentSerializer;
|
||||
|
||||
public class EntitySerializer implements JsonSerializer<Entity>, JsonDeserializer<Entity>
|
||||
public class EntitySerializer extends BaseComponentSerializer implements JsonSerializer<Entity>, JsonDeserializer<Entity>
|
||||
{
|
||||
|
||||
public EntitySerializer(VersionedComponentSerializer serializer)
|
||||
{
|
||||
super( serializer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException
|
||||
{
|
||||
@@ -34,8 +41,7 @@ public class EntitySerializer implements JsonSerializer<Entity>, JsonDeserialize
|
||||
return new Entity(
|
||||
( value.has( newEntity ? "id" : "type" ) ) ? value.get( newEntity ? "id" : "type" ).getAsString() : null,
|
||||
idString,
|
||||
( value.has( "name" ) ) ? context.deserialize( value.get( "name" ), BaseComponent.class ) : null,
|
||||
newEntity
|
||||
( value.has( "name" ) ) ? context.deserialize( value.get( "name" ), BaseComponent.class ) : null
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,8 +50,20 @@ public class EntitySerializer implements JsonSerializer<Entity>, JsonDeserialize
|
||||
{
|
||||
JsonObject object = new JsonObject();
|
||||
|
||||
object.addProperty( content.isV1_21_5() ? "id" : "type", ( content.getType() != null ) ? content.getType() : "minecraft:pig" );
|
||||
object.addProperty( content.isV1_21_5() ? "uuid" : "id", content.getId() );
|
||||
switch ( serializer.getVersion() )
|
||||
{
|
||||
case V1_21_5:
|
||||
object.addProperty( "id", ( content.getType() != null ) ? content.getType() : "minecraft:pig" );
|
||||
object.addProperty( "uuid", content.getId() );
|
||||
break;
|
||||
case V1_16:
|
||||
object.addProperty( "type", ( content.getType() != null ) ? content.getType() : "minecraft:pig" );
|
||||
object.addProperty( "id", content.getId() );
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException( "Unknown version " + serializer.getVersion() );
|
||||
}
|
||||
|
||||
if ( content.getName() != null )
|
||||
{
|
||||
object.add( "name", context.serialize( content.getName() ) );
|
||||
|
@@ -10,15 +10,19 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Locale;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import net.md_5.bungee.api.chat.ComponentStyle;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.hover.content.Content;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class BaseComponentSerializer
|
||||
{
|
||||
|
||||
protected final VersionedComponentSerializer serializer;
|
||||
|
||||
protected void deserialize(JsonObject object, BaseComponent component, JsonDeserializationContext context)
|
||||
{
|
||||
component.applyStyle( context.deserialize( object, ComponentStyle.class ) );
|
||||
@@ -59,7 +63,6 @@ public class BaseComponentSerializer
|
||||
component.setClickEvent( new ClickEvent( action, ( clickEvent.has( "value" ) ) ? clickEvent.get( "value" ).getAsString() : "" ) );
|
||||
break;
|
||||
}
|
||||
component.getClickEvent().setV1_21_5( true );
|
||||
} else
|
||||
{
|
||||
component.setClickEvent( new ClickEvent( action, ( clickEvent.has( "value" ) ) ? clickEvent.get( "value" ).getAsString() : "" ) );
|
||||
@@ -101,7 +104,6 @@ public class BaseComponentSerializer
|
||||
};
|
||||
}
|
||||
hoverEvent = new HoverEvent( action, new ArrayList<>( Arrays.asList( list ) ) );
|
||||
hoverEvent.setV1_21_5( newHoverEvent );
|
||||
}
|
||||
} else
|
||||
{
|
||||
@@ -141,15 +143,15 @@ public class BaseComponentSerializer
|
||||
protected void serialize(JsonObject object, BaseComponent component, JsonSerializationContext context)
|
||||
{
|
||||
boolean first = false;
|
||||
if ( ComponentSerializer.serializedComponents.get() == null )
|
||||
if ( VersionedComponentSerializer.serializedComponents.get() == null )
|
||||
{
|
||||
first = true;
|
||||
ComponentSerializer.serializedComponents.set( Collections.newSetFromMap( new IdentityHashMap<BaseComponent, Boolean>() ) );
|
||||
VersionedComponentSerializer.serializedComponents.set( Collections.newSetFromMap( new IdentityHashMap<BaseComponent, Boolean>() ) );
|
||||
}
|
||||
try
|
||||
{
|
||||
Preconditions.checkArgument( !ComponentSerializer.serializedComponents.get().contains( component ), "Component loop" );
|
||||
ComponentSerializer.serializedComponents.get().add( component );
|
||||
Preconditions.checkArgument( !VersionedComponentSerializer.serializedComponents.get().contains( component ), "Component loop" );
|
||||
VersionedComponentSerializer.serializedComponents.get().add( component );
|
||||
|
||||
ComponentStyleSerializer.serializeTo( component.getStyle(), object );
|
||||
|
||||
@@ -164,30 +166,34 @@ public class BaseComponentSerializer
|
||||
JsonObject clickEvent = new JsonObject();
|
||||
String actionName = component.getClickEvent().getAction().toString().toLowerCase( Locale.ROOT );
|
||||
clickEvent.addProperty( "action", actionName.toLowerCase( Locale.ROOT ) );
|
||||
if ( component.getClickEvent().isV1_21_5() )
|
||||
switch ( serializer.getVersion() )
|
||||
{
|
||||
ClickEvent.Action action = ClickEvent.Action.valueOf( actionName.toUpperCase( Locale.ROOT ) );
|
||||
switch ( action )
|
||||
{
|
||||
case OPEN_URL:
|
||||
clickEvent.addProperty( "url", component.getClickEvent().getValue() );
|
||||
break;
|
||||
case RUN_COMMAND:
|
||||
case SUGGEST_COMMAND:
|
||||
clickEvent.addProperty( "command", component.getClickEvent().getValue() );
|
||||
break;
|
||||
case CHANGE_PAGE:
|
||||
clickEvent.addProperty( "page", Integer.parseInt( component.getClickEvent().getValue() ) );
|
||||
break;
|
||||
default:
|
||||
clickEvent.addProperty( "value", component.getClickEvent().getValue() );
|
||||
break;
|
||||
}
|
||||
object.add( "click_event", clickEvent );
|
||||
} else
|
||||
{
|
||||
clickEvent.addProperty( "value", component.getClickEvent().getValue() );
|
||||
object.add( "clickEvent", clickEvent );
|
||||
case V1_21_5:
|
||||
ClickEvent.Action action = ClickEvent.Action.valueOf( actionName.toUpperCase( Locale.ROOT ) );
|
||||
switch ( action )
|
||||
{
|
||||
case OPEN_URL:
|
||||
clickEvent.addProperty( "url", component.getClickEvent().getValue() );
|
||||
break;
|
||||
case RUN_COMMAND:
|
||||
case SUGGEST_COMMAND:
|
||||
clickEvent.addProperty( "command", component.getClickEvent().getValue() );
|
||||
break;
|
||||
case CHANGE_PAGE:
|
||||
clickEvent.addProperty( "page", Integer.parseInt( component.getClickEvent().getValue() ) );
|
||||
break;
|
||||
default:
|
||||
clickEvent.addProperty( "value", component.getClickEvent().getValue() );
|
||||
break;
|
||||
}
|
||||
object.add( "click_event", clickEvent );
|
||||
break;
|
||||
case V1_16:
|
||||
clickEvent.addProperty( "value", component.getClickEvent().getValue() );
|
||||
object.add( "clickEvent", clickEvent );
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException( "Unknown version " + serializer.getVersion() );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -195,32 +201,44 @@ public class BaseComponentSerializer
|
||||
{
|
||||
JsonObject hoverEvent = new JsonObject();
|
||||
hoverEvent.addProperty( "action", component.getHoverEvent().getAction().toString().toLowerCase( Locale.ROOT ) );
|
||||
boolean newFormat = component.getHoverEvent().isV1_21_5();
|
||||
if ( component.getHoverEvent().isLegacy() )
|
||||
{
|
||||
hoverEvent.add( "value", context.serialize( component.getHoverEvent().getContents().get( 0 ) ) );
|
||||
} else
|
||||
{
|
||||
if ( newFormat )
|
||||
switch ( serializer.getVersion() )
|
||||
{
|
||||
if ( component.getHoverEvent().getAction() == HoverEvent.Action.SHOW_ITEM || component.getHoverEvent().getAction() == HoverEvent.Action.SHOW_ENTITY )
|
||||
{
|
||||
JsonObject inlined = context.serialize( ( component.getHoverEvent().getContents().size() == 1 )
|
||||
? component.getHoverEvent().getContents().get( 0 ) : component.getHoverEvent().getContents() ).getAsJsonObject();
|
||||
inlined.entrySet().forEach( entry -> hoverEvent.add( entry.getKey(), entry.getValue() ) );
|
||||
} else
|
||||
{
|
||||
hoverEvent.add( "value", context.serialize( ( component.getHoverEvent().getContents().size() == 1 )
|
||||
case V1_21_5:
|
||||
if ( component.getHoverEvent().getAction() == HoverEvent.Action.SHOW_ITEM || component.getHoverEvent().getAction() == HoverEvent.Action.SHOW_ENTITY )
|
||||
{
|
||||
JsonObject inlined = context.serialize( ( component.getHoverEvent().getContents().size() == 1 )
|
||||
? component.getHoverEvent().getContents().get( 0 ) : component.getHoverEvent().getContents() ).getAsJsonObject();
|
||||
inlined.entrySet().forEach( entry -> hoverEvent.add( entry.getKey(), entry.getValue() ) );
|
||||
} else
|
||||
{
|
||||
hoverEvent.add( "value", context.serialize( ( component.getHoverEvent().getContents().size() == 1 )
|
||||
? component.getHoverEvent().getContents().get( 0 ) : component.getHoverEvent().getContents() ) );
|
||||
}
|
||||
break;
|
||||
case V1_16:
|
||||
hoverEvent.add( "contents", context.serialize( ( component.getHoverEvent().getContents().size() == 1 )
|
||||
? component.getHoverEvent().getContents().get( 0 ) : component.getHoverEvent().getContents() ) );
|
||||
}
|
||||
} else
|
||||
{
|
||||
hoverEvent.add( "contents", context.serialize( ( component.getHoverEvent().getContents().size() == 1 )
|
||||
? component.getHoverEvent().getContents().get( 0 ) : component.getHoverEvent().getContents() ) );
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException( "Unknown version " + serializer.getVersion() );
|
||||
}
|
||||
|
||||
}
|
||||
object.add( newFormat ? "hover_event" : "hoverEvent", hoverEvent );
|
||||
switch ( serializer.getVersion() )
|
||||
{
|
||||
case V1_21_5:
|
||||
object.add( "hover_event", hoverEvent );
|
||||
break;
|
||||
case V1_16:
|
||||
object.add( "hoverEvent", hoverEvent );
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException( "Unknown version " + serializer.getVersion() );
|
||||
}
|
||||
}
|
||||
|
||||
if ( component.getExtra() != null )
|
||||
@@ -229,10 +247,10 @@ public class BaseComponentSerializer
|
||||
}
|
||||
} finally
|
||||
{
|
||||
ComponentSerializer.serializedComponents.get().remove( component );
|
||||
VersionedComponentSerializer.serializedComponents.get().remove( component );
|
||||
if ( first )
|
||||
{
|
||||
ComponentSerializer.serializedComponents.set( null );
|
||||
VersionedComponentSerializer.serializedComponents.set( null );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
10
chat/src/main/java/net/md_5/bungee/chat/ChatVersion.java
Normal file
10
chat/src/main/java/net/md_5/bungee/chat/ChatVersion.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package net.md_5.bungee.chat;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public enum ChatVersion
|
||||
{
|
||||
V1_16,
|
||||
V1_21_5;
|
||||
}
|
@@ -1,52 +1,17 @@
|
||||
package net.md_5.bungee.chat;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
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.JsonParser;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Set;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.ComponentStyle;
|
||||
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.Content;
|
||||
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>
|
||||
{
|
||||
|
||||
private static final Gson gson = new GsonBuilder().
|
||||
registerTypeAdapter( BaseComponent.class, new ComponentSerializer() ).
|
||||
registerTypeAdapter( TextComponent.class, new TextComponentSerializer() ).
|
||||
registerTypeAdapter( TranslatableComponent.class, new TranslatableComponentSerializer() ).
|
||||
registerTypeAdapter( KeybindComponent.class, new KeybindComponentSerializer() ).
|
||||
registerTypeAdapter( ScoreComponent.class, new ScoreComponentSerializer() ).
|
||||
registerTypeAdapter( SelectorComponent.class, new SelectorComponentSerializer() ).
|
||||
registerTypeAdapter( ComponentStyle.class, new ComponentStyleSerializer() ).
|
||||
registerTypeAdapter( Entity.class, new EntitySerializer() ).
|
||||
registerTypeAdapter( Text.class, new TextSerializer() ).
|
||||
registerTypeAdapter( Item.class, new ItemSerializer() ).
|
||||
registerTypeAdapter( ItemTag.class, new ItemTag.Serializer() ).
|
||||
create();
|
||||
|
||||
public static final ThreadLocal<Set<BaseComponent>> serializedComponents = new ThreadLocal<Set<BaseComponent>>();
|
||||
|
||||
/**
|
||||
* Parse a JSON-compliant String as an array of base components. The input
|
||||
* can be one of either an array of components, or a single component
|
||||
@@ -66,18 +31,7 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent>
|
||||
*/
|
||||
public static BaseComponent[] parse(String json)
|
||||
{
|
||||
JsonElement jsonElement = JsonParser.parseString( json );
|
||||
|
||||
if ( jsonElement.isJsonArray() )
|
||||
{
|
||||
return gson.fromJson( jsonElement, BaseComponent[].class );
|
||||
} else
|
||||
{
|
||||
return new BaseComponent[]
|
||||
{
|
||||
gson.fromJson( jsonElement, BaseComponent.class )
|
||||
};
|
||||
}
|
||||
return VersionedComponentSerializer.getDefault().parse( json );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,9 +44,7 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent>
|
||||
*/
|
||||
public static BaseComponent deserialize(String json)
|
||||
{
|
||||
JsonElement jsonElement = JsonParser.parseString( json );
|
||||
|
||||
return deserialize( jsonElement );
|
||||
return VersionedComponentSerializer.getDefault().deserialize( json );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,20 +57,7 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent>
|
||||
*/
|
||||
public static BaseComponent deserialize(JsonElement jsonElement)
|
||||
{
|
||||
if ( jsonElement instanceof JsonPrimitive )
|
||||
{
|
||||
JsonPrimitive primitive = (JsonPrimitive) jsonElement;
|
||||
if ( primitive.isString() )
|
||||
{
|
||||
return new TextComponent( primitive.getAsString() );
|
||||
}
|
||||
} else if ( jsonElement instanceof JsonArray )
|
||||
{
|
||||
BaseComponent[] array = gson.fromJson( jsonElement, BaseComponent[].class );
|
||||
return TextComponent.fromArray( array );
|
||||
}
|
||||
|
||||
return gson.fromJson( jsonElement, BaseComponent.class );
|
||||
return VersionedComponentSerializer.getDefault().deserialize( jsonElement );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,9 +70,7 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent>
|
||||
*/
|
||||
public static ComponentStyle deserializeStyle(String json)
|
||||
{
|
||||
JsonElement jsonElement = JsonParser.parseString( json );
|
||||
|
||||
return deserializeStyle( jsonElement );
|
||||
return VersionedComponentSerializer.getDefault().deserializeStyle( json );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,17 +83,17 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent>
|
||||
*/
|
||||
public static ComponentStyle deserializeStyle(JsonElement jsonElement)
|
||||
{
|
||||
return gson.fromJson( jsonElement, ComponentStyle.class );
|
||||
return VersionedComponentSerializer.getDefault().deserializeStyle( jsonElement );
|
||||
}
|
||||
|
||||
public static JsonElement toJson(BaseComponent component)
|
||||
{
|
||||
return gson.toJsonTree( component );
|
||||
return VersionedComponentSerializer.getDefault().toJson( component );
|
||||
}
|
||||
|
||||
public static JsonElement toJson(ComponentStyle style)
|
||||
{
|
||||
return gson.toJsonTree( style );
|
||||
return VersionedComponentSerializer.getDefault().toJson( style );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,7 +104,7 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent>
|
||||
@Deprecated
|
||||
public static String toString(Object object)
|
||||
{
|
||||
return gson.toJson( object );
|
||||
return VersionedComponentSerializer.getDefault().toString( object );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,54 +115,27 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent>
|
||||
@Deprecated
|
||||
public static String toString(Content content)
|
||||
{
|
||||
return gson.toJson( content );
|
||||
return VersionedComponentSerializer.getDefault().toString( content );
|
||||
}
|
||||
|
||||
public static String toString(BaseComponent component)
|
||||
{
|
||||
return gson.toJson( component );
|
||||
return VersionedComponentSerializer.getDefault().toString( component );
|
||||
}
|
||||
|
||||
public static String toString(BaseComponent... components)
|
||||
{
|
||||
if ( components.length == 1 )
|
||||
{
|
||||
return gson.toJson( components[0] );
|
||||
} else
|
||||
{
|
||||
return gson.toJson( new TextComponent( components ) );
|
||||
}
|
||||
return VersionedComponentSerializer.getDefault().toString( components );
|
||||
}
|
||||
|
||||
public static String toString(ComponentStyle style)
|
||||
{
|
||||
return gson.toJson( style );
|
||||
return VersionedComponentSerializer.getDefault().toString( style );
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
|
||||
{
|
||||
if ( json.isJsonPrimitive() )
|
||||
{
|
||||
return new TextComponent( json.getAsString() );
|
||||
}
|
||||
JsonObject object = json.getAsJsonObject();
|
||||
if ( object.has( "translate" ) )
|
||||
{
|
||||
return context.deserialize( json, TranslatableComponent.class );
|
||||
}
|
||||
if ( object.has( "keybind" ) )
|
||||
{
|
||||
return context.deserialize( json, KeybindComponent.class );
|
||||
}
|
||||
if ( object.has( "score" ) )
|
||||
{
|
||||
return context.deserialize( json, ScoreComponent.class );
|
||||
}
|
||||
if ( object.has( "selector" ) )
|
||||
{
|
||||
return context.deserialize( json, SelectorComponent.class );
|
||||
}
|
||||
return context.deserialize( json, TextComponent.class );
|
||||
return VersionedComponentSerializer.getDefault().deserialize( json, typeOfT, context );
|
||||
}
|
||||
}
|
||||
|
@@ -13,6 +13,11 @@ import net.md_5.bungee.api.chat.KeybindComponent;
|
||||
public class KeybindComponentSerializer extends BaseComponentSerializer implements JsonSerializer<KeybindComponent>, JsonDeserializer<KeybindComponent>
|
||||
{
|
||||
|
||||
public KeybindComponentSerializer(VersionedComponentSerializer serializer)
|
||||
{
|
||||
super( serializer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeybindComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
|
||||
{
|
||||
|
@@ -13,6 +13,11 @@ import net.md_5.bungee.api.chat.ScoreComponent;
|
||||
public class ScoreComponentSerializer extends BaseComponentSerializer implements JsonSerializer<ScoreComponent>, JsonDeserializer<ScoreComponent>
|
||||
{
|
||||
|
||||
public ScoreComponentSerializer(VersionedComponentSerializer serializer)
|
||||
{
|
||||
super( serializer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScoreComponent deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException
|
||||
{
|
||||
|
@@ -13,6 +13,11 @@ import net.md_5.bungee.api.chat.SelectorComponent;
|
||||
public class SelectorComponentSerializer extends BaseComponentSerializer implements JsonSerializer<SelectorComponent>, JsonDeserializer<SelectorComponent>
|
||||
{
|
||||
|
||||
public SelectorComponentSerializer(VersionedComponentSerializer serializer)
|
||||
{
|
||||
super( serializer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectorComponent deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException
|
||||
{
|
||||
@@ -27,7 +32,7 @@ public class SelectorComponentSerializer extends BaseComponentSerializer impleme
|
||||
JsonElement separator = object.get( "separator" );
|
||||
if ( separator != null )
|
||||
{
|
||||
component.setSeparator( ComponentSerializer.deserialize( separator.getAsString() ) );
|
||||
component.setSeparator( serializer.deserialize( separator.getAsString() ) );
|
||||
}
|
||||
|
||||
deserialize( object, component, context );
|
||||
@@ -43,7 +48,7 @@ public class SelectorComponentSerializer extends BaseComponentSerializer impleme
|
||||
|
||||
if ( component.getSeparator() != null )
|
||||
{
|
||||
object.addProperty( "separator", ComponentSerializer.toString( component.getSeparator() ) );
|
||||
object.addProperty( "separator", serializer.toString( component.getSeparator() ) );
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
@@ -13,6 +13,11 @@ import net.md_5.bungee.api.chat.TextComponent;
|
||||
public class TextComponentSerializer extends BaseComponentSerializer implements JsonSerializer<TextComponent>, JsonDeserializer<TextComponent>
|
||||
{
|
||||
|
||||
public TextComponentSerializer(VersionedComponentSerializer serializer)
|
||||
{
|
||||
super( serializer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
|
||||
{
|
||||
|
@@ -15,6 +15,11 @@ import net.md_5.bungee.api.chat.TranslatableComponent;
|
||||
public class TranslatableComponentSerializer extends BaseComponentSerializer implements JsonSerializer<TranslatableComponent>, JsonDeserializer<TranslatableComponent>
|
||||
{
|
||||
|
||||
public TranslatableComponentSerializer(VersionedComponentSerializer serializer)
|
||||
{
|
||||
super( serializer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public TranslatableComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
|
||||
{
|
||||
|
@@ -0,0 +1,269 @@
|
||||
package net.md_5.bungee.chat;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
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.JsonParser;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Set;
|
||||
import lombok.Getter;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.ComponentStyle;
|
||||
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.Content;
|
||||
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;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public class VersionedComponentSerializer implements JsonDeserializer<BaseComponent>
|
||||
{
|
||||
|
||||
@Getter
|
||||
@ApiStatus.Internal
|
||||
private final Gson gson;
|
||||
@Getter
|
||||
@ApiStatus.Internal
|
||||
private final ChatVersion version;
|
||||
|
||||
public VersionedComponentSerializer(ChatVersion version)
|
||||
{
|
||||
this.version = version;
|
||||
this.gson = new GsonBuilder().
|
||||
registerTypeAdapter( BaseComponent.class, this ).
|
||||
registerTypeAdapter( TextComponent.class, new TextComponentSerializer( this ) ).
|
||||
registerTypeAdapter( TranslatableComponent.class, new TranslatableComponentSerializer( this ) ).
|
||||
registerTypeAdapter( KeybindComponent.class, new KeybindComponentSerializer( this ) ).
|
||||
registerTypeAdapter( ScoreComponent.class, new ScoreComponentSerializer( this ) ).
|
||||
registerTypeAdapter( SelectorComponent.class, new SelectorComponentSerializer( this ) ).
|
||||
registerTypeAdapter( ComponentStyle.class, new ComponentStyleSerializer() ).
|
||||
registerTypeAdapter( Entity.class, new EntitySerializer( this ) ).
|
||||
registerTypeAdapter( Text.class, new TextSerializer() ).
|
||||
registerTypeAdapter( Item.class, new ItemSerializer() ).
|
||||
registerTypeAdapter( ItemTag.class, new ItemTag.Serializer() ).
|
||||
create();
|
||||
}
|
||||
|
||||
private static final VersionedComponentSerializer v1_16 = new VersionedComponentSerializer( ChatVersion.V1_16 );
|
||||
private static final VersionedComponentSerializer v1_21_5 = new VersionedComponentSerializer( ChatVersion.V1_21_5 );
|
||||
|
||||
public static VersionedComponentSerializer forVersion(ChatVersion version)
|
||||
{
|
||||
switch ( version )
|
||||
{
|
||||
case V1_16:
|
||||
return v1_16;
|
||||
case V1_21_5:
|
||||
return v1_21_5;
|
||||
default:
|
||||
throw new IllegalArgumentException( "Unknown version " + version );
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ApiStatus.Internal
|
||||
public static VersionedComponentSerializer getDefault()
|
||||
{
|
||||
return v1_16;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static final ThreadLocal<Set<BaseComponent>> serializedComponents = new ThreadLocal<Set<BaseComponent>>();
|
||||
|
||||
/**
|
||||
* Parse a JSON-compliant String as an array of base components. The input
|
||||
* can be one of either an array of components, or a single component
|
||||
* object. If the input is an array, each component will be parsed
|
||||
* individually and returned in the order that they were parsed. If the
|
||||
* input is a single component object, a single-valued array with the
|
||||
* component will be returned.
|
||||
* <p>
|
||||
* <strong>NOTE:</strong> {@link #deserialize(String)} is preferred as it
|
||||
* will parse only one component as opposed to an array of components which
|
||||
* is non- standard behavior. This method is still appropriate for parsing
|
||||
* multiple components at once, although such use case is rarely (if at all)
|
||||
* exhibited in vanilla Minecraft.
|
||||
*
|
||||
* @param json the component json to parse
|
||||
* @return an array of all parsed components
|
||||
*/
|
||||
public BaseComponent[] parse(String json)
|
||||
{
|
||||
JsonElement jsonElement = JsonParser.parseString( json );
|
||||
|
||||
if ( jsonElement.isJsonArray() )
|
||||
{
|
||||
return gson.fromJson( jsonElement, BaseComponent[].class );
|
||||
} else
|
||||
{
|
||||
return new BaseComponent[]
|
||||
{
|
||||
gson.fromJson( jsonElement, BaseComponent.class )
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize a JSON-compliant String as a single component.
|
||||
*
|
||||
* @param json the component json to parse
|
||||
* @return the deserialized component
|
||||
* @throws IllegalArgumentException if anything other than a valid JSON
|
||||
* component string is passed as input
|
||||
*/
|
||||
public BaseComponent deserialize(String json)
|
||||
{
|
||||
JsonElement jsonElement = JsonParser.parseString( json );
|
||||
|
||||
return deserialize( jsonElement );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize a JSON element as a single component.
|
||||
*
|
||||
* @param jsonElement the component json to parse
|
||||
* @return the deserialized component
|
||||
* @throws IllegalArgumentException if anything other than a valid JSON
|
||||
* component is passed as input
|
||||
*/
|
||||
public BaseComponent deserialize(JsonElement jsonElement)
|
||||
{
|
||||
if ( jsonElement instanceof JsonPrimitive )
|
||||
{
|
||||
JsonPrimitive primitive = (JsonPrimitive) jsonElement;
|
||||
if ( primitive.isString() )
|
||||
{
|
||||
return new TextComponent( primitive.getAsString() );
|
||||
}
|
||||
} else if ( jsonElement instanceof JsonArray )
|
||||
{
|
||||
BaseComponent[] array = gson.fromJson( jsonElement, BaseComponent[].class );
|
||||
return TextComponent.fromArray( array );
|
||||
}
|
||||
|
||||
return gson.fromJson( jsonElement, BaseComponent.class );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize a JSON-compliant String as a component style.
|
||||
*
|
||||
* @param json the component style json to parse
|
||||
* @return the deserialized component style
|
||||
* @throws IllegalArgumentException if anything other than a valid JSON
|
||||
* component style string is passed as input
|
||||
*/
|
||||
public ComponentStyle deserializeStyle(String json)
|
||||
{
|
||||
JsonElement jsonElement = JsonParser.parseString( json );
|
||||
|
||||
return deserializeStyle( jsonElement );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize a JSON element as a component style.
|
||||
*
|
||||
* @param jsonElement the component style json to parse
|
||||
* @return the deserialized component style
|
||||
* @throws IllegalArgumentException if anything other than a valid JSON
|
||||
* component style is passed as input
|
||||
*/
|
||||
public ComponentStyle deserializeStyle(JsonElement jsonElement)
|
||||
{
|
||||
return gson.fromJson( jsonElement, ComponentStyle.class );
|
||||
}
|
||||
|
||||
public JsonElement toJson(BaseComponent component)
|
||||
{
|
||||
return gson.toJsonTree( component );
|
||||
}
|
||||
|
||||
public JsonElement toJson(ComponentStyle style)
|
||||
{
|
||||
return gson.toJsonTree( style );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object the object to serialize
|
||||
* @return the JSON string representation of the object
|
||||
* @deprecated Error-prone, be careful which object you input here
|
||||
*/
|
||||
@Deprecated
|
||||
public String toString(Object object)
|
||||
{
|
||||
return gson.toJson( object );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param content the content to serialize
|
||||
* @return the JSON string representation of the object
|
||||
* @deprecated for legacy internal use only
|
||||
*/
|
||||
@Deprecated
|
||||
public String toString(Content content)
|
||||
{
|
||||
return gson.toJson( content );
|
||||
}
|
||||
|
||||
public String toString(BaseComponent component)
|
||||
{
|
||||
return gson.toJson( component );
|
||||
}
|
||||
|
||||
public String toString(BaseComponent... components)
|
||||
{
|
||||
if ( components.length == 1 )
|
||||
{
|
||||
return gson.toJson( components[0] );
|
||||
} else
|
||||
{
|
||||
return gson.toJson( new TextComponent( components ) );
|
||||
}
|
||||
}
|
||||
|
||||
public String toString(ComponentStyle style)
|
||||
{
|
||||
return gson.toJson( style );
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
|
||||
{
|
||||
if ( json.isJsonPrimitive() )
|
||||
{
|
||||
return new TextComponent( json.getAsString() );
|
||||
}
|
||||
JsonObject object = json.getAsJsonObject();
|
||||
if ( object.has( "translate" ) )
|
||||
{
|
||||
return context.deserialize( json, TranslatableComponent.class );
|
||||
}
|
||||
if ( object.has( "keybind" ) )
|
||||
{
|
||||
return context.deserialize( json, KeybindComponent.class );
|
||||
}
|
||||
if ( object.has( "score" ) )
|
||||
{
|
||||
return context.deserialize( json, ScoreComponent.class );
|
||||
}
|
||||
if ( object.has( "selector" ) )
|
||||
{
|
||||
return context.deserialize( json, SelectorComponent.class );
|
||||
}
|
||||
return context.deserialize( json, TextComponent.class );
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user