Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve chat api toLegacy conversion #3625

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 156 additions & 28 deletions chat/src/main/java/net/md_5/bungee/api/chat/BaseComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -215,11 +215,29 @@ public BaseComponent duplicateWithoutFormatting()
public static String toLegacyText(BaseComponent... components)
{
StringBuilder builder = new StringBuilder();
ComponentStyle currentLegacy = new ComponentStyle();
currentLegacy.setColor( ChatColor.RESET );

toLegacyText( builder, currentLegacy, components );
return builder.toString();
}

/**
* Converts the components to a string that uses the old formatting codes
* ({@link net.md_5.bungee.api.ChatColor#COLOR_CHAR}
*
* @param builder the StringBuilder to append to
* @param currentLegacy the style at the end of {@code builder}
* @param components the components to convert
* @return the style at the end of the legacy string
*/
public static ComponentStyle toLegacyText(StringBuilder builder, ComponentStyle currentLegacy, BaseComponent... components)
{
for ( BaseComponent msg : components )
{
builder.append( msg.toLegacyText() );
currentLegacy = msg.toLegacyText( builder, currentLegacy );
}
return builder.toString();
return currentLegacy;
}

/**
Expand Down Expand Up @@ -273,15 +291,20 @@ public void setColor(ChatColor color)
*/
public ChatColor getColor()
{
if ( !style.hasColor() )
return getColor( ChatColor.WHITE );
}

ChatColor getColor(ChatColor def)
{
if ( style.hasColor() )
{
if ( parent == null )
{
return ChatColor.WHITE;
}
return parent.getColor();
return style.getColor();
}
return style.getColor();
if ( parent == null )
{
return def;
}
return parent.getColor( def );
}

/**
Expand Down Expand Up @@ -651,43 +674,148 @@ void toPlainText(StringBuilder builder)
public String toLegacyText()
{
StringBuilder builder = new StringBuilder();
toLegacyText( builder );
ComponentStyle currentLegacy = new ComponentStyle();
currentLegacy.setColor( ChatColor.RESET );
toLegacyText( builder, currentLegacy );
return builder.toString();
}

void toLegacyText(StringBuilder builder)
/**
* Converts the component to a string that uses the old formatting codes
* ({@link net.md_5.bungee.api.ChatColor#COLOR_CHAR}
*
* @param currentLegacy the style at the end of the string the result of this method will be appended to
* @return the string in the old format
*/
public String toLegacyText(ComponentStyle currentLegacy)
{
if ( extra != null )
StringBuilder builder = new StringBuilder();
toLegacyText( builder, currentLegacy );
return builder.toString();
}

/**
* Converts the component to a string that uses the old formatting codes
* ({@link net.md_5.bungee.api.ChatColor#COLOR_CHAR}
*
* @param builder the StringBuilder to append to
* @param currentLegacy the style at the end of {@code builder}
* @return the style at the end of the legacy string
*/
public ComponentStyle toLegacyText(StringBuilder builder, ComponentStyle currentLegacy)
{
currentLegacy = currentLegacy.clone();
if ( !currentLegacy.hasColor() )
{
for ( BaseComponent e : extra )
{
e.toLegacyText( builder );
}
currentLegacy.setColor( ChatColor.RESET );
}
return toLegacyText( builder, currentLegacy.hasColor() ? currentLegacy.getColor() : ChatColor.RESET, currentLegacy );
}

void addFormat(StringBuilder builder)
/**
* Converts the component to a string that uses the old formatting codes
* ({@link net.md_5.bungee.api.ChatColor#COLOR_CHAR}
*
* @param builder the StringBuilder to append to
* @param baseColor the color to use if no color is set, but a format downgrade is needed
* @param currentLegacy the style at the end of {@code builder}
* @return the new current style at the end of the {@code builder}
*/
ComponentStyle toLegacyText(StringBuilder builder, ChatColor baseColor, ComponentStyle currentLegacy)
{
builder.append( getColor() );
if ( isBold() )
if ( extra == null )
{
builder.append( ChatColor.BOLD );
return currentLegacy;
}
if ( isItalic() )
for ( BaseComponent e : extra )
{
currentLegacy = e.toLegacyText( builder, baseColor, currentLegacy );
}
return currentLegacy;
}

private static boolean colorEquals(ChatColor a, ChatColor b)
{
if ( a == b )
{
builder.append( ChatColor.ITALIC );
return true;
}
if ( isUnderlined() )
if ( a == null || b == null )
{
builder.append( ChatColor.UNDERLINE );
return false;
}
if ( isStrikethrough() )
if ( ChatColor.RESET.equals( a ) )
{
builder.append( ChatColor.STRIKETHROUGH );
return ChatColor.WHITE.equals( b ) || ChatColor.RESET.equals( b );
}
if ( ChatColor.RESET.equals( b ) )
{
return ChatColor.WHITE.equals( a ) || ChatColor.RESET.equals( a );
}
return a.equals( b );
}

/**
* @param builder the StringBuilder to append to
* @param baseColor the color to use if no color is set, but a format downgrade is needed
* @param currentLegacy the style at the end of {@code builder}
* @return the new current style at the end of {@code builder}
*/
ComponentStyle addFormat(StringBuilder builder, ChatColor baseColor, ComponentStyle currentLegacy)
{
// Check if we can skip adding color code
if ( colorEquals( getColor(), currentLegacy.getColor() ) && currentLegacy.isLegacyFormattingUpgrade( style ) )
{
if ( isBold() && !currentLegacy.isBold() )
{
builder.append( ChatColor.BOLD );
}
if ( isItalic() && !currentLegacy.isItalic() )
{
builder.append( ChatColor.ITALIC );
}
if ( isUnderlined() && !currentLegacy.isUnderlined() )
{
builder.append( ChatColor.UNDERLINE );
}
if ( isStrikethrough() && !currentLegacy.isStrikethrough() )
{
builder.append( ChatColor.STRIKETHROUGH );
}
if ( isObfuscated() && !currentLegacy.isObfuscated() )
{
builder.append( ChatColor.MAGIC );
}
} else
{
builder.append( getColor( baseColor ) == null ? baseColor : getColor( baseColor ) );
if ( isBold() )
{
builder.append( ChatColor.BOLD );
}
if ( isItalic() )
{
builder.append( ChatColor.ITALIC );
}
if ( isUnderlined() )
{
builder.append( ChatColor.UNDERLINE );
}
if ( isStrikethrough() )
{
builder.append( ChatColor.STRIKETHROUGH );
}
if ( isObfuscated() )
{
builder.append( ChatColor.MAGIC );
}
}
if ( isObfuscated() )
currentLegacy = style;
if ( currentLegacy.getColor() == null )
{
builder.append( ChatColor.MAGIC );
currentLegacy = style.clone();
currentLegacy.setColor( getColor( baseColor ) == null ? baseColor : getColor( baseColor ) );
}
return currentLegacy;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,10 @@ public ComponentBuilder retain(FormatRetention retention)
public BaseComponent build()
{
TextComponent base = new TextComponent();
if ( parts.size() == 1 )
{
return parts.get( 0 );
}
if ( !parts.isEmpty() )
{
List<BaseComponent> cloned = new ArrayList<>( parts );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,15 @@ public boolean isEmpty()
&& strikethrough == null && obfuscated == null;
}

boolean isLegacyFormattingUpgrade(ComponentStyle newStyle)
{
return ( newStyle.isBold() || !isBold() )
&& ( newStyle.isItalic() || !isItalic() )
&& ( newStyle.isUnderlined() || !isUnderlined() )
&& ( newStyle.isStrikethrough() || !isStrikethrough() )
&& ( newStyle.isObfuscated() || !isObfuscated() );
}

@Override
public ComponentStyle clone()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import net.md_5.bungee.api.ChatColor;

@Getter
@Setter
Expand Down Expand Up @@ -57,10 +58,10 @@ protected void toPlainText(StringBuilder builder)
}

@Override
protected void toLegacyText(StringBuilder builder)
ComponentStyle toLegacyText(StringBuilder builder, ChatColor baseColor, ComponentStyle currentLegacy)
{
addFormat( builder );
currentLegacy = addFormat( builder, baseColor, currentLegacy );
builder.append( getKeybind() );
super.toLegacyText( builder );
return super.toLegacyText( builder, baseColor, currentLegacy );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import net.md_5.bungee.api.ChatColor;

/**
* This component displays the score based on a player score on the scoreboard.
Expand Down Expand Up @@ -92,10 +93,10 @@ protected void toPlainText(StringBuilder builder)
}

@Override
protected void toLegacyText(StringBuilder builder)
ComponentStyle toLegacyText(StringBuilder builder, ChatColor baseColor, ComponentStyle currentLegacy)
{
addFormat( builder );
currentLegacy = addFormat( builder, baseColor, currentLegacy );
builder.append( this.value );
super.toLegacyText( builder );
return super.toLegacyText( builder, baseColor, currentLegacy );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import net.md_5.bungee.api.ChatColor;

/**
* This component processes a target selector into a pre-formatted set of
Expand Down Expand Up @@ -76,10 +77,10 @@ protected void toPlainText(StringBuilder builder)
}

@Override
protected void toLegacyText(StringBuilder builder)
ComponentStyle toLegacyText(StringBuilder builder, ChatColor baseColor, ComponentStyle currentLegacy)
{
addFormat( builder );
currentLegacy = addFormat( builder, baseColor, currentLegacy );
builder.append( this.selector );
super.toLegacyText( builder );
return super.toLegacyText( builder, baseColor, currentLegacy );
}
}
11 changes: 7 additions & 4 deletions chat/src/main/java/net/md_5/bungee/api/chat/TextComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ public TextComponent(BaseComponent... extras)
{
return;
}
setExtra( new ArrayList<BaseComponent>( Arrays.asList( extras ) ) );
setExtra( new ArrayList<>( Arrays.asList( extras ) ) );
}

/**
Expand All @@ -287,11 +287,14 @@ protected void toPlainText(StringBuilder builder)
}

@Override
protected void toLegacyText(StringBuilder builder)
ComponentStyle toLegacyText(StringBuilder builder, ChatColor baseColor, ComponentStyle currentLegacy)
{
addFormat( builder );
// cannot eliminate formatting codes if text is empty to keep test case testFormattingOnlyTextConversion happy
// (this could be solved to always add formatting if (parent == null) and to not ignore formatting at the end in
// general in case plugins are doing weird combinations with conversions
currentLegacy = addFormat( builder, baseColor, currentLegacy );
builder.append( text );
super.toLegacyText( builder );
return super.toLegacyText( builder, baseColor, currentLegacy );
}

@Override
Expand Down
Loading