11package ru .overwrite .rtp .color .impl ;
22
3- import org .jetbrains .annotations .Nullable ;
43import ru .overwrite .rtp .color .Colorizer ;
54
65public class LegacyColorizer implements Colorizer {
76
87 private static final char COLOR_CHAR = '§' ;
98 private static final char ALT_COLOR_CHAR = '&' ;
109
10+ private static final boolean [] HEX = new boolean [128 ];
11+ private static final boolean [] COLOR = new boolean [128 ];
12+
13+ static {
14+ for (int c = '0' ; c <= '9' ; c ++) {
15+ HEX [c ] = true ;
16+ COLOR [c ] = true ;
17+ }
18+ for (int c = 'a' ; c <= 'f' ; c ++) {
19+ HEX [c ] = true ;
20+ COLOR [c ] = true ;
21+ }
22+ for (int c = 'A' ; c <= 'F' ; c ++) {
23+ HEX [c ] = true ;
24+ COLOR [c ] = true ;
25+ }
26+ for (int c : new int []{'r' , 'R' , 'k' , 'K' , 'l' , 'L' , 'm' , 'M' , 'n' , 'N' , 'o' , 'O' }) {
27+ COLOR [c ] = true ;
28+ }
29+ }
30+
1131 @ Override
12- public String colorize (@ Nullable String message ) {
13- if (message == null || message .isEmpty ()) {
32+ public String colorize (String message ) {
33+ if (message == null ) {
34+ return null ;
35+ }
36+ final char [] s = message .toCharArray ();
37+ final int len = s .length ;
38+ if (len == 0 ) {
39+ return message ;
40+ }
41+
42+ final int firstAmp = message .indexOf (ALT_COLOR_CHAR );
43+ if (firstAmp < 0 ) {
1444 return message ;
1545 }
1646
17- final char [] chars = message .toCharArray ();
18- final int length = chars .length ;
19-
20- final StringBuilder builder = new StringBuilder (length + 32 );
21- char [] hex = null ;
22-
23- int start = 0 , end ;
24- loop :
25- for (int i = 0 ; i < length - 1 ; ) {
26- final char ch = chars [i ];
27- if (ch == ALT_COLOR_CHAR ) {
28- final char nextChar = chars [++i ];
29- if (nextChar == '#' ) {
30- if (i + 6 >= length ) break ;
31- if (hex == null ) {
32- hex = new char [14 ];
33- hex [0 ] = COLOR_CHAR ;
34- hex [1 ] = 'x' ;
35- }
36- end = i - 1 ;
37- for (int j = 0 , hexI = 1 ; j < 6 ; j ++) {
38- final char hexChar = chars [++i ];
39- if (!isHexCharacter (hexChar )) {
40- continue loop ;
41- }
42- hex [++hexI ] = COLOR_CHAR ;
43- hex [++hexI ] = hexChar ;
44- }
45- builder .append (chars , start , end - start ).append (hex );
46- start = i + 1 ;
47- } else {
48- if (isColorCharacter (nextChar )) {
49- chars [i - 1 ] = COLOR_CHAR ;
50- chars [i ] |= 0x20 ;
51- }
47+ final char [] d = new char [len * 3 ];
48+ int w = 0 ;
49+ int i = 0 ;
50+
51+ if (firstAmp > 8 ) {
52+ System .arraycopy (s , 0 , d , 0 , firstAmp );
53+ w = firstAmp ;
54+ i = firstAmp ;
55+ } else {
56+ while (i < firstAmp ) d [w ++] = s [i ++];
57+ }
58+
59+ while (i < len ) {
60+ final char c = s [i ];
61+
62+ if (c != ALT_COLOR_CHAR ) {
63+ d [w ++] = c ;
64+ i ++;
65+ continue ;
66+ }
67+
68+ final int remaining = len - i ;
69+
70+ if (remaining >= 8 && s [i + 1 ] == '#' ) {
71+ final char h0 = s [i + 2 ], h1 = s [i + 3 ], h2 = s [i + 4 ], h3 = s [i + 5 ], h4 = s [i + 6 ], h5 = s [i + 7 ];
72+ if (h0 < 128 && HEX [h0 ] && h1 < 128 && HEX [h1 ] && h2 < 128 && HEX [h2 ] && h3 < 128 && HEX [h3 ] && h4 < 128 && HEX [h4 ] && h5 < 128 && HEX [h5 ]) {
73+ d [w ] = COLOR_CHAR ;
74+ d [w + 1 ] = 'x' ;
75+ d [w + 2 ] = COLOR_CHAR ;
76+ d [w + 3 ] = h0 ;
77+ d [w + 4 ] = COLOR_CHAR ;
78+ d [w + 5 ] = h1 ;
79+ d [w + 6 ] = COLOR_CHAR ;
80+ d [w + 7 ] = h2 ;
81+ d [w + 8 ] = COLOR_CHAR ;
82+ d [w + 9 ] = h3 ;
83+ d [w + 10 ] = COLOR_CHAR ;
84+ d [w + 11 ] = h4 ;
85+ d [w + 12 ] = COLOR_CHAR ;
86+ d [w + 13 ] = h5 ;
87+ w += 14 ;
88+ i += 8 ;
89+ continue ;
5290 }
5391 }
54- ++i ;
55- }
5692
57- builder .append (chars , start , length - start );
58- return builder .toString ();
59- }
93+ if (remaining >= 2 ) {
94+ final char next = s [i + 1 ];
95+ if (next < 128 && COLOR [next ]) {
96+ d [w ] = COLOR_CHAR ;
97+ d [w + 1 ] = next ;
98+ w += 2 ;
99+ i += 2 ;
100+ continue ;
101+ }
102+ }
60103
61- public static boolean isHexCharacter (final char ch ) {
62- return switch (ch ) {
63- case '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' ,
64- 'a' , 'A' , 'b' , 'B' , 'c' , 'C' , 'd' , 'D' , 'e' , 'E' , 'f' , 'F' -> true ;
65- default -> false ;
66- };
67- }
104+ d [w ++] = ALT_COLOR_CHAR ;
105+ i ++;
106+ }
68107
69- private boolean isColorCharacter (char c ) {
70- return switch (c ) {
71- case '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' ,
72- 'a' , 'b' , 'c' , 'd' , 'e' , 'f' ,
73- 'A' , 'B' , 'C' , 'D' , 'E' , 'F' ,
74- 'r' , 'R' , 'k' , 'K' , 'l' , 'L' , 'm' , 'M' , 'n' , 'N' , 'o' , 'O' , 'x' , 'X' -> true ;
75- default -> false ;
76- };
108+ return new String (d , 0 , w );
77109 }
78110}
0 commit comments