round hex colors

This commit is contained in:
Chayapak 2023-11-03 17:41:20 +07:00
parent 79b59a6685
commit 2d0a1f7608
3 changed files with 103 additions and 29 deletions

View file

@ -80,10 +80,12 @@ public class DiscordPlugin {
bot.chat.addListener(new ChatPlugin.Listener() { bot.chat.addListener(new ChatPlugin.Listener() {
@Override @Override
public boolean systemMessageReceived (Component component, String string, String ansi) { public boolean systemMessageReceived (Component component, String string, String _ansi) {
if (string.length() > 2048) { if (string.length() > 2048) {
sendMessage(CodeBlockUtilities.escape(string), channelId); sendMessage(CodeBlockUtilities.escape(string), channelId);
} else { } else {
final String ansi = ComponentUtilities.stringifyAnsi(component, true);
sendMessage( sendMessage(
CodeBlockUtilities.escape( CodeBlockUtilities.escape(
ansi ansi

View file

@ -38,4 +38,67 @@ public class ColorUtilities {
Color color = Color.getHSBColor(hue / 360.0f, saturation / 100.0f, value / 100.0f); Color color = Color.getHSBColor(hue / 360.0f, saturation / 100.0f, value / 100.0f);
return color.getRGB() & 0xFFFFFF; return color.getRGB() & 0xFFFFFF;
} }
private static final ChatColor[] COLORS = {
new ChatColor("0", 0x000000),
new ChatColor("1", 0x0000aa),
new ChatColor("2", 0x00aa00),
new ChatColor("3", 0x00aaaa),
new ChatColor("4", 0xaa0000),
new ChatColor("5", 0xaa00aa),
new ChatColor("6", 0xffaa00),
new ChatColor("7", 0xaaaaaa),
new ChatColor("8", 0x555555),
new ChatColor("9", 0x5555ff),
new ChatColor("a", 0x55ff55),
new ChatColor("b", 0x55ffff),
new ChatColor("c", 0xff5555),
new ChatColor("d", 0xff55ff),
new ChatColor("e", 0xffff55),
new ChatColor("f", 0xffffff)
};
public static String getClosestChatColor(int rgb) {
int r = (rgb >> 16) & 0xFF;
int g = (rgb >> 8) & 0xFF;
int b = rgb & 0xFF;
ChatColor closest = null;
int smallestDiff = 0;
for (ChatColor color : COLORS) {
if (color.rgb == rgb) {
return color.colorName;
}
// Check by the greatest diff of the 3 values
int rAverage = (color.r + r) / 2;
int rDiff = color.r - r;
int gDiff = color.g - g;
int bDiff = color.b - b;
int diff = ((2 + (rAverage >> 8)) * rDiff * rDiff)
+ (4 * gDiff * gDiff)
+ ((2 + ((255 - rAverage) >> 8)) * bDiff * bDiff);
if (closest == null || diff < smallestDiff) {
closest = color;
smallestDiff = diff;
}
}
return closest.colorName;
}
public static final class ChatColor {
private final String colorName;
private final int rgb;
private final int r, g, b;
public ChatColor(String colorName, int rgb) {
this.colorName = colorName;
this.rgb = rgb;
r = (rgb >> 16) & 0xFF;
g = (rgb >> 8) & 0xFF;
b = rgb & 0xFF;
}
}
} }

View file

@ -59,7 +59,7 @@ public class ComponentUtilities {
ansiMap.put("r", "\u001b[0m"); ansiMap.put("r", "\u001b[0m");
} }
private record PartiallyStringified( public record PartiallyStringified(
String output, String output,
String lastColor String lastColor
) {} ) {}
@ -95,7 +95,7 @@ public class ComponentUtilities {
try { try {
final StringBuilder builder = new StringBuilder(); final StringBuilder builder = new StringBuilder();
final PartiallyStringified output = stringifyPartially(message, false, false, lastColor); final PartiallyStringified output = stringifyPartially(message, false, false, lastColor, false);
builder.append(output.output); builder.append(output.output);
@ -112,7 +112,7 @@ public class ComponentUtilities {
try { try {
final StringBuilder builder = new StringBuilder(); final StringBuilder builder = new StringBuilder();
final PartiallyStringified output = stringifyPartially(message, true, false, lastColor); final PartiallyStringified output = stringifyPartially(message, true, false, lastColor, false);
builder.append(output.output); builder.append(output.output);
@ -124,16 +124,17 @@ public class ComponentUtilities {
} }
} }
public static String stringifyAnsi (Component message) { return stringifyAnsi(message, null); } public static String stringifyAnsi (Component message) { return stringifyAnsi(message, null, false); }
private static String stringifyAnsi (Component message, String lastColor) { public static String stringifyAnsi (Component message, boolean noHex) { return stringifyAnsi(message, null, noHex); }
private static String stringifyAnsi (Component message, String lastColor, boolean noHex) {
try { try {
final StringBuilder builder = new StringBuilder(); final StringBuilder builder = new StringBuilder();
final PartiallyStringified output = stringifyPartially(message, false, true, lastColor); final PartiallyStringified output = stringifyPartially(message, false, true, lastColor, noHex);
builder.append(output.output); builder.append(output.output);
for (Component child : message.children()) builder.append(stringifyAnsi(child, output.lastColor)); for (Component child : message.children()) builder.append(stringifyAnsi(child, output.lastColor, noHex));
return builder.toString(); return builder.toString();
} catch (Exception e) { } catch (Exception e) {
@ -141,11 +142,11 @@ public class ComponentUtilities {
} }
} }
public static PartiallyStringified stringifyPartially (Component message, boolean motd, boolean ansi, String lastColor) { public static PartiallyStringified stringifyPartially (Component message, boolean motd, boolean ansi, String lastColor, boolean noHex) {
if (message instanceof TextComponent) return stringifyPartially((TextComponent) message, motd, ansi, lastColor); if (message instanceof TextComponent) return stringifyPartially((TextComponent) message, motd, ansi, lastColor, noHex);
else if (message instanceof TranslatableComponent) return stringifyPartially((TranslatableComponent) message, motd, ansi, lastColor); else if (message instanceof TranslatableComponent) return stringifyPartially((TranslatableComponent) message, motd, ansi, lastColor, noHex);
else if (message instanceof SelectorComponent) return stringifyPartially((SelectorComponent) message, motd, ansi, lastColor); else if (message instanceof SelectorComponent) return stringifyPartially((SelectorComponent) message, motd, ansi, lastColor, noHex);
else if (message instanceof KeybindComponent) return stringifyPartially((KeybindComponent) message, motd, ansi, lastColor); else if (message instanceof KeybindComponent) return stringifyPartially((KeybindComponent) message, motd, ansi, lastColor, noHex);
return new PartiallyStringified("", null); return new PartiallyStringified("", null);
} }
@ -183,7 +184,7 @@ public class ComponentUtilities {
return style.toString(); return style.toString();
} }
public static String getColor (TextColor color, boolean motd, boolean ansi) { public static String getColor (TextColor color, boolean motd, boolean ansi, boolean noHex) {
if (color == null) return null; if (color == null) return null;
// map totallynotskidded too from https://github.com/PrismarineJS/prismarine-chat/blob/master/index.js#L299 // map totallynotskidded too from https://github.com/PrismarineJS/prismarine-chat/blob/master/index.js#L299
@ -217,6 +218,13 @@ public class ComponentUtilities {
} else if (ansi) { } else if (ansi) {
String ansiCode = ansiMap.get(code); String ansiCode = ansiMap.get(code);
if (ansiCode == null) { if (ansiCode == null) {
if (noHex) {
final int rgb = Integer.parseInt(code.substring(1), 16);
final String chatColor = ColorUtilities.getClosestChatColor(rgb);
ansiCode = ansiMap.get(chatColor);
} else {
ansiCode = "\u001b[38;2;" + ansiCode = "\u001b[38;2;" +
color.red() + color.red() +
";" + ";" +
@ -225,14 +233,15 @@ public class ComponentUtilities {
color.blue() + color.blue() +
"m"; "m";
} }
}
return ansiCode; return ansiCode;
} else return null; } else return null;
} }
public static PartiallyStringified stringifyPartially (TextComponent message, boolean motd, boolean ansi, String lastColor) { public static PartiallyStringified stringifyPartially (TextComponent message, boolean motd, boolean ansi, String lastColor, boolean noHex) {
if ((motd || ansi) && /* don't color big messages -> */ message.content().length() < 25_000) { if ((motd || ansi) && /* don't color big messages -> */ message.content().length() < 25_000) {
final String color = getColor(message.color(), motd, ansi); final String color = getColor(message.color(), motd, ansi, noHex);
final String style = getStyle(message.style(), motd); final String style = getStyle(message.style(), motd);
String replacedContent = message.content(); String replacedContent = message.content();
@ -254,7 +263,7 @@ public class ComponentUtilities {
return new PartiallyStringified(message.content(), null); return new PartiallyStringified(message.content(), null);
} }
public static PartiallyStringified stringifyPartially (TranslatableComponent message, boolean motd, boolean ansi, String lastColor) { public static PartiallyStringified stringifyPartially (TranslatableComponent message, boolean motd, boolean ansi, String lastColor, boolean noHex) {
String format = getOrReturnKey(message.key()); String format = getOrReturnKey(message.key());
// totallynotskidded from HBot (and changed a bit) // totallynotskidded from HBot (and changed a bit)
@ -262,7 +271,7 @@ public class ComponentUtilities {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
final String style = getStyle(message.style(), motd); final String style = getStyle(message.style(), motd);
final String _color = getColor(message.color(), motd, ansi); final String _color = getColor(message.color(), motd, ansi, noHex);
String color; String color;
if (_color == null) color = ""; if (_color == null) color = "";
else color = _color; else color = _color;
@ -297,18 +306,18 @@ public class ComponentUtilities {
return new PartiallyStringified((lastColor != null ? lastColor : "") + color + (style != null && ansi ? style : "") + sb + (ansi ? ansiMap.get("r") : ""), _color); return new PartiallyStringified((lastColor != null ? lastColor : "") + color + (style != null && ansi ? style : "") + sb + (ansi ? ansiMap.get("r") : ""), _color);
} }
public static PartiallyStringified stringifyPartially (SelectorComponent message, boolean motd, boolean ansi, String lastColor) { public static PartiallyStringified stringifyPartially (SelectorComponent message, boolean motd, boolean ansi, String lastColor, boolean noHex) {
final String style = getStyle(message.style(), motd); final String style = getStyle(message.style(), motd);
final String _color = getColor(message.color(), motd, ansi); final String _color = getColor(message.color(), motd, ansi, noHex);
String color; String color;
if (_color == null) color = ""; if (_color == null) color = "";
else color = _color; else color = _color;
return new PartiallyStringified((lastColor != null ? lastColor : "") + color + (style != null && ansi ? style : "") + message.pattern(), _color); // * Client-side selector components are equivalent to text ones, and do NOT list entities. return new PartiallyStringified((lastColor != null ? lastColor : "") + color + (style != null && ansi ? style : "") + message.pattern(), _color); // * Client-side selector components are equivalent to text ones, and do NOT list entities.
} }
public static PartiallyStringified stringifyPartially (KeybindComponent message, boolean motd, boolean ansi, String lastColor) { public static PartiallyStringified stringifyPartially (KeybindComponent message, boolean motd, boolean ansi, String lastColor, boolean noHex) {
String keybind = message.keybind(); String keybind = message.keybind();
Component component = keybinds.containsKey(keybind) ? Component.translatable(keybind) : Component.text(keybind); // TODO: Fix some keys like `key.keyboard.a` Component component = keybinds.containsKey(keybind) ? Component.translatable(keybind) : Component.text(keybind); // TODO: Fix some keys like `key.keyboard.a`
return stringifyPartially(component, motd, ansi, lastColor); return stringifyPartially(component, motd, ansi, lastColor, noHex);
} }
} }