-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add api to get the closest default ChatColor for a specific color (faster) #3888
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
base: master
Are you sure you want to change the base?
Conversation
Introducing the ChatColor#closestDefaultColor(java.awt.Color) method: It computes the closest legacy default ChatColor (§1, §a, §e...) by using squared Euclidean distance calculation. It can be very useful if one just wants to translate the new hex color back for old clients. Co-authored-by: Outfluencer <[email protected]>
| public static ChatColor closestDefaultColor(Color target) | ||
| { | ||
| Preconditions.checkNotNull( target, "target cannot be null" ); | ||
| int targetRed = target.getRed(); | ||
| int targetGreen = target.getGreen(); | ||
| int targetBlue = target.getBlue(); | ||
|
|
||
| ChatColor result = null; | ||
| int smallestDistance = Integer.MAX_VALUE; | ||
|
|
||
| for ( int i = 0, length = COLORS_HEX.length; i < length; i++ ) | ||
| { | ||
| int colorValue = COLORS_HEX[ i ]; | ||
| int redDiff = ( colorValue >> 16 & 0xFF ) - targetRed; | ||
| int greenDiff = ( colorValue >> 8 & 0xFF ) - targetGreen; | ||
| int blueDiff = ( colorValue & 0xFF ) - targetBlue; | ||
| int distance = redDiff * redDiff + greenDiff * greenDiff + blueDiff * blueDiff; | ||
|
|
||
| if ( distance < smallestDistance ) | ||
| { | ||
| smallestDistance = distance; | ||
| result = COLORS[ i ]; | ||
| } | ||
| if ( distance < MAX_CLOSEST_COLOR_DIST_SQ ) | ||
| { | ||
| break; | ||
| } | ||
| } | ||
| return Preconditions.checkNotNull( result, "Could not find a match for " + target ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its late, I think MAX_CLOSEST_COLOR_DIST_SQ + 1 can be the initial value of smallestDistance (or not +1 and we change comparision to <=), but I'm not 100% sure.
|
If needed, I can also do a microbenhcmark. These optimizations are based on educated guesses (like to not iterate over formattings in the first place). |
|
| smallestDistance = distance; | ||
| result = COLORS[ i ]; | ||
| } | ||
| if ( distance < MAX_CLOSEST_COLOR_DIST_SQ ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this correct? Can you please explain?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, would also appreciate an explaination for that "magic" value
|
It was too late in the night, the algorithm is wrong. The constant is too high (see how I calculated the constant in the test file). |
This is meant to support legacy minecraft versions, those will never get a new color. Thanks LLM AI for not knowing the context.
It is exactly how awt color saves / their getters work. For cache locality I got rid of the Color object.
Some small updates to the file are not noteworthy enough to mention them. I suggest evaluating AI LLM responses yourself before posting them.
No, the index is needed.
Unfortunaly the algorithm I wrote in the test file calculated this constant wrong, I will revise it and add a comment to this constant.
I think the code is still perfectly readable, thanks LLM AI. The time of initial computations is irrelevant. |
…erence in speed. Added testClosestDefaultColor to ensure correctness of abort constant.
|
I have bruteforced the exact value now and it seems like for the specific legacy colors its 3697 so we can fast break even more. But i am not sure if we should use any of those precalculated values at all. Here how i tested it btw if you increment the magic value by one it will fail |
I investigated, this happens because there are some specific rgb values which have the same distance to 2 default colors. If, in my method, I change |
…al-distance colors, only check for abort distance if we found a new smallest distance.
|
why copy paste? i have seen the same commit in bungeecord? |
|
|
It does not. legacy colors do not change. |
|
Legacy mc versions are not changed ever anymore by minecraft, so the amount of named colors this method needs will not change, especially named colors will never get less. |
|
Bedrcok is not the target of Bungeecord. |
|
never. and fix your formatting, dont put your new text into quote. |

Introducing the ChatColor#closestDefaultColor(java.awt.Color) method:
It computes the closest legacy default ChatColor (§1, §a, §e...) by using squared Euclidean distance calculation. It can be very useful if one just wants to translate the new hex color back for old clients.
Based on idea from Outfluencer in #3887