fix: Support hex RGB colors (#RRGGBB) in chat messages (fixes #2054)

Minecraft 1.16+ servers can send custom hex colors in JSON text
components ("color": "#RRGGBB"). MCC's ChatParser.Color2tag() only
recognized the 16 named colors, silently dropping hex values and
leaving gradient/custom-colored chat as uncolored plain text.

- ChatParser: recognize hex color values and emit internal §#rrggbb
  encoding; extend ColorCodeRegex to match the new format
- ClassicConsoleBackend: resolve §#rrggbb to ANSI escape codes via
  ColorHelper before passing to ConsoleInteractive (adapts to the
  configured ConsoleColorMode: 24-bit, 8-bit, 4-bit, or disable)
- McColorParser (TUI): parse §#rrggbb into exact SolidColorBrush
  for full RGB fidelity in Avalonia
- ChatBot.GetVerbatim(): skip the full 8-char §#rrggbb sequence
  instead of only 2 chars, preventing hex digits from leaking into
  stripped text

Made-with: Cursor
This commit is contained in:
BruceChen 2026-04-06 01:18:05 +08:00
parent 914c56fc6e
commit 7fd70ccf38
4 changed files with 80 additions and 6 deletions

View file

@ -1,4 +1,6 @@
using System;
using System.Text.RegularExpressions;
using static MinecraftClient.Settings.ConsoleConfigHealper.ConsoleConfig;
namespace MinecraftClient
{
@ -26,11 +28,29 @@ namespace MinecraftClient
ConsoleInteractive.ConsoleWriter.WriteLine(text);
}
private static readonly Regex HexColorRegex = new(@"§#([0-9a-fA-F]{6})", RegexOptions.Compiled);
public void WriteLineFormatted(string text)
{
bool hasHex = text.Contains("§#");
if (hasHex)
text = ResolveHexColors(text);
ConsoleInteractive.ConsoleWriter.WriteLineFormatted(text);
}
private static string ResolveHexColors(string text)
{
var mode = Settings.Config.Console.General.ConsoleColorMode;
return HexColorRegex.Replace(text, match =>
{
ReadOnlySpan<char> hex = match.Groups[1].ValueSpan;
byte r = Convert.ToByte(hex[..2].ToString(), 16);
byte g = Convert.ToByte(hex[2..4].ToString(), 16);
byte b = Convert.ToByte(hex[4..6].ToString(), 16);
return ColorHelper.GetColorEscapeCode(r, g, b, foreground: true, mode);
});
}
public void BeginReadThread()
{
ConsoleInteractive.ConsoleReader.MessageReceived += ForwardMessage;