#3774: Minecraft 25w04a chat component changes
This commit is contained in:
parent
4fded9828f
commit
80bb237289
@ -3,7 +3,9 @@ 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
|
||||
@ -23,6 +25,13 @@ 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
|
||||
{
|
||||
|
||||
|
@ -14,6 +14,7 @@ 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 org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@ -34,8 +35,33 @@ public final class HoverEvent
|
||||
* Returns whether this hover event is prior to 1.16
|
||||
*/
|
||||
@Setter
|
||||
@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.
|
||||
*
|
||||
|
@ -7,6 +7,7 @@ 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
|
||||
@ -15,6 +16,18 @@ import net.md_5.bungee.api.chat.HoverEvent;
|
||||
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.
|
||||
*
|
||||
@ -35,6 +48,12 @@ 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()
|
||||
{
|
||||
|
@ -19,20 +19,23 @@ public class EntitySerializer implements JsonSerializer<Entity>, JsonDeserialize
|
||||
{
|
||||
JsonObject value = element.getAsJsonObject();
|
||||
|
||||
boolean newEntity = value.has( "uuid" );
|
||||
|
||||
String idString;
|
||||
JsonElement id = value.get( "id" );
|
||||
if ( id.isJsonArray() )
|
||||
JsonElement uuid = value.get( newEntity ? "uuid" : "id" );
|
||||
if ( uuid.isJsonArray() )
|
||||
{
|
||||
idString = parseUUID( context.deserialize( id, int[].class ) ).toString();
|
||||
idString = parseUUID( context.deserialize( uuid, int[].class ) ).toString();
|
||||
} else
|
||||
{
|
||||
idString = id.getAsString();
|
||||
idString = uuid.getAsString();
|
||||
}
|
||||
|
||||
return new Entity(
|
||||
( value.has( "type" ) ) ? value.get( "type" ).getAsString() : null,
|
||||
( value.has( newEntity ? "id" : "type" ) ) ? value.get( newEntity ? "id" : "type" ).getAsString() : null,
|
||||
idString,
|
||||
( value.has( "name" ) ) ? context.deserialize( value.get( "name" ), BaseComponent.class ) : null
|
||||
( value.has( "name" ) ) ? context.deserialize( value.get( "name" ), BaseComponent.class ) : null,
|
||||
newEntity
|
||||
);
|
||||
}
|
||||
|
||||
@ -40,8 +43,9 @@ public class EntitySerializer implements JsonSerializer<Entity>, JsonDeserialize
|
||||
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() );
|
||||
|
||||
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() );
|
||||
if ( content.getName() != null )
|
||||
{
|
||||
object.add( "name", context.serialize( content.getName() ) );
|
||||
|
@ -30,42 +30,65 @@ public class BaseComponentSerializer
|
||||
}
|
||||
|
||||
//Events
|
||||
JsonObject clickEvent = object.getAsJsonObject( "clickEvent" );
|
||||
JsonObject clickEvent;
|
||||
boolean newClickEvent = ( clickEvent = object.getAsJsonObject( "click_event" ) ) != null;
|
||||
if ( !newClickEvent )
|
||||
{
|
||||
clickEvent = object.getAsJsonObject( "clickEvent" );
|
||||
}
|
||||
if ( clickEvent != null )
|
||||
{
|
||||
component.setClickEvent( new ClickEvent(
|
||||
ClickEvent.Action.valueOf( clickEvent.get( "action" ).getAsString().toUpperCase( Locale.ROOT ) ),
|
||||
( clickEvent.has( "value" ) ) ? clickEvent.get( "value" ).getAsString() : "" ) );
|
||||
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;
|
||||
}
|
||||
component.getClickEvent().setV1_21_5( true );
|
||||
} else
|
||||
{
|
||||
component.setClickEvent( new ClickEvent( action, ( clickEvent.has( "value" ) ) ? clickEvent.get( "value" ).getAsString() : "" ) );
|
||||
}
|
||||
}
|
||||
JsonObject hoverEventJson = object.getAsJsonObject( "hoverEvent" );
|
||||
|
||||
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 ) );
|
||||
|
||||
JsonElement value = hoverEventJson.get( "value" );
|
||||
if ( value != null )
|
||||
if ( newHoverEvent || hoverEventJson.has( "contents" ) )
|
||||
{
|
||||
|
||||
// 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() )
|
||||
// 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 ) ) )
|
||||
{
|
||||
components = context.deserialize( value, BaseComponent[].class );
|
||||
} else
|
||||
{
|
||||
components = new BaseComponent[]
|
||||
if ( contents == null )
|
||||
{
|
||||
context.deserialize( value, BaseComponent.class )
|
||||
};
|
||||
}
|
||||
hoverEvent = new HoverEvent( action, components );
|
||||
} else
|
||||
{
|
||||
JsonElement contents = hoverEventJson.get( "contents" );
|
||||
if ( contents != null )
|
||||
{
|
||||
// this is the new inline for SHOW_ITEM and SHOW_ENTITY
|
||||
contents = hoverEventJson;
|
||||
}
|
||||
Content[] list;
|
||||
if ( contents.isJsonArray() )
|
||||
{
|
||||
@ -78,6 +101,27 @@ public class BaseComponentSerializer
|
||||
};
|
||||
}
|
||||
hoverEvent = new HoverEvent( action, new ArrayList<>( Arrays.asList( list ) ) );
|
||||
hoverEvent.setV1_21_5( newHoverEvent );
|
||||
}
|
||||
} 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 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,23 +162,65 @@ public class BaseComponentSerializer
|
||||
if ( component.getClickEvent() != null )
|
||||
{
|
||||
JsonObject clickEvent = new JsonObject();
|
||||
clickEvent.addProperty( "action", component.getClickEvent().getAction().toString().toLowerCase( Locale.ROOT ) );
|
||||
clickEvent.addProperty( "value", component.getClickEvent().getValue() );
|
||||
object.add( "clickEvent", clickEvent );
|
||||
String actionName = component.getClickEvent().getAction().toString().toLowerCase( Locale.ROOT );
|
||||
clickEvent.addProperty( "action", actionName.toLowerCase( Locale.ROOT ) );
|
||||
if ( component.getClickEvent().isV1_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 );
|
||||
} else
|
||||
{
|
||||
clickEvent.addProperty( "value", component.getClickEvent().getValue() );
|
||||
object.add( "clickEvent", clickEvent );
|
||||
}
|
||||
|
||||
}
|
||||
if ( component.getHoverEvent() != null )
|
||||
{
|
||||
JsonObject hoverEvent = new JsonObject();
|
||||
hoverEvent.addProperty( "action", component.getHoverEvent().getAction().toString().toLowerCase( Locale.ROOT ) );
|
||||
boolean newFormat = component.getHoverEvent().isV1_21_5();
|
||||
if ( component.getHoverEvent().isLegacy() )
|
||||
{
|
||||
hoverEvent.add( "value", context.serialize( component.getHoverEvent().getContents().get( 0 ) ) );
|
||||
} else
|
||||
{
|
||||
hoverEvent.add( "contents", context.serialize( ( component.getHoverEvent().getContents().size() == 1 )
|
||||
? component.getHoverEvent().getContents().get( 0 ) : component.getHoverEvent().getContents() ) );
|
||||
if ( newFormat )
|
||||
{
|
||||
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() ) );
|
||||
}
|
||||
} else
|
||||
{
|
||||
hoverEvent.add( "contents", context.serialize( ( component.getHoverEvent().getContents().size() == 1 )
|
||||
? component.getHoverEvent().getContents().get( 0 ) : component.getHoverEvent().getContents() ) );
|
||||
}
|
||||
|
||||
}
|
||||
object.add( "hoverEvent", hoverEvent );
|
||||
object.add( newFormat ? "hover_event" : "hoverEvent", hoverEvent );
|
||||
}
|
||||
|
||||
if ( component.getExtra() != null )
|
||||
|
@ -50,6 +50,20 @@ public final class ChatComponentTransformer
|
||||
next.getHoverEvent().getContents().clear();
|
||||
next.getHoverEvent().getContents().add( exception );
|
||||
}
|
||||
} else if ( player.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_21_5 )
|
||||
{
|
||||
if ( next.getHoverEvent() != null && !next.getHoverEvent().isV1_21_5() )
|
||||
{
|
||||
next = next.duplicate();
|
||||
next.getHoverEvent().setV1_21_5( true );
|
||||
}
|
||||
|
||||
if ( next.getClickEvent() != null && !next.getClickEvent().isV1_21_5() )
|
||||
{
|
||||
next = next.duplicate();
|
||||
next.getClickEvent().setV1_21_5( true );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return next;
|
||||
|
Loading…
Reference in New Issue
Block a user