Minecraft 25w20a protocol support
This commit is contained in:
@@ -4,12 +4,14 @@ import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
@RequiredArgsConstructor
|
||||
public final class ClickEvent
|
||||
@ApiStatus.NonExtendable
|
||||
public class ClickEvent
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -52,11 +54,19 @@ public final class ClickEvent
|
||||
* {@link net.md_5.bungee.api.chat.ClickEvent#value} in a book.
|
||||
*/
|
||||
CHANGE_PAGE,
|
||||
/**
|
||||
* Must use subclass ShowDialogClickEvent.
|
||||
*/
|
||||
SHOW_DIALOG,
|
||||
/**
|
||||
* Copy the string given by
|
||||
* {@link net.md_5.bungee.api.chat.ClickEvent#value} into the player's
|
||||
* clipboard.
|
||||
*/
|
||||
COPY_TO_CLIPBOARD
|
||||
COPY_TO_CLIPBOARD,
|
||||
/**
|
||||
* Must use subclass {@link ClickEventCustom}.
|
||||
*/
|
||||
CUSTOM,
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,30 @@
|
||||
package net.md_5.bungee.api.chat;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* Click event which sends a custom payload to the server.
|
||||
*/
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class ClickEventCustom extends ClickEvent
|
||||
{
|
||||
|
||||
/**
|
||||
* The custom payload.
|
||||
*/
|
||||
private final String payload;
|
||||
|
||||
/**
|
||||
* @param id identifier for the event (lower case, no special characters)
|
||||
* @param payload custom payload
|
||||
*/
|
||||
public ClickEventCustom(String id, String payload)
|
||||
{
|
||||
super( ClickEvent.Action.CUSTOM, id );
|
||||
this.payload = payload;
|
||||
}
|
||||
}
|
@@ -13,7 +13,6 @@ 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.VersionedComponentSerializer;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@Getter
|
||||
@@ -73,22 +72,6 @@ public final class HoverEvent
|
||||
this.legacy = true;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public BaseComponent[] getValue()
|
||||
{
|
||||
Content content = contents.get( 0 );
|
||||
if ( content instanceof Text && ( (Text) content ).getValue() instanceof BaseComponent[] )
|
||||
{
|
||||
return (BaseComponent[]) ( (Text) content ).getValue();
|
||||
}
|
||||
|
||||
TextComponent component = new TextComponent( VersionedComponentSerializer.getDefault().toString( content ) );
|
||||
return new BaseComponent[]
|
||||
{
|
||||
component
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a content to this hover event.
|
||||
*
|
||||
|
@@ -1,78 +0,0 @@
|
||||
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 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 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
|
||||
{
|
||||
JsonObject value = element.getAsJsonObject();
|
||||
|
||||
boolean newEntity = value.has( "uuid" );
|
||||
|
||||
String idString;
|
||||
JsonElement uuid = value.get( newEntity ? "uuid" : "id" );
|
||||
if ( uuid.isJsonArray() )
|
||||
{
|
||||
idString = parseUUID( context.deserialize( uuid, int[].class ) ).toString();
|
||||
} else
|
||||
{
|
||||
idString = uuid.getAsString();
|
||||
}
|
||||
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(Entity content, Type type, JsonSerializationContext context)
|
||||
{
|
||||
JsonObject object = new JsonObject();
|
||||
|
||||
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() ) );
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
private static UUID parseUUID(int[] array)
|
||||
{
|
||||
return new UUID( (long) array[0] << 32 | (long) array[1] & 0XFFFFFFFFL, (long) array[2] << 32 | (long) array[3] & 0XFFFFFFFFL );
|
||||
}
|
||||
}
|
@@ -1,71 +0,0 @@
|
||||
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();
|
||||
char last = cString.charAt( cString.length() - 1 );
|
||||
// Check for all number suffixes
|
||||
if ( last == 'b' || last == 's' || last == 'l' || last == 'f' || last == 'd' )
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
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.isJsonPrimitive() )
|
||||
{
|
||||
return new Text( element.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() );
|
||||
}
|
||||
}
|
@@ -1,257 +0,0 @@
|
||||
package net.md_5.bungee.chat;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import java.util.ArrayList;
|
||||
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 ) );
|
||||
|
||||
JsonElement insertion = object.get( "insertion" );
|
||||
if ( insertion != null )
|
||||
{
|
||||
component.setInsertion( insertion.getAsString() );
|
||||
}
|
||||
|
||||
//Events
|
||||
JsonObject clickEvent;
|
||||
boolean newClickEvent = ( clickEvent = object.getAsJsonObject( "click_event" ) ) != null;
|
||||
if ( !newClickEvent )
|
||||
{
|
||||
clickEvent = object.getAsJsonObject( "clickEvent" );
|
||||
}
|
||||
if ( clickEvent != null )
|
||||
{
|
||||
ClickEvent.Action action = ClickEvent.Action.valueOf( clickEvent.get( "action" ).getAsString().toUpperCase( Locale.ROOT ) );
|
||||
if ( newClickEvent )
|
||||
{
|
||||
switch ( action )
|
||||
{
|
||||
case OPEN_URL:
|
||||
component.setClickEvent( new ClickEvent( action, clickEvent.get( "url" ).getAsString() ) );
|
||||
break;
|
||||
case RUN_COMMAND:
|
||||
case SUGGEST_COMMAND:
|
||||
component.setClickEvent( new ClickEvent( action, clickEvent.get( "command" ).getAsString() ) );
|
||||
break;
|
||||
case CHANGE_PAGE:
|
||||
int page = clickEvent.get( "page" ).getAsInt();
|
||||
Preconditions.checkArgument( page >= 0, "Page number has to be positive" );
|
||||
component.setClickEvent( new ClickEvent( action, Integer.toString( page ) ) );
|
||||
break;
|
||||
default:
|
||||
component.setClickEvent( new ClickEvent( action, ( clickEvent.has( "value" ) ) ? clickEvent.get( "value" ).getAsString() : "" ) );
|
||||
break;
|
||||
}
|
||||
} else
|
||||
{
|
||||
component.setClickEvent( new ClickEvent( action, ( clickEvent.has( "value" ) ) ? clickEvent.get( "value" ).getAsString() : "" ) );
|
||||
}
|
||||
}
|
||||
|
||||
JsonObject hoverEventJson;
|
||||
boolean newHoverEvent = ( hoverEventJson = object.getAsJsonObject( "hover_event" ) ) != null;
|
||||
if ( !newHoverEvent )
|
||||
{
|
||||
hoverEventJson = object.getAsJsonObject( "hoverEvent" );
|
||||
}
|
||||
|
||||
if ( hoverEventJson != null )
|
||||
{
|
||||
HoverEvent hoverEvent = null;
|
||||
HoverEvent.Action action = HoverEvent.Action.valueOf( hoverEventJson.get( "action" ).getAsString().toUpperCase( Locale.ROOT ) );
|
||||
|
||||
if ( newHoverEvent || hoverEventJson.has( "contents" ) )
|
||||
{
|
||||
// value is only used for text in >= 1.21.5 (its inlined now)
|
||||
JsonElement contents = hoverEventJson.get( newHoverEvent ? "value" : "contents" );
|
||||
if ( contents != null || ( newHoverEvent && ( action == HoverEvent.Action.SHOW_ITEM || action == HoverEvent.Action.SHOW_ENTITY ) ) )
|
||||
{
|
||||
if ( contents == null )
|
||||
{
|
||||
// this is the new inline for SHOW_ITEM and SHOW_ENTITY
|
||||
contents = hoverEventJson;
|
||||
}
|
||||
Content[] list;
|
||||
if ( contents.isJsonArray() )
|
||||
{
|
||||
list = context.deserialize( contents, HoverEvent.getClass( action, true ) );
|
||||
} else
|
||||
{
|
||||
list = new Content[]
|
||||
{
|
||||
context.deserialize( contents, HoverEvent.getClass( action, false ) )
|
||||
};
|
||||
}
|
||||
hoverEvent = new HoverEvent( action, new ArrayList<>( Arrays.asList( list ) ) );
|
||||
}
|
||||
} else
|
||||
{
|
||||
JsonElement value = hoverEventJson.get( "value" );
|
||||
if ( value != null )
|
||||
{
|
||||
// Plugins previously had support to pass BaseComponent[] into any action.
|
||||
// If the GSON is possible to be parsed as BaseComponent, attempt to parse as so.
|
||||
BaseComponent[] components;
|
||||
if ( value.isJsonArray() )
|
||||
{
|
||||
components = context.deserialize( value, BaseComponent[].class );
|
||||
} else
|
||||
{
|
||||
components = new BaseComponent[]
|
||||
{
|
||||
context.deserialize( value, BaseComponent.class )
|
||||
};
|
||||
}
|
||||
hoverEvent = new HoverEvent( action, components );
|
||||
}
|
||||
}
|
||||
|
||||
if ( hoverEvent != null )
|
||||
{
|
||||
component.setHoverEvent( hoverEvent );
|
||||
}
|
||||
}
|
||||
|
||||
JsonElement extra = object.get( "extra" );
|
||||
if ( extra != null )
|
||||
{
|
||||
component.setExtra( Arrays.asList( context.deserialize( extra, BaseComponent[].class ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
protected void serialize(JsonObject object, BaseComponent component, JsonSerializationContext context)
|
||||
{
|
||||
boolean first = false;
|
||||
if ( VersionedComponentSerializer.serializedComponents.get() == null )
|
||||
{
|
||||
first = true;
|
||||
VersionedComponentSerializer.serializedComponents.set( Collections.newSetFromMap( new IdentityHashMap<BaseComponent, Boolean>() ) );
|
||||
}
|
||||
try
|
||||
{
|
||||
Preconditions.checkArgument( !VersionedComponentSerializer.serializedComponents.get().contains( component ), "Component loop" );
|
||||
VersionedComponentSerializer.serializedComponents.get().add( component );
|
||||
|
||||
ComponentStyleSerializer.serializeTo( component.getStyle(), object );
|
||||
|
||||
if ( component.getInsertion() != null )
|
||||
{
|
||||
object.addProperty( "insertion", component.getInsertion() );
|
||||
}
|
||||
|
||||
//Events
|
||||
if ( component.getClickEvent() != null )
|
||||
{
|
||||
JsonObject clickEvent = new JsonObject();
|
||||
String actionName = component.getClickEvent().getAction().toString().toLowerCase( Locale.ROOT );
|
||||
clickEvent.addProperty( "action", actionName.toLowerCase( Locale.ROOT ) );
|
||||
switch ( serializer.getVersion() )
|
||||
{
|
||||
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() );
|
||||
}
|
||||
|
||||
}
|
||||
if ( component.getHoverEvent() != null )
|
||||
{
|
||||
JsonObject hoverEvent = new JsonObject();
|
||||
hoverEvent.addProperty( "action", component.getHoverEvent().getAction().toString().toLowerCase( Locale.ROOT ) );
|
||||
if ( component.getHoverEvent().isLegacy() )
|
||||
{
|
||||
hoverEvent.add( "value", context.serialize( component.getHoverEvent().getContents().get( 0 ) ) );
|
||||
} else
|
||||
{
|
||||
switch ( serializer.getVersion() )
|
||||
{
|
||||
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() ) );
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException( "Unknown version " + serializer.getVersion() );
|
||||
}
|
||||
}
|
||||
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 )
|
||||
{
|
||||
object.add( "extra", context.serialize( component.getExtra() ) );
|
||||
}
|
||||
} finally
|
||||
{
|
||||
VersionedComponentSerializer.serializedComponents.get().remove( component );
|
||||
if ( first )
|
||||
{
|
||||
VersionedComponentSerializer.serializedComponents.set( null );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,10 +0,0 @@
|
||||
package net.md_5.bungee.chat;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public enum ChatVersion
|
||||
{
|
||||
V1_16,
|
||||
V1_21_5;
|
||||
}
|
@@ -1,141 +0,0 @@
|
||||
package net.md_5.bungee.chat;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import java.lang.reflect.Type;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.ComponentStyle;
|
||||
import net.md_5.bungee.api.chat.hover.content.Content;
|
||||
|
||||
public class ComponentSerializer implements JsonDeserializer<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 static BaseComponent[] parse(String json)
|
||||
{
|
||||
return VersionedComponentSerializer.getDefault().parse( json );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 static BaseComponent deserialize(String json)
|
||||
{
|
||||
return VersionedComponentSerializer.getDefault().deserialize( json );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 static BaseComponent deserialize(JsonElement jsonElement)
|
||||
{
|
||||
return VersionedComponentSerializer.getDefault().deserialize( jsonElement );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 static ComponentStyle deserializeStyle(String json)
|
||||
{
|
||||
return VersionedComponentSerializer.getDefault().deserializeStyle( json );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 static ComponentStyle deserializeStyle(JsonElement jsonElement)
|
||||
{
|
||||
return VersionedComponentSerializer.getDefault().deserializeStyle( jsonElement );
|
||||
}
|
||||
|
||||
public static JsonElement toJson(BaseComponent component)
|
||||
{
|
||||
return VersionedComponentSerializer.getDefault().toJson( component );
|
||||
}
|
||||
|
||||
public static JsonElement toJson(ComponentStyle style)
|
||||
{
|
||||
return VersionedComponentSerializer.getDefault().toJson( 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 static String toString(Object object)
|
||||
{
|
||||
return VersionedComponentSerializer.getDefault().toString( object );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param content the content to serialize
|
||||
* @return the JSON string representation of the object
|
||||
* @deprecated for legacy internal use only
|
||||
*/
|
||||
@Deprecated
|
||||
public static String toString(Content content)
|
||||
{
|
||||
return VersionedComponentSerializer.getDefault().toString( content );
|
||||
}
|
||||
|
||||
public static String toString(BaseComponent component)
|
||||
{
|
||||
return VersionedComponentSerializer.getDefault().toString( component );
|
||||
}
|
||||
|
||||
public static String toString(BaseComponent... components)
|
||||
{
|
||||
return VersionedComponentSerializer.getDefault().toString( components );
|
||||
}
|
||||
|
||||
public static String toString(ComponentStyle style)
|
||||
{
|
||||
return VersionedComponentSerializer.getDefault().toString( style );
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
|
||||
{
|
||||
return VersionedComponentSerializer.getDefault().deserialize( json, typeOfT, context );
|
||||
}
|
||||
}
|
@@ -1,137 +0,0 @@
|
||||
package net.md_5.bungee.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.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import java.awt.Color;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.chat.ComponentStyle;
|
||||
import net.md_5.bungee.api.chat.ComponentStyleBuilder;
|
||||
|
||||
public class ComponentStyleSerializer implements JsonSerializer<ComponentStyle>, JsonDeserializer<ComponentStyle>
|
||||
{
|
||||
|
||||
private static boolean getAsBoolean(JsonElement el)
|
||||
{
|
||||
if ( el.isJsonPrimitive() )
|
||||
{
|
||||
JsonPrimitive primitive = (JsonPrimitive) el;
|
||||
|
||||
if ( primitive.isBoolean() )
|
||||
{
|
||||
return primitive.getAsBoolean();
|
||||
}
|
||||
|
||||
if ( primitive.isNumber() )
|
||||
{
|
||||
Number number = primitive.getAsNumber();
|
||||
if ( number instanceof Byte )
|
||||
{
|
||||
return number.byteValue() != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void serializeTo(ComponentStyle style, JsonObject object)
|
||||
{
|
||||
if ( style.isBoldRaw() != null )
|
||||
{
|
||||
object.addProperty( "bold", style.isBoldRaw() );
|
||||
}
|
||||
if ( style.isItalicRaw() != null )
|
||||
{
|
||||
object.addProperty( "italic", style.isItalicRaw() );
|
||||
}
|
||||
if ( style.isUnderlinedRaw() != null )
|
||||
{
|
||||
object.addProperty( "underlined", style.isUnderlinedRaw() );
|
||||
}
|
||||
if ( style.isStrikethroughRaw() != null )
|
||||
{
|
||||
object.addProperty( "strikethrough", style.isStrikethroughRaw() );
|
||||
}
|
||||
if ( style.isObfuscatedRaw() != null )
|
||||
{
|
||||
object.addProperty( "obfuscated", style.isObfuscatedRaw() );
|
||||
}
|
||||
if ( style.hasColor() && style.getColor().getColor() != null )
|
||||
{
|
||||
object.addProperty( "color", style.getColor().getName() );
|
||||
}
|
||||
if ( style.hasShadowColor() )
|
||||
{
|
||||
object.addProperty( "shadow_color", style.getShadowColor().getRGB() );
|
||||
}
|
||||
if ( style.hasFont() )
|
||||
{
|
||||
object.addProperty( "font", style.getFont() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentStyle deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
|
||||
{
|
||||
ComponentStyleBuilder builder = ComponentStyle.builder();
|
||||
JsonObject object = json.getAsJsonObject();
|
||||
for ( Map.Entry<String, JsonElement> entry : object.entrySet() )
|
||||
{
|
||||
String name = entry.getKey();
|
||||
JsonElement value = entry.getValue();
|
||||
switch ( name )
|
||||
{
|
||||
case "bold":
|
||||
builder.bold( getAsBoolean( value ) );
|
||||
break;
|
||||
case "italic":
|
||||
builder.italic( getAsBoolean( value ) );
|
||||
break;
|
||||
case "underlined":
|
||||
builder.underlined( getAsBoolean( value ) );
|
||||
break;
|
||||
case "strikethrough":
|
||||
builder.strikethrough( getAsBoolean( value ) );
|
||||
break;
|
||||
case "obfuscated":
|
||||
builder.obfuscated( getAsBoolean( value ) );
|
||||
break;
|
||||
case "color":
|
||||
builder.color( ChatColor.of( value.getAsString() ) );
|
||||
break;
|
||||
case "shadow_color":
|
||||
if ( value.isJsonArray() )
|
||||
{
|
||||
JsonArray array = value.getAsJsonArray();
|
||||
|
||||
builder.shadowColor( new Color( array.get( 0 ).getAsFloat(), array.get( 1 ).getAsFloat(), array.get( 2 ).getAsFloat(), array.get( 3 ).getAsFloat() ) );
|
||||
} else if ( value.isJsonPrimitive() )
|
||||
{
|
||||
builder.shadowColor( new Color( value.getAsNumber().intValue(), true ) );
|
||||
}
|
||||
break;
|
||||
case "font":
|
||||
builder.font( value.getAsString() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(ComponentStyle src, Type typeOfSrc, JsonSerializationContext context)
|
||||
{
|
||||
JsonObject object = new JsonObject();
|
||||
serializeTo( src, object );
|
||||
return object;
|
||||
}
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
package net.md_5.bungee.chat;
|
||||
|
||||
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.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
|
||||
{
|
||||
JsonObject object = json.getAsJsonObject();
|
||||
JsonElement keybind = object.get( "keybind" );
|
||||
if ( keybind == null )
|
||||
{
|
||||
throw new JsonParseException( "Could not parse JSON: missing 'keybind' property" );
|
||||
}
|
||||
KeybindComponent component = new KeybindComponent();
|
||||
deserialize( object, component, context );
|
||||
component.setKeybind( keybind.getAsString() );
|
||||
return component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(KeybindComponent src, Type typeOfSrc, JsonSerializationContext context)
|
||||
{
|
||||
JsonObject object = new JsonObject();
|
||||
serialize( object, src, context );
|
||||
object.addProperty( "keybind", src.getKeybind() );
|
||||
return object;
|
||||
}
|
||||
}
|
@@ -1,66 +0,0 @@
|
||||
package net.md_5.bungee.chat;
|
||||
|
||||
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.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
|
||||
{
|
||||
JsonObject json = element.getAsJsonObject();
|
||||
JsonObject score = json.getAsJsonObject( "score" );
|
||||
if ( score == null )
|
||||
{
|
||||
throw new JsonParseException( "Could not parse JSON: missing 'score' property" );
|
||||
}
|
||||
JsonElement nameJson = score.get( "name" );
|
||||
if ( nameJson == null )
|
||||
{
|
||||
throw new JsonParseException( "A score component needs at least a name (and an objective)" );
|
||||
}
|
||||
JsonElement objectiveJson = score.get( "objective" );
|
||||
if ( objectiveJson == null )
|
||||
{
|
||||
throw new JsonParseException( "A score component needs at least a name and an objective" );
|
||||
}
|
||||
|
||||
String name = nameJson.getAsString();
|
||||
String objective = objectiveJson.getAsString();
|
||||
ScoreComponent component = new ScoreComponent( name, objective );
|
||||
JsonElement value = score.get( "value" );
|
||||
if ( value != null && !value.getAsString().isEmpty() )
|
||||
{
|
||||
component.setValue( value.getAsString() );
|
||||
}
|
||||
|
||||
deserialize( json, component, context );
|
||||
return component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(ScoreComponent component, Type type, JsonSerializationContext context)
|
||||
{
|
||||
JsonObject root = new JsonObject();
|
||||
serialize( root, component, context );
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty( "name", component.getName() );
|
||||
json.addProperty( "objective", component.getObjective() );
|
||||
json.addProperty( "value", component.getValue() );
|
||||
root.add( "score", json );
|
||||
return root;
|
||||
}
|
||||
}
|
@@ -1,55 +0,0 @@
|
||||
package net.md_5.bungee.chat;
|
||||
|
||||
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.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
|
||||
{
|
||||
JsonObject object = element.getAsJsonObject();
|
||||
JsonElement selector = object.get( "selector" );
|
||||
if ( selector == null )
|
||||
{
|
||||
throw new JsonParseException( "Could not parse JSON: missing 'selector' property" );
|
||||
}
|
||||
SelectorComponent component = new SelectorComponent( selector.getAsString() );
|
||||
|
||||
JsonElement separator = object.get( "separator" );
|
||||
if ( separator != null )
|
||||
{
|
||||
component.setSeparator( serializer.deserialize( separator.getAsString() ) );
|
||||
}
|
||||
|
||||
deserialize( object, component, context );
|
||||
return component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(SelectorComponent component, Type type, JsonSerializationContext context)
|
||||
{
|
||||
JsonObject object = new JsonObject();
|
||||
serialize( object, component, context );
|
||||
object.addProperty( "selector", component.getSelector() );
|
||||
|
||||
if ( component.getSeparator() != null )
|
||||
{
|
||||
object.addProperty( "separator", serializer.toString( component.getSeparator() ) );
|
||||
}
|
||||
return object;
|
||||
}
|
||||
}
|
@@ -1,43 +0,0 @@
|
||||
package net.md_5.bungee.chat;
|
||||
|
||||
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.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
|
||||
{
|
||||
TextComponent component = new TextComponent();
|
||||
JsonObject object = json.getAsJsonObject();
|
||||
JsonElement text = object.get( "text" );
|
||||
if ( text != null )
|
||||
{
|
||||
component.setText( text.getAsString() );
|
||||
}
|
||||
deserialize( object, component, context );
|
||||
return component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(TextComponent src, Type typeOfSrc, JsonSerializationContext context)
|
||||
{
|
||||
JsonObject object = new JsonObject();
|
||||
serialize( object, src, context );
|
||||
object.addProperty( "text", src.getText() );
|
||||
return object;
|
||||
}
|
||||
}
|
@@ -1,64 +0,0 @@
|
||||
package net.md_5.bungee.chat;
|
||||
|
||||
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.Arrays;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
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
|
||||
{
|
||||
TranslatableComponent component = new TranslatableComponent();
|
||||
JsonObject object = json.getAsJsonObject();
|
||||
deserialize( object, component, context );
|
||||
JsonElement translate = object.get( "translate" );
|
||||
if ( translate == null )
|
||||
{
|
||||
throw new JsonParseException( "Could not parse JSON: missing 'translate' property" );
|
||||
}
|
||||
component.setTranslate( translate.getAsString() );
|
||||
JsonElement with = object.get( "with" );
|
||||
if ( with != null )
|
||||
{
|
||||
component.setWith( Arrays.asList( context.deserialize( with, BaseComponent[].class ) ) );
|
||||
}
|
||||
JsonElement fallback = object.get( "fallback" );
|
||||
if ( fallback != null )
|
||||
{
|
||||
component.setFallback( fallback.getAsString() );
|
||||
}
|
||||
return component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(TranslatableComponent src, Type typeOfSrc, JsonSerializationContext context)
|
||||
{
|
||||
JsonObject object = new JsonObject();
|
||||
serialize( object, src, context );
|
||||
object.addProperty( "translate", src.getTranslate() );
|
||||
if ( src.getWith() != null )
|
||||
{
|
||||
object.add( "with", context.serialize( src.getWith() ) );
|
||||
}
|
||||
if ( src.getFallback() != null )
|
||||
{
|
||||
object.addProperty( "fallback", src.getFallback() );
|
||||
}
|
||||
return object;
|
||||
}
|
||||
}
|
@@ -1,269 +0,0 @@
|
||||
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