mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
Merge pull request #3068 from BruceChenQAQ/master
refactor: simplify color handling in ClassicConsoleBackend
This commit is contained in:
commit
5363ef7bc1
5 changed files with 42 additions and 30 deletions
|
|
@ -1 +1 @@
|
||||||
Subproject commit a9afc0df4ce79450b76acedffa1b549449cf69cb
|
Subproject commit ff6d2129e9f1e0fc6c7032741bdc42a2f0fa263e
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using static MinecraftClient.Settings.ConsoleConfigHealper.ConsoleConfig;
|
|
||||||
|
|
||||||
namespace MinecraftClient
|
namespace MinecraftClient
|
||||||
{
|
{
|
||||||
|
|
@ -28,29 +26,11 @@ namespace MinecraftClient
|
||||||
ConsoleInteractive.ConsoleWriter.WriteLine(text);
|
ConsoleInteractive.ConsoleWriter.WriteLine(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Regex HexColorRegex = new(@"§#([0-9a-fA-F]{6})", RegexOptions.Compiled);
|
|
||||||
|
|
||||||
public void WriteLineFormatted(string text)
|
public void WriteLineFormatted(string text)
|
||||||
{
|
{
|
||||||
bool hasHex = text.Contains("§#");
|
|
||||||
if (hasHex)
|
|
||||||
text = ResolveHexColors(text);
|
|
||||||
ConsoleInteractive.ConsoleWriter.WriteLineFormatted(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()
|
public void BeginReadThread()
|
||||||
{
|
{
|
||||||
ConsoleInteractive.ConsoleReader.MessageReceived += ForwardMessage;
|
ConsoleInteractive.ConsoleReader.MessageReceived += ForwardMessage;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using static MinecraftClient.Settings.ConsoleConfigHealper.ConsoleConfig;
|
using static MinecraftClient.Settings.ConsoleConfigHealper.ConsoleConfig;
|
||||||
|
|
||||||
namespace MinecraftClient
|
namespace MinecraftClient
|
||||||
|
|
@ -100,9 +100,9 @@ namespace MinecraftClient
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (foreground)
|
if (foreground)
|
||||||
return $"§{best_idx:X}";
|
return $"§{best_idx:x}";
|
||||||
else
|
else
|
||||||
return $"§§{best_idx:X}";
|
return $"§§{best_idx:x}";
|
||||||
}
|
}
|
||||||
|
|
||||||
case ConsoleColorModeType.vt100_4bit:
|
case ConsoleColorModeType.vt100_4bit:
|
||||||
|
|
|
||||||
|
|
@ -202,6 +202,11 @@ namespace MinecraftClient
|
||||||
{
|
{
|
||||||
ConsoleIO.Backend = new ClassicConsoleBackend();
|
ConsoleIO.Backend = new ClassicConsoleBackend();
|
||||||
ConsoleIO.Backend.Init();
|
ConsoleIO.Backend.Init();
|
||||||
|
|
||||||
|
// Config deserialization triggers OnSettingUpdate before the backend
|
||||||
|
// exists, so console-specific settings (UseVT100ColorCode, colors, etc.)
|
||||||
|
// are never applied. Re-apply them now that the backend is ready.
|
||||||
|
Config.Console.OnSettingUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ProcessStartupState(startupState))
|
if (!ProcessStartupState(startupState))
|
||||||
|
|
@ -240,6 +245,7 @@ namespace MinecraftClient
|
||||||
|
|
||||||
ConsoleIO.Backend = new ClassicConsoleBackend();
|
ConsoleIO.Backend = new ClassicConsoleBackend();
|
||||||
ConsoleIO.Backend.Init();
|
ConsoleIO.Backend.Init();
|
||||||
|
Config.Console.OnSettingUpdate();
|
||||||
|
|
||||||
ConsoleIO.WriteLineFormatted("§c" + Translations.mcc_tui_startup_failed);
|
ConsoleIO.WriteLineFormatted("§c" + Translations.mcc_tui_startup_failed);
|
||||||
ConsoleIO.WriteLine(exception.ToString());
|
ConsoleIO.WriteLine(exception.ToString());
|
||||||
|
|
|
||||||
|
|
@ -141,9 +141,17 @@ class TransUnit:
|
||||||
# XLIFF parsing
|
# XLIFF parsing
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def parse_xliff(path: Path, *, exclude_paths: list[str] | None = None) -> list[TransUnit]:
|
def parse_xliff(
|
||||||
|
path: Path, *,
|
||||||
|
exclude_paths: list[str] | None = None,
|
||||||
|
include_paths: list[str] | None = None,
|
||||||
|
) -> list[TransUnit]:
|
||||||
"""Parse an XLIFF 1.2 file, return trans-units with state=needs-translation.
|
"""Parse an XLIFF 1.2 file, return trans-units with state=needs-translation.
|
||||||
|
|
||||||
|
include_paths: if set, only keep <file> elements whose ``original``
|
||||||
|
starts with (or equals) one of these prefixes. Takes priority over
|
||||||
|
exclude_paths.
|
||||||
|
|
||||||
exclude_paths: skip <file> elements whose ``original`` starts with any
|
exclude_paths: skip <file> elements whose ``original`` starts with any
|
||||||
of these prefixes (e.g. ``["/docs/"]``).
|
of these prefixes (e.g. ``["/docs/"]``).
|
||||||
"""
|
"""
|
||||||
|
|
@ -153,7 +161,12 @@ def parse_xliff(path: Path, *, exclude_paths: list[str] | None = None) -> list[T
|
||||||
|
|
||||||
for file_elem in root.findall(f"{{{XLIFF_NS}}}file"):
|
for file_elem in root.findall(f"{{{XLIFF_NS}}}file"):
|
||||||
original = file_elem.get("original", "")
|
original = file_elem.get("original", "")
|
||||||
if exclude_paths and any(original.startswith(p) for p in exclude_paths):
|
if include_paths:
|
||||||
|
if not any(original == p or original.startswith(p.rstrip("/") + "/")
|
||||||
|
or original == p.rstrip("/")
|
||||||
|
for p in include_paths):
|
||||||
|
continue
|
||||||
|
elif exclude_paths and any(original.startswith(p) for p in exclude_paths):
|
||||||
continue
|
continue
|
||||||
finfo = FileInfo(
|
finfo = FileInfo(
|
||||||
file_id=file_elem.get("id", ""),
|
file_id=file_elem.get("id", ""),
|
||||||
|
|
@ -695,6 +708,7 @@ def process_language(
|
||||||
dry_run: bool,
|
dry_run: bool,
|
||||||
skip_upload: bool,
|
skip_upload: bool,
|
||||||
exclude_paths: list[str] | None = None,
|
exclude_paths: list[str] | None = None,
|
||||||
|
include_paths: list[str] | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Full pipeline for one language."""
|
"""Full pipeline for one language."""
|
||||||
lang_info = LANGUAGE_MAP.get(locale)
|
lang_info = LANGUAGE_MAP.get(locale)
|
||||||
|
|
@ -706,7 +720,8 @@ def process_language(
|
||||||
log.info("=" * 60)
|
log.info("=" * 60)
|
||||||
log.info("Processing %s -> %s", locale, target_lang)
|
log.info("Processing %s -> %s", locale, target_lang)
|
||||||
|
|
||||||
units = parse_xliff(xliff_path, exclude_paths=exclude_paths)
|
units = parse_xliff(xliff_path, exclude_paths=exclude_paths,
|
||||||
|
include_paths=include_paths)
|
||||||
log.info(" Found %d needs-translation entries", len(units))
|
log.info(" Found %d needs-translation entries", len(units))
|
||||||
|
|
||||||
if not units:
|
if not units:
|
||||||
|
|
@ -878,6 +893,10 @@ def build_parser() -> argparse.ArgumentParser:
|
||||||
help="Output directory (default: <bundle-dir>/translated/)")
|
help="Output directory (default: <bundle-dir>/translated/)")
|
||||||
p.add_argument("--include-docs", action="store_true",
|
p.add_argument("--include-docs", action="store_true",
|
||||||
help="Include /docs/ files in translation (skipped by default)")
|
help="Include /docs/ files in translation (skipped by default)")
|
||||||
|
p.add_argument("-f", "--files", type=str, default=None,
|
||||||
|
help="Comma-separated file paths to translate (e.g. "
|
||||||
|
"/docs/guide/README.md,/MinecraftClient/Resources/Translations/Translations.resx). "
|
||||||
|
"Overrides --include-docs")
|
||||||
p.add_argument("-v", "--verbose", action="store_true",
|
p.add_argument("-v", "--verbose", action="store_true",
|
||||||
help="Enable debug logging")
|
help="Enable debug logging")
|
||||||
return p
|
return p
|
||||||
|
|
@ -933,9 +952,15 @@ def main() -> None:
|
||||||
output_dir.mkdir(parents=True, exist_ok=True)
|
output_dir.mkdir(parents=True, exist_ok=True)
|
||||||
log.info("Output directory: %s", output_dir)
|
log.info("Output directory: %s", output_dir)
|
||||||
|
|
||||||
exclude_paths: list[str] | None = None if args.include_docs else ["/docs/"]
|
include_paths: list[str] | None = None
|
||||||
if exclude_paths:
|
if args.files:
|
||||||
log.info("Excluding XLIFF files under: %s (use --include-docs to include)",
|
include_paths = [f.strip() for f in args.files.split(",")]
|
||||||
|
log.info("Filtering to files: %s", ", ".join(include_paths))
|
||||||
|
|
||||||
|
exclude_paths: list[str] | None = None
|
||||||
|
if not include_paths and not args.include_docs:
|
||||||
|
exclude_paths = ["/docs/"]
|
||||||
|
log.info("Excluding XLIFF files under: %s (use --include-docs or --files to include)",
|
||||||
", ".join(exclude_paths))
|
", ".join(exclude_paths))
|
||||||
|
|
||||||
xliff_files = find_xliff_files(bundle_dir, locales)
|
xliff_files = find_xliff_files(bundle_dir, locales)
|
||||||
|
|
@ -959,6 +984,7 @@ def main() -> None:
|
||||||
dry_run=args.dry_run,
|
dry_run=args.dry_run,
|
||||||
skip_upload=args.skip_upload,
|
skip_upload=args.skip_upload,
|
||||||
exclude_paths=exclude_paths,
|
exclude_paths=exclude_paths,
|
||||||
|
include_paths=include_paths,
|
||||||
)
|
)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
log.warning("Interrupted by user. Partial results have been saved.")
|
log.warning("Interrupted by user. Partial results have been saved.")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue