Skip to content

Commit 7587f03

Browse files
committed
SPIGOT-8024, SpigotMC#3811, SpigotMC#3812: Add versioned chat serialization (beta)
1 parent 77b81f2 commit 7587f03

24 files changed

+464
-279
lines changed

chat/src/main/java/net/md_5/bungee/api/chat/ClickEvent.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
import lombok.EqualsAndHashCode;
44
import lombok.Getter;
55
import lombok.RequiredArgsConstructor;
6-
import lombok.Setter;
76
import lombok.ToString;
8-
import org.jetbrains.annotations.ApiStatus;
97

108
@Getter
119
@ToString
@@ -25,13 +23,6 @@ public final class ClickEvent
2523
*/
2624
private final String value;
2725

28-
/**
29-
* Returns whether this click event is used for version above 1.21.4
30-
*/
31-
@Setter
32-
@ApiStatus.Internal
33-
private boolean v1_21_5 = false;
34-
3526
public enum Action
3627
{
3728

chat/src/main/java/net/md_5/bungee/api/chat/HoverEvent.java

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import net.md_5.bungee.api.chat.hover.content.Entity;
1414
import net.md_5.bungee.api.chat.hover.content.Item;
1515
import net.md_5.bungee.api.chat.hover.content.Text;
16-
import net.md_5.bungee.chat.ComponentSerializer;
16+
import net.md_5.bungee.chat.VersionedComponentSerializer;
1717
import org.jetbrains.annotations.ApiStatus;
1818

1919
@Getter
@@ -38,30 +38,6 @@ public final class HoverEvent
3838
@ApiStatus.Internal
3939
private boolean legacy = false;
4040

41-
/**
42-
* Returns whether this hover event is used for version above 1.21.4
43-
*/
44-
@ApiStatus.Internal
45-
private boolean v1_21_5 = false;
46-
47-
/**
48-
* Set the compatibility to 1.21.5, also modifies the underlying entities.
49-
*
50-
* @param v1_21_5 the compatibility to set
51-
*/
52-
@ApiStatus.Internal
53-
public void setV1_21_5(boolean v1_21_5)
54-
{
55-
this.v1_21_5 = v1_21_5;
56-
for ( Content content : contents )
57-
{
58-
if ( content instanceof Entity )
59-
{
60-
( (Entity) content ).setV1_21_5( v1_21_5 );
61-
}
62-
}
63-
}
64-
6541
/**
6642
* Creates event with an action and a list of contents.
6743
*
@@ -106,7 +82,7 @@ public BaseComponent[] getValue()
10682
return (BaseComponent[]) ( (Text) content ).getValue();
10783
}
10884

109-
TextComponent component = new TextComponent( ComponentSerializer.toString( content ) );
85+
TextComponent component = new TextComponent( VersionedComponentSerializer.getDefault().toString( content ) );
11086
return new BaseComponent[]
11187
{
11288
component

chat/src/main/java/net/md_5/bungee/api/chat/hover/content/Entity.java

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import lombok.ToString;
88
import net.md_5.bungee.api.chat.BaseComponent;
99
import net.md_5.bungee.api.chat.HoverEvent;
10-
import org.jetbrains.annotations.ApiStatus;
1110

1211
@Data
1312
@AllArgsConstructor
@@ -16,18 +15,6 @@
1615
public class Entity extends Content
1716
{
1817

19-
/**
20-
* Required for backwards compatibility.
21-
*
22-
* @param type the type of the entity, for example 'minecraft:pig'
23-
* @param id for example '6cb1b229-ce5c-4179-af8d-eea185c25963'
24-
* @param name the name of the entity
25-
*/
26-
public Entity(String type, @NonNull String id, BaseComponent name)
27-
{
28-
this( type, id, name, false );
29-
}
30-
3118
/**
3219
* Namespaced entity ID.
3320
*
@@ -48,12 +35,6 @@ public Entity(String type, @NonNull String id, BaseComponent name)
4835
*/
4936
private BaseComponent name;
5037

51-
/**
52-
* True if this entity is for 1.21.5 or later
53-
*/
54-
@ApiStatus.Internal
55-
private boolean v1_21_5;
56-
5738
@Override
5839
public HoverEvent.Action requiredAction()
5940
{

chat/src/main/java/net/md_5/bungee/api/chat/hover/content/EntitySerializer.java

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,17 @@
1010
import java.lang.reflect.Type;
1111
import java.util.UUID;
1212
import net.md_5.bungee.api.chat.BaseComponent;
13+
import net.md_5.bungee.chat.BaseComponentSerializer;
14+
import net.md_5.bungee.chat.VersionedComponentSerializer;
1315

14-
public class EntitySerializer implements JsonSerializer<Entity>, JsonDeserializer<Entity>
16+
public class EntitySerializer extends BaseComponentSerializer implements JsonSerializer<Entity>, JsonDeserializer<Entity>
1517
{
1618

19+
public EntitySerializer(VersionedComponentSerializer serializer)
20+
{
21+
super( serializer );
22+
}
23+
1724
@Override
1825
public Entity deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException
1926
{
@@ -34,8 +41,7 @@ public Entity deserialize(JsonElement element, Type type, JsonDeserializationCon
3441
return new Entity(
3542
( value.has( newEntity ? "id" : "type" ) ) ? value.get( newEntity ? "id" : "type" ).getAsString() : null,
3643
idString,
37-
( value.has( "name" ) ) ? context.deserialize( value.get( "name" ), BaseComponent.class ) : null,
38-
newEntity
44+
( value.has( "name" ) ) ? context.deserialize( value.get( "name" ), BaseComponent.class ) : null
3945
);
4046
}
4147

@@ -44,8 +50,20 @@ public JsonElement serialize(Entity content, Type type, JsonSerializationContext
4450
{
4551
JsonObject object = new JsonObject();
4652

47-
object.addProperty( content.isV1_21_5() ? "id" : "type", ( content.getType() != null ) ? content.getType() : "minecraft:pig" );
48-
object.addProperty( content.isV1_21_5() ? "uuid" : "id", content.getId() );
53+
switch ( serializer.getVersion() )
54+
{
55+
case V1_21_5:
56+
object.addProperty( "id", ( content.getType() != null ) ? content.getType() : "minecraft:pig" );
57+
object.addProperty( "uuid", content.getId() );
58+
break;
59+
case V1_16:
60+
object.addProperty( "type", ( content.getType() != null ) ? content.getType() : "minecraft:pig" );
61+
object.addProperty( "id", content.getId() );
62+
break;
63+
default:
64+
throw new IllegalArgumentException( "Unknown version " + serializer.getVersion() );
65+
}
66+
4967
if ( content.getName() != null )
5068
{
5169
object.add( "name", context.serialize( content.getName() ) );

chat/src/main/java/net/md_5/bungee/chat/BaseComponentSerializer.java

Lines changed: 66 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,19 @@
1010
import java.util.Collections;
1111
import java.util.IdentityHashMap;
1212
import java.util.Locale;
13+
import lombok.RequiredArgsConstructor;
1314
import net.md_5.bungee.api.chat.BaseComponent;
1415
import net.md_5.bungee.api.chat.ClickEvent;
1516
import net.md_5.bungee.api.chat.ComponentStyle;
1617
import net.md_5.bungee.api.chat.HoverEvent;
1718
import net.md_5.bungee.api.chat.hover.content.Content;
1819

20+
@RequiredArgsConstructor
1921
public class BaseComponentSerializer
2022
{
2123

24+
protected final VersionedComponentSerializer serializer;
25+
2226
protected void deserialize(JsonObject object, BaseComponent component, JsonDeserializationContext context)
2327
{
2428
component.applyStyle( context.deserialize( object, ComponentStyle.class ) );
@@ -59,7 +63,6 @@ protected void deserialize(JsonObject object, BaseComponent component, JsonDeser
5963
component.setClickEvent( new ClickEvent( action, ( clickEvent.has( "value" ) ) ? clickEvent.get( "value" ).getAsString() : "" ) );
6064
break;
6165
}
62-
component.getClickEvent().setV1_21_5( true );
6366
} else
6467
{
6568
component.setClickEvent( new ClickEvent( action, ( clickEvent.has( "value" ) ) ? clickEvent.get( "value" ).getAsString() : "" ) );
@@ -101,7 +104,6 @@ protected void deserialize(JsonObject object, BaseComponent component, JsonDeser
101104
};
102105
}
103106
hoverEvent = new HoverEvent( action, new ArrayList<>( Arrays.asList( list ) ) );
104-
hoverEvent.setV1_21_5( newHoverEvent );
105107
}
106108
} else
107109
{
@@ -141,15 +143,15 @@ protected void deserialize(JsonObject object, BaseComponent component, JsonDeser
141143
protected void serialize(JsonObject object, BaseComponent component, JsonSerializationContext context)
142144
{
143145
boolean first = false;
144-
if ( ComponentSerializer.serializedComponents.get() == null )
146+
if ( VersionedComponentSerializer.serializedComponents.get() == null )
145147
{
146148
first = true;
147-
ComponentSerializer.serializedComponents.set( Collections.newSetFromMap( new IdentityHashMap<BaseComponent, Boolean>() ) );
149+
VersionedComponentSerializer.serializedComponents.set( Collections.newSetFromMap( new IdentityHashMap<BaseComponent, Boolean>() ) );
148150
}
149151
try
150152
{
151-
Preconditions.checkArgument( !ComponentSerializer.serializedComponents.get().contains( component ), "Component loop" );
152-
ComponentSerializer.serializedComponents.get().add( component );
153+
Preconditions.checkArgument( !VersionedComponentSerializer.serializedComponents.get().contains( component ), "Component loop" );
154+
VersionedComponentSerializer.serializedComponents.get().add( component );
153155

154156
ComponentStyleSerializer.serializeTo( component.getStyle(), object );
155157

@@ -164,63 +166,79 @@ protected void serialize(JsonObject object, BaseComponent component, JsonSeriali
164166
JsonObject clickEvent = new JsonObject();
165167
String actionName = component.getClickEvent().getAction().toString().toLowerCase( Locale.ROOT );
166168
clickEvent.addProperty( "action", actionName.toLowerCase( Locale.ROOT ) );
167-
if ( component.getClickEvent().isV1_21_5() )
169+
switch ( serializer.getVersion() )
168170
{
169-
ClickEvent.Action action = ClickEvent.Action.valueOf( actionName.toUpperCase( Locale.ROOT ) );
170-
switch ( action )
171-
{
172-
case OPEN_URL:
173-
clickEvent.addProperty( "url", component.getClickEvent().getValue() );
174-
break;
175-
case RUN_COMMAND:
176-
case SUGGEST_COMMAND:
177-
clickEvent.addProperty( "command", component.getClickEvent().getValue() );
178-
break;
179-
case CHANGE_PAGE:
180-
clickEvent.addProperty( "page", Integer.parseInt( component.getClickEvent().getValue() ) );
181-
break;
182-
default:
183-
clickEvent.addProperty( "value", component.getClickEvent().getValue() );
184-
break;
185-
}
186-
object.add( "click_event", clickEvent );
187-
} else
188-
{
189-
clickEvent.addProperty( "value", component.getClickEvent().getValue() );
190-
object.add( "clickEvent", clickEvent );
171+
case V1_21_5:
172+
ClickEvent.Action action = ClickEvent.Action.valueOf( actionName.toUpperCase( Locale.ROOT ) );
173+
switch ( action )
174+
{
175+
case OPEN_URL:
176+
clickEvent.addProperty( "url", component.getClickEvent().getValue() );
177+
break;
178+
case RUN_COMMAND:
179+
case SUGGEST_COMMAND:
180+
clickEvent.addProperty( "command", component.getClickEvent().getValue() );
181+
break;
182+
case CHANGE_PAGE:
183+
clickEvent.addProperty( "page", Integer.parseInt( component.getClickEvent().getValue() ) );
184+
break;
185+
default:
186+
clickEvent.addProperty( "value", component.getClickEvent().getValue() );
187+
break;
188+
}
189+
object.add( "click_event", clickEvent );
190+
break;
191+
case V1_16:
192+
clickEvent.addProperty( "value", component.getClickEvent().getValue() );
193+
object.add( "clickEvent", clickEvent );
194+
break;
195+
default:
196+
throw new IllegalArgumentException( "Unknown version " + serializer.getVersion() );
191197
}
192198

193199
}
194200
if ( component.getHoverEvent() != null )
195201
{
196202
JsonObject hoverEvent = new JsonObject();
197203
hoverEvent.addProperty( "action", component.getHoverEvent().getAction().toString().toLowerCase( Locale.ROOT ) );
198-
boolean newFormat = component.getHoverEvent().isV1_21_5();
199204
if ( component.getHoverEvent().isLegacy() )
200205
{
201206
hoverEvent.add( "value", context.serialize( component.getHoverEvent().getContents().get( 0 ) ) );
202207
} else
203208
{
204-
if ( newFormat )
209+
switch ( serializer.getVersion() )
205210
{
206-
if ( component.getHoverEvent().getAction() == HoverEvent.Action.SHOW_ITEM || component.getHoverEvent().getAction() == HoverEvent.Action.SHOW_ENTITY )
207-
{
208-
JsonObject inlined = context.serialize( ( component.getHoverEvent().getContents().size() == 1 )
209-
? component.getHoverEvent().getContents().get( 0 ) : component.getHoverEvent().getContents() ).getAsJsonObject();
210-
inlined.entrySet().forEach( entry -> hoverEvent.add( entry.getKey(), entry.getValue() ) );
211-
} else
212-
{
213-
hoverEvent.add( "value", context.serialize( ( component.getHoverEvent().getContents().size() == 1 )
211+
case V1_21_5:
212+
if ( component.getHoverEvent().getAction() == HoverEvent.Action.SHOW_ITEM || component.getHoverEvent().getAction() == HoverEvent.Action.SHOW_ENTITY )
213+
{
214+
JsonObject inlined = context.serialize( ( component.getHoverEvent().getContents().size() == 1 )
215+
? component.getHoverEvent().getContents().get( 0 ) : component.getHoverEvent().getContents() ).getAsJsonObject();
216+
inlined.entrySet().forEach( entry -> hoverEvent.add( entry.getKey(), entry.getValue() ) );
217+
} else
218+
{
219+
hoverEvent.add( "value", context.serialize( ( component.getHoverEvent().getContents().size() == 1 )
220+
? component.getHoverEvent().getContents().get( 0 ) : component.getHoverEvent().getContents() ) );
221+
}
222+
break;
223+
case V1_16:
224+
hoverEvent.add( "contents", context.serialize( ( component.getHoverEvent().getContents().size() == 1 )
214225
? component.getHoverEvent().getContents().get( 0 ) : component.getHoverEvent().getContents() ) );
215-
}
216-
} else
217-
{
218-
hoverEvent.add( "contents", context.serialize( ( component.getHoverEvent().getContents().size() == 1 )
219-
? component.getHoverEvent().getContents().get( 0 ) : component.getHoverEvent().getContents() ) );
226+
break;
227+
default:
228+
throw new IllegalArgumentException( "Unknown version " + serializer.getVersion() );
220229
}
221-
222230
}
223-
object.add( newFormat ? "hover_event" : "hoverEvent", hoverEvent );
231+
switch ( serializer.getVersion() )
232+
{
233+
case V1_21_5:
234+
object.add( "hover_event", hoverEvent );
235+
break;
236+
case V1_16:
237+
object.add( "hoverEvent", hoverEvent );
238+
break;
239+
default:
240+
throw new IllegalArgumentException( "Unknown version " + serializer.getVersion() );
241+
}
224242
}
225243

226244
if ( component.getExtra() != null )
@@ -229,10 +247,10 @@ protected void serialize(JsonObject object, BaseComponent component, JsonSeriali
229247
}
230248
} finally
231249
{
232-
ComponentSerializer.serializedComponents.get().remove( component );
250+
VersionedComponentSerializer.serializedComponents.get().remove( component );
233251
if ( first )
234252
{
235-
ComponentSerializer.serializedComponents.set( null );
253+
VersionedComponentSerializer.serializedComponents.set( null );
236254
}
237255
}
238256
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package net.md_5.bungee.chat;
2+
3+
import org.jetbrains.annotations.ApiStatus;
4+
5+
@ApiStatus.Internal
6+
public enum ChatVersion
7+
{
8+
V1_16,
9+
V1_21_5;
10+
}

0 commit comments

Comments
 (0)