#3634: Micro-optimize chat deserialization

This commit is contained in:
Janmm14 2024-03-31 09:38:17 +11:00 committed by md_5
parent e642b9dde1
commit c2f73d32b8
No known key found for this signature in database
GPG Key ID: E8E901AC7C617C11
8 changed files with 96 additions and 76 deletions

View File

@ -244,7 +244,7 @@ public final class ChatColor
public static ChatColor of(String string)
{
Preconditions.checkArgument( string != null, "string cannot be null" );
if ( string.startsWith( "#" ) && string.length() == 7 )
if ( string.length() == 7 && string.charAt( 0 ) == '#' )
{
int rgb;
try

View File

@ -23,59 +23,62 @@ public class BaseComponentSerializer
{
component.applyStyle( context.deserialize( object, ComponentStyle.class ) );
if ( object.has( "insertion" ) )
JsonElement insertion = object.get( "insertion" );
if ( insertion != null )
{
component.setInsertion( object.get( "insertion" ).getAsString() );
component.setInsertion( insertion.getAsString() );
}
//Events
if ( object.has( "clickEvent" ) )
JsonObject clickEvent = object.getAsJsonObject( "clickEvent" );
if ( clickEvent != null )
{
JsonObject event = object.getAsJsonObject( "clickEvent" );
component.setClickEvent( new ClickEvent(
ClickEvent.Action.valueOf( event.get( "action" ).getAsString().toUpperCase( Locale.ROOT ) ),
( event.has( "value" ) ) ? event.get( "value" ).getAsString() : "" ) );
ClickEvent.Action.valueOf( clickEvent.get( "action" ).getAsString().toUpperCase( Locale.ROOT ) ),
( clickEvent.has( "value" ) ) ? clickEvent.get( "value" ).getAsString() : "" ) );
}
if ( object.has( "hoverEvent" ) )
JsonObject hoverEventJson = object.getAsJsonObject( "hoverEvent" );
if ( hoverEventJson != null )
{
JsonObject event = object.getAsJsonObject( "hoverEvent" );
HoverEvent hoverEvent = null;
HoverEvent.Action action = HoverEvent.Action.valueOf( event.get( "action" ).getAsString().toUpperCase( Locale.ROOT ) );
HoverEvent.Action action = HoverEvent.Action.valueOf( hoverEventJson.get( "action" ).getAsString().toUpperCase( Locale.ROOT ) );
if ( event.has( "value" ) )
JsonElement value = hoverEventJson.get( "value" );
if ( value != null )
{
JsonElement contents = event.get( "value" );
// 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 ( contents.isJsonArray() )
if ( value.isJsonArray() )
{
components = context.deserialize( contents, BaseComponent[].class );
components = context.deserialize( value, BaseComponent[].class );
} else
{
components = new BaseComponent[]
{
context.deserialize( contents, BaseComponent.class )
context.deserialize( value, BaseComponent.class )
};
}
hoverEvent = new HoverEvent( action, components );
} else if ( event.has( "contents" ) )
} else
{
JsonElement contents = event.get( "contents" );
Content[] list;
if ( contents.isJsonArray() )
JsonElement contents = hoverEventJson.get( "contents" );
if ( contents != null )
{
list = context.deserialize( contents, HoverEvent.getClass( action, true ) );
} else
{
list = new Content[]
Content[] list;
if ( contents.isJsonArray() )
{
context.deserialize( contents, HoverEvent.getClass( action, false ) )
};
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 ) ) );
}
hoverEvent = new HoverEvent( action, new ArrayList<>( Arrays.asList( list ) ) );
}
if ( hoverEvent != null )
@ -84,9 +87,10 @@ public class BaseComponentSerializer
}
}
if ( object.has( "extra" ) )
JsonElement extra = object.get( "extra" );
if ( extra != null )
{
component.setExtra( Arrays.asList( context.<BaseComponent[]>deserialize( object.get( "extra" ), BaseComponent[].class ) ) );
component.setExtra( Arrays.asList( context.deserialize( extra, BaseComponent[].class ) ) );
}
}

View File

@ -9,6 +9,7 @@ import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
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;
@ -77,33 +78,34 @@ public class ComponentStyleSerializer implements JsonSerializer<ComponentStyle>,
{
ComponentStyleBuilder builder = ComponentStyle.builder();
JsonObject object = json.getAsJsonObject();
if ( object.has( "bold" ) )
for ( Map.Entry<String, JsonElement> entry : object.entrySet() )
{
builder.bold( getAsBoolean( object.get( "bold" ) ) );
}
if ( object.has( "italic" ) )
{
builder.italic( getAsBoolean( object.get( "italic" ) ) );
}
if ( object.has( "underlined" ) )
{
builder.underlined( getAsBoolean( object.get( "underlined" ) ) );
}
if ( object.has( "strikethrough" ) )
{
builder.strikethrough( getAsBoolean( object.get( "strikethrough" ) ) );
}
if ( object.has( "obfuscated" ) )
{
builder.obfuscated( getAsBoolean( object.get( "obfuscated" ) ) );
}
if ( object.has( "color" ) )
{
builder.color( ChatColor.of( object.get( "color" ).getAsString() ) );
}
if ( object.has( "font" ) )
{
builder.font( object.get( "font" ).getAsString() );
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 "font":
builder.font( value.getAsString() );
break;
}
}
return builder.build();
}

View File

@ -17,13 +17,14 @@ public class KeybindComponentSerializer extends BaseComponentSerializer implemen
public KeybindComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
{
JsonObject object = json.getAsJsonObject();
if ( !object.has( "keybind" ) )
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( object.get( "keybind" ).getAsString() );
component.setKeybind( keybind.getAsString() );
return component;
}

View File

@ -17,22 +17,29 @@ public class ScoreComponentSerializer extends BaseComponentSerializer implements
public ScoreComponent deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException
{
JsonObject json = element.getAsJsonObject();
if ( !json.has( "score" ) )
JsonObject score = json.getAsJsonObject( "score" );
if ( score == null )
{
throw new JsonParseException( "Could not parse JSON: missing 'score' property" );
}
JsonObject score = json.get( "score" ).getAsJsonObject();
if ( !score.has( "name" ) || !score.has( "objective" ) )
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 = score.get( "name" ).getAsString();
String objective = score.get( "objective" ).getAsString();
String name = nameJson.getAsString();
String objective = objectiveJson.getAsString();
ScoreComponent component = new ScoreComponent( name, objective );
if ( score.has( "value" ) && !score.get( "value" ).getAsString().isEmpty() )
JsonElement value = score.get( "value" );
if ( value != null && !value.getAsString().isEmpty() )
{
component.setValue( score.get( "value" ).getAsString() );
component.setValue( value.getAsString() );
}
deserialize( json, component, context );

View File

@ -17,15 +17,17 @@ public class SelectorComponentSerializer extends BaseComponentSerializer impleme
public SelectorComponent deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException
{
JsonObject object = element.getAsJsonObject();
if ( !object.has( "selector" ) )
JsonElement selector = object.get( "selector" );
if ( selector == null )
{
throw new JsonParseException( "Could not parse JSON: missing 'selector' property" );
}
SelectorComponent component = new SelectorComponent( object.get( "selector" ).getAsString() );
SelectorComponent component = new SelectorComponent( selector.getAsString() );
if ( object.has( "separator" ) )
JsonElement separator = object.get( "separator" );
if ( separator != null )
{
component.setSeparator( ComponentSerializer.deserialize( object.get( "separator" ).getAsString() ) );
component.setSeparator( ComponentSerializer.deserialize( separator.getAsString() ) );
}
deserialize( object, component, context );

View File

@ -18,9 +18,10 @@ public class TextComponentSerializer extends BaseComponentSerializer implements
{
TextComponent component = new TextComponent();
JsonObject object = json.getAsJsonObject();
if ( object.has( "text" ) )
JsonElement text = object.get( "text" );
if ( text != null )
{
component.setText( object.get( "text" ).getAsString() );
component.setText( text.getAsString() );
}
deserialize( object, component, context );
return component;

View File

@ -21,18 +21,21 @@ public class TranslatableComponentSerializer extends BaseComponentSerializer imp
TranslatableComponent component = new TranslatableComponent();
JsonObject object = json.getAsJsonObject();
deserialize( object, component, context );
if ( !object.has( "translate" ) )
JsonElement translate = object.get( "translate" );
if ( translate == null )
{
throw new JsonParseException( "Could not parse JSON: missing 'translate' property" );
}
component.setTranslate( object.get( "translate" ).getAsString() );
if ( object.has( "with" ) )
component.setTranslate( translate.getAsString() );
JsonElement with = object.get( "with" );
if ( with != null )
{
component.setWith( Arrays.asList( context.deserialize( object.get( "with" ), BaseComponent[].class ) ) );
component.setWith( Arrays.asList( context.deserialize( with, BaseComponent[].class ) ) );
}
if ( object.has( "fallback" ) )
JsonElement fallback = object.get( "fallback" );
if ( fallback != null )
{
component.setFallback( object.get( "fallback" ).getAsString() );
component.setFallback( fallback.getAsString() );
}
return component;
}