Skip to content

Commit 32dfedc

Browse files
committed
Improve chat api toLegacy conversion
The target is to output less redundant legacy codes, this has been achieved by using context-aware toLegacy conversion which keeps track of the current end-of-string style. Fixes behaviour change introduced in f4144eb8c2e83f43f41b24b4ea8b03b0f4c9c44e of array toLegacy conversion where the next array element would no longer reset to white color.
1 parent 7a64e0d commit 32dfedc

9 files changed

+217
-78
lines changed

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

+154-29
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,29 @@ public BaseComponent duplicateWithoutFormatting()
215215
public static String toLegacyText(BaseComponent... components)
216216
{
217217
StringBuilder builder = new StringBuilder();
218+
ComponentStyle currentLegacy = new ComponentStyle();
219+
currentLegacy.setColor( ChatColor.RESET );
220+
221+
toLegacyText( builder, currentLegacy, components );
222+
return builder.toString();
223+
}
224+
225+
/**
226+
* Converts the components to a string that uses the old formatting codes
227+
* ({@link net.md_5.bungee.api.ChatColor#COLOR_CHAR}
228+
*
229+
* @param builder the StringBuilder to append to
230+
* @param currentLegacy the style at the end of {@code builder}
231+
* @param components the components to convert
232+
* @return the style at the end of the legacy string
233+
*/
234+
public static ComponentStyle toLegacyText(StringBuilder builder, ComponentStyle currentLegacy, BaseComponent... components)
235+
{
218236
for ( BaseComponent msg : components )
219237
{
220-
builder.append( msg.toLegacyText() );
238+
currentLegacy = msg.toLegacyText( builder, currentLegacy );
221239
}
222-
return builder.toString();
240+
return currentLegacy;
223241
}
224242

225243
/**
@@ -273,15 +291,20 @@ public void setColor(ChatColor color)
273291
*/
274292
public ChatColor getColor()
275293
{
276-
if ( !style.hasColor() )
294+
return getColor( ChatColor.WHITE );
295+
}
296+
297+
ChatColor getColor(ChatColor def)
298+
{
299+
if ( style.hasColor() )
277300
{
278-
if ( parent == null )
279-
{
280-
return ChatColor.WHITE;
281-
}
282-
return parent.getColor();
301+
return style.getColor();
283302
}
284-
return style.getColor();
303+
if ( parent == null )
304+
{
305+
return def;
306+
}
307+
return parent.getColor( def );
285308
}
286309

287310
/**
@@ -651,46 +674,148 @@ void toPlainText(StringBuilder builder)
651674
public String toLegacyText()
652675
{
653676
StringBuilder builder = new StringBuilder();
654-
toLegacyText( builder );
677+
ComponentStyle currentLegacy = new ComponentStyle();
678+
currentLegacy.setColor( ChatColor.RESET );
679+
toLegacyText( builder, currentLegacy );
655680
return builder.toString();
656681
}
657682

658-
void toLegacyText(StringBuilder builder)
683+
/**
684+
* Converts the component to a string that uses the old formatting codes
685+
* ({@link net.md_5.bungee.api.ChatColor#COLOR_CHAR}
686+
*
687+
* @param currentLegacy the style at the end of the string the result of this method will be appended to
688+
* @return the string in the old format
689+
*/
690+
public String toLegacyText(ComponentStyle currentLegacy)
659691
{
660-
if ( extra != null )
692+
StringBuilder builder = new StringBuilder();
693+
toLegacyText( builder, currentLegacy );
694+
return builder.toString();
695+
}
696+
697+
/**
698+
* Converts the component to a string that uses the old formatting codes
699+
* ({@link net.md_5.bungee.api.ChatColor#COLOR_CHAR}
700+
*
701+
* @param builder the StringBuilder to append to
702+
* @param currentLegacy the style at the end of {@code builder}
703+
* @return the style at the end of the legacy string
704+
*/
705+
public ComponentStyle toLegacyText(StringBuilder builder, ComponentStyle currentLegacy)
706+
{
707+
currentLegacy = currentLegacy.clone();
708+
if ( !currentLegacy.hasColor() )
661709
{
662-
for ( BaseComponent e : extra )
663-
{
664-
e.toLegacyText( builder );
665-
}
710+
currentLegacy.setColor( ChatColor.RESET );
711+
}
712+
return toLegacyText( builder, currentLegacy.hasColor() ? currentLegacy.getColor() : ChatColor.RESET, currentLegacy );
713+
}
714+
715+
/**
716+
* Converts the component to a string that uses the old formatting codes
717+
* ({@link net.md_5.bungee.api.ChatColor#COLOR_CHAR}
718+
*
719+
* @param builder the StringBuilder to append to
720+
* @param baseColor the color to use if no color is set, but a format downgrade is needed
721+
* @param currentLegacy the style at the end of {@code builder}
722+
* @return the new current style at the end of the {@code builder}
723+
*/
724+
ComponentStyle toLegacyText(StringBuilder builder, ChatColor baseColor, ComponentStyle currentLegacy)
725+
{
726+
if ( extra == null )
727+
{
728+
return currentLegacy;
666729
}
730+
for ( BaseComponent e : extra )
731+
{
732+
currentLegacy = e.toLegacyText( builder, baseColor, currentLegacy );
733+
}
734+
return currentLegacy;
667735
}
668736

669-
void addFormat(StringBuilder builder)
737+
private static boolean colorEquals(ChatColor a, ChatColor b)
670738
{
671-
if ( style.hasColor() || parent != null )
739+
if ( a == b )
672740
{
673-
builder.append( getColor() );
741+
return true;
674742
}
675-
if ( isBold() )
743+
if ( a == null || b == null )
676744
{
677-
builder.append( ChatColor.BOLD );
745+
return false;
678746
}
679-
if ( isItalic() )
747+
if ( ChatColor.RESET.equals( a ) )
680748
{
681-
builder.append( ChatColor.ITALIC );
749+
return ChatColor.WHITE.equals( b ) || ChatColor.RESET.equals( b );
682750
}
683-
if ( isUnderlined() )
751+
if ( ChatColor.RESET.equals( b ) )
684752
{
685-
builder.append( ChatColor.UNDERLINE );
753+
return ChatColor.WHITE.equals( a ) || ChatColor.RESET.equals( a );
686754
}
687-
if ( isStrikethrough() )
755+
return a.equals( b );
756+
}
757+
758+
/**
759+
* @param builder the StringBuilder to append to
760+
* @param baseColor the color to use if no color is set, but a format downgrade is needed
761+
* @param currentLegacy the style at the end of {@code builder}
762+
* @return the new current style at the end of {@code builder}
763+
*/
764+
ComponentStyle addFormat(StringBuilder builder, ChatColor baseColor, ComponentStyle currentLegacy)
765+
{
766+
// Check if we can skip adding color code
767+
if ( colorEquals( getColor(), currentLegacy.getColor() ) && currentLegacy.isLegacyFormattingUpgrade( style ) )
768+
{
769+
if ( isBold() && !currentLegacy.isBold() )
770+
{
771+
builder.append( ChatColor.BOLD );
772+
}
773+
if ( isItalic() && !currentLegacy.isItalic() )
774+
{
775+
builder.append( ChatColor.ITALIC );
776+
}
777+
if ( isUnderlined() && !currentLegacy.isUnderlined() )
778+
{
779+
builder.append( ChatColor.UNDERLINE );
780+
}
781+
if ( isStrikethrough() && !currentLegacy.isStrikethrough() )
782+
{
783+
builder.append( ChatColor.STRIKETHROUGH );
784+
}
785+
if ( isObfuscated() && !currentLegacy.isObfuscated() )
786+
{
787+
builder.append( ChatColor.MAGIC );
788+
}
789+
} else
688790
{
689-
builder.append( ChatColor.STRIKETHROUGH );
791+
builder.append( getColor( baseColor ) == null ? baseColor : getColor( baseColor ) );
792+
if ( isBold() )
793+
{
794+
builder.append( ChatColor.BOLD );
795+
}
796+
if ( isItalic() )
797+
{
798+
builder.append( ChatColor.ITALIC );
799+
}
800+
if ( isUnderlined() )
801+
{
802+
builder.append( ChatColor.UNDERLINE );
803+
}
804+
if ( isStrikethrough() )
805+
{
806+
builder.append( ChatColor.STRIKETHROUGH );
807+
}
808+
if ( isObfuscated() )
809+
{
810+
builder.append( ChatColor.MAGIC );
811+
}
690812
}
691-
if ( isObfuscated() )
813+
currentLegacy = style;
814+
if ( currentLegacy.getColor() == null )
692815
{
693-
builder.append( ChatColor.MAGIC );
816+
currentLegacy = style.clone();
817+
currentLegacy.setColor( getColor( baseColor ) == null ? baseColor : getColor( baseColor ) );
694818
}
819+
return currentLegacy;
695820
}
696821
}

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

+9
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,15 @@ public boolean isEmpty()
200200
&& strikethrough == null && obfuscated == null;
201201
}
202202

203+
boolean isLegacyFormattingUpgrade(ComponentStyle newStyle)
204+
{
205+
return ( newStyle.isBold() || !isBold() )
206+
&& ( newStyle.isItalic() || !isItalic() )
207+
&& ( newStyle.isUnderlined() || !isUnderlined() )
208+
&& ( newStyle.isStrikethrough() || !isStrikethrough() )
209+
&& ( newStyle.isObfuscated() || !isObfuscated() );
210+
}
211+
203212
@Override
204213
public ComponentStyle clone()
205214
{

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import lombok.NoArgsConstructor;
66
import lombok.Setter;
77
import lombok.ToString;
8+
import net.md_5.bungee.api.ChatColor;
89

910
@Getter
1011
@Setter
@@ -57,10 +58,10 @@ protected void toPlainText(StringBuilder builder)
5758
}
5859

5960
@Override
60-
protected void toLegacyText(StringBuilder builder)
61+
ComponentStyle toLegacyText(StringBuilder builder, ChatColor baseColor, ComponentStyle currentLegacy)
6162
{
62-
addFormat( builder );
63+
currentLegacy = addFormat( builder, baseColor, currentLegacy );
6364
builder.append( getKeybind() );
64-
super.toLegacyText( builder );
65+
return super.toLegacyText( builder, baseColor, currentLegacy );
6566
}
6667
}

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import lombok.Getter;
66
import lombok.Setter;
77
import lombok.ToString;
8+
import net.md_5.bungee.api.ChatColor;
89

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

9495
@Override
95-
protected void toLegacyText(StringBuilder builder)
96+
ComponentStyle toLegacyText(StringBuilder builder, ChatColor baseColor, ComponentStyle currentLegacy)
9697
{
97-
addFormat( builder );
98+
currentLegacy = addFormat( builder, baseColor, currentLegacy );
9899
builder.append( this.value );
99-
super.toLegacyText( builder );
100+
return super.toLegacyText( builder, baseColor, currentLegacy );
100101
}
101102
}

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import lombok.Getter;
66
import lombok.Setter;
77
import lombok.ToString;
8+
import net.md_5.bungee.api.ChatColor;
89

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

7879
@Override
79-
protected void toLegacyText(StringBuilder builder)
80+
ComponentStyle toLegacyText(StringBuilder builder, ChatColor baseColor, ComponentStyle currentLegacy)
8081
{
81-
addFormat( builder );
82+
currentLegacy = addFormat( builder, baseColor, currentLegacy );
8283
builder.append( this.selector );
83-
super.toLegacyText( builder );
84+
return super.toLegacyText( builder, baseColor, currentLegacy );
8485
}
8586
}

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

+7-4
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ public TextComponent(BaseComponent... extras)
265265
{
266266
return;
267267
}
268-
setExtra( new ArrayList<BaseComponent>( Arrays.asList( extras ) ) );
268+
setExtra( new ArrayList<>( Arrays.asList( extras ) ) );
269269
}
270270

271271
/**
@@ -287,11 +287,14 @@ protected void toPlainText(StringBuilder builder)
287287
}
288288

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

297300
@Override

0 commit comments

Comments
 (0)