@@ -98,22 +98,72 @@ private ChatColor getClosestColor(Color color) {
9898 * Retrieves a {@link ChatColor} for the given {@link Color}, taking into account legacy mode.
9999 *
100100 * @param color the AWT color to convert
101- * @param isLegacy if {@code true}, legacy colors are used (closest match); otherwise, modern RGB support is used
101+ * @param legacy if {@code true}, legacy colors are used (closest match); otherwise, modern RGB support is used
102102 * @return the corresponding {@link ChatColor}
103103 */
104- private ChatColor getBukkit (Color color , boolean isLegacy ) {
105- return isLegacy ? getClosestColor (color ) : ChatColor .of (color );
104+ private ChatColor getBukkit (Color color , boolean legacy ) {
105+ return legacy ? getClosestColor (color ) : ChatColor .of (color );
106106 }
107107
108108 /**
109109 * Converts a hexadecimal color string into a {@link ChatColor}.
110110 *
111111 * @param string the hexadecimal color code (without the leading '#' character)
112- * @param isLegacy if {@code true}, legacy color mode is used
112+ * @param legacy if {@code true}, legacy color mode is used
113113 * @return the resulting {@link ChatColor}
114114 */
115- public ChatColor fromString (String string , boolean isLegacy ) {
116- return getBukkit (new Color (Integer .parseInt (string , 16 )), isLegacy );
115+ public ChatColor fromString (String string , boolean legacy ) {
116+ return getBukkit (new Color (Integer .parseInt (string , 16 )), legacy );
117+ }
118+
119+ /**
120+ * Parses a color string into a {@link ChatColor}, using optional player context
121+ * to decide if legacy (pre-1.16) color mode should apply.
122+ * <p>
123+ * The input may include legacy color code markers ('&' or '§').
124+ * </p>
125+ * - If the cleaned string is a single hex-digit or formatting code (0–9, A–F, K–O, R),
126+ * returns {@link ChatColor#getByChar(char)}.
127+ * <p>
128+ * - If it’s a six-digit hex (A–F, 0–9), delegates to
129+ * {@link #fromString(String, boolean)} with legacy determined by server and client versions.
130+ * </p>
131+ * - Otherwise, defaults to {@link ChatColor#WHITE}.
132+ *
133+ * @param player the {@link Player} whose client version may force legacy mode (may be {@code null})
134+ * @param string the color code to parse (may include '&' or '§' markers)
135+ * @return the corresponding {@link ChatColor}, or {@link ChatColor#WHITE} if unrecognized
136+ */
137+ public ChatColor fromString (Player player , String string ) {
138+ if (string .matches ("^[&§]x" )) string = string .substring (2 );
139+ string = string .replaceAll ("[&§]" , "" );
140+
141+ if (string .matches ("^(?i)[a-fk-or0-9]$" ))
142+ return ChatColor .getByChar (string .toCharArray ()[0 ]);
143+
144+ if (string .matches ("^(?i)[a-f0-9]{6}$" )) {
145+ boolean legacy = ClientVersion .SERVER_VERSION < 16.0 ;
146+ if (player != null )
147+ legacy = legacy || ClientVersion .isLegacy (player );
148+ return fromString (string , legacy );
149+ }
150+
151+ return ChatColor .WHITE ;
152+ }
153+
154+ /**
155+ * Parses a color string into a {@link ChatColor} based solely on server version,
156+ * without any player-specific legacy checks.
157+ * <p>
158+ * This is equivalent to calling {@link #fromString(Player, String)} with a {@code null}
159+ * player, so legacy mode is determined only by {@link ClientVersion#SERVER_VERSION}.
160+ * </p>
161+ *
162+ * @param string the color code to parse (may include '&' or '§' markers)
163+ * @return the corresponding {@link ChatColor}, or {@link ChatColor#WHITE} if unrecognized
164+ */
165+ public ChatColor fromString (String string ) {
166+ return fromString (null , string );
117167 }
118168
119169 /**
@@ -122,10 +172,10 @@ public ChatColor fromString(String string, boolean isLegacy) {
122172 * @param start the starting color of the gradient
123173 * @param end the ending color of the gradient
124174 * @param step the number of steps (colors) in the gradient
125- * @param isLegacy if {@code true}, legacy color mode is used
175+ * @param legacy if {@code true}, legacy color mode is used
126176 * @return an array of {@link ChatColor} forming the gradient
127177 */
128- private ChatColor [] createGradient (Color start , Color end , int step , boolean isLegacy ) {
178+ private ChatColor [] createGradient (Color start , Color end , int step , boolean legacy ) {
129179 ChatColor [] colors = new ChatColor [step ];
130180 int stepR = Math .abs (start .getRed () - end .getRed ()) / (step - 1 ),
131181 stepG = Math .abs (start .getGreen () - end .getGreen ()) / (step - 1 ),
@@ -141,7 +191,7 @@ private ChatColor[] createGradient(Color start, Color end, int step, boolean isL
141191 start .getGreen () + ((stepG * i ) * direction [1 ]),
142192 start .getBlue () + ((stepB * i ) * direction [2 ])
143193 );
144- colors [i ] = getBukkit (color , isLegacy );
194+ colors [i ] = getBukkit (color , legacy );
145195 }
146196 return colors ;
147197 }
@@ -151,15 +201,15 @@ private ChatColor[] createGradient(Color start, Color end, int step, boolean isL
151201 *
152202 * @param step the number of colors in the rainbow
153203 * @param sat the saturation level (0.0 to 1.0)
154- * @param isLegacy if {@code true}, legacy color mode is used
204+ * @param legacy if {@code true}, legacy color mode is used
155205 * @return an array of {@link ChatColor} forming a rainbow
156206 */
157- private ChatColor [] createRainbow (int step , float sat , boolean isLegacy ) {
207+ private ChatColor [] createRainbow (int step , float sat , boolean legacy ) {
158208 ChatColor [] colors = new ChatColor [step ];
159209 double colorStep = (1.00 / step );
160210 for (int i = 0 ; i < step ; i ++) {
161211 Color color = Color .getHSBColor ((float ) (colorStep * i ), sat , sat );
162- colors [i ] = getBukkit (color , isLegacy );
212+ colors [i ] = getBukkit (color , legacy );
163213 }
164214 return colors ;
165215 }
@@ -169,11 +219,11 @@ private ChatColor[] createRainbow(int step, float sat, boolean isLegacy) {
169219 *
170220 * @param color the color to apply
171221 * @param string the string to colorize
172- * @param isLegacy if {@code true}, legacy color mode is used
222+ * @param legacy if {@code true}, legacy color mode is used
173223 * @return the colorized string
174224 */
175- public String applyColor (Color color , String string , boolean isLegacy ) {
176- return getBukkit (color , isLegacy ) + string ;
225+ public String applyColor (Color color , String string , boolean legacy ) {
226+ return getBukkit (color , legacy ) + string ;
177227 }
178228
179229 /**
@@ -212,25 +262,25 @@ private String apply(String source, ChatColor[] colors) {
212262 * @param string the string to apply the gradient to
213263 * @param start the starting color of the gradient
214264 * @param end the ending color of the gradient
215- * @param isLegacy if {@code true}, legacy color mode is used
265+ * @param legacy if {@code true}, legacy color mode is used
216266 * @return the string with a gradient effect applied
217267 */
218- public String applyGradient (String string , Color start , Color end , boolean isLegacy ) {
268+ public String applyGradient (String string , Color start , Color end , boolean legacy ) {
219269 int i = stripSpecial (string ).length ();
220- return i <= 1 ? string : apply (string , createGradient (start , end , i , isLegacy ));
270+ return i <= 1 ? string : apply (string , createGradient (start , end , i , legacy ));
221271 }
222272
223273 /**
224274 * Applies a rainbow color effect to the given string.
225275 *
226276 * @param string the string to apply the rainbow effect to
227277 * @param saturation the saturation level for the rainbow (0.0 to 1.0)
228- * @param isLegacy if {@code true}, legacy color mode is used
278+ * @param legacy if {@code true}, legacy color mode is used
229279 * @return the string with a rainbow effect applied
230280 */
231- public String applyRainbow (String string , float saturation , boolean isLegacy ) {
281+ public String applyRainbow (String string , float saturation , boolean legacy ) {
232282 int i = stripSpecial (string ).length ();
233- return i == 0 ? string : apply (string , createRainbow (i , saturation , isLegacy ));
283+ return i == 0 ? string : apply (string , createRainbow (i , saturation , legacy ));
234284 }
235285
236286 /**
@@ -245,11 +295,11 @@ public String applyRainbow(String string, float saturation, boolean isLegacy) {
245295 * @return the colorized string
246296 */
247297 public String colorize (Player player , String string ) {
248- boolean isLegacy = ClientVersion .SERVER_VERSION < 16.0 ;
298+ boolean legacy = ClientVersion .SERVER_VERSION < 16.0 ;
249299 if (player != null )
250- isLegacy = isLegacy || ClientVersion .isLegacy (player );
300+ legacy = legacy || ClientVersion .isLegacy (player );
251301 for (ColorPattern p : ColorPattern .COLOR_PATTERNS )
252- string = p .apply (string , isLegacy );
302+ string = p .apply (string , legacy );
253303 return ChatColor .translateAlternateColorCodes ('&' , string );
254304 }
255305
0 commit comments