XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Text.Json;
using System.Text.RegularExpressions;

namespace XFEEDToolBox.Core.Localization;

/// <summary>Labels from the installed game Chinese resource. Native target names and identities stay unchanged.</summary>
public static partial class GameNavigationNames
{
    private static readonly IReadOnlyDictionary<string,string> Texts=Load();
    // USS templates are "$USS;"; the game supplies the corresponding USS_Type label.
    private static readonly Dictionary<string,string> SignalTypes=new(StringComparer.OrdinalIgnoreCase)
    {
        ["uss_degradedemissions"]="uss_type_salvage",["uss_encodedemissions"]="uss_type_valuablesalvage",
        ["uss_highgradeemissions"]="uss_type_veryvaluablesalvage",["uss_combataftermath"]="uss_type_aftermath",
        ["uss_distresscall"]="uss_type_distresssignal",["uss_ceremonialcomms"]="uss_type_ceremonial",
        ["uss_convoydispersalpattern"]="uss_type_convoy",["uss_nonhumansignalsource"]="uss_type_nonhuman"
    };
    private static readonly Dictionary<string,string> LiteralKeys=new(StringComparer.OrdinalIgnoreCase)
    {
        ["Nav Beacon"]="navbeacon_name",["System Colonisation Beacon"]="navbeacon_colonisation_name",
        ["Degraded Emissions"]="uss_type_salvage",["Encoded Emissions"]="uss_type_valuablesalvage",
        ["High Grade Emissions"]="uss_type_veryvaluablesalvage",["Combat Aftermath"]="uss_type_aftermath",
        ["Distress Call"]="uss_type_distresssignal",["Ceremonial Comms"]="uss_type_ceremonial",
        ["Convoy Dispersal Pattern"]="uss_type_convoy",["Non-Human Signal Source"]="uss_type_nonhuman",
        ["Unidentified Signal Source"]="uss",["Unexplored"]="ext_panel_location_not_scanned"
    };
    private static IReadOnlyDictionary<string,string> Load()
    {
        using var stream=typeof(GameNavigationNames).Assembly.GetManifestResourceStream("XFEEDToolBox.Core.Localization.game-navigation.json")!;
        using var document=JsonDocument.Parse(stream);
        return document.RootElement.GetProperty("tokens").EnumerateObject().ToDictionary(p=>p.Name,p=>p.Value.GetString()!,StringComparer.OrdinalIgnoreCase);
    }
    public static string Label(string key,string fallback)
        =>Texts.TryGetValue(key,out var text)?text:fallback;
    public static string Location(string nativeName,string fallback="地点")
    {
        if(string.IsNullOrEmpty(nativeName))return nativeName;
        if(LiteralKeys.TryGetValue(nativeName,out var literal))return Label(literal,nativeName);
        var belt=BeltCluster().Match(nativeName);
        if(belt.Success)return $"{belt.Groups[1].Value} {Label("ext_panel_filter_asteroidcluster","小行星带")} {belt.Groups[2].Value}";
        // Do not rewrite player, carrier, station, system or planetary proper names.
        if(!Token().IsMatch(nativeName))return nativeName;
        var key=nativeName[1..^1];
        for(var depth=0;depth<4;depth++)
        {
            if(SignalTypes.TryGetValue(key,out var type))key=type;
            else if(key.StartsWith("uss_",StringComparison.OrdinalIgnoreCase)&&Texts.ContainsKey("uss_type_"+key[4..]))key="uss_type_"+key[4..];
            if(!Texts.TryGetValue(key,out var text))return fallback;
            if(!Token().IsMatch(text))return text.Contains('$')?fallback:text;
            key=text[1..^1];
        }
        return fallback;
    }
    [GeneratedRegex(@"^\$[A-Za-z0-9_]+;$",RegexOptions.CultureInvariant)] private static partial Regex Token();
    [GeneratedRegex(@"^(.+) Belt Cluster (\d+)$",RegexOptions.IgnoreCase|RegexOptions.CultureInvariant)] private static partial Regex BeltCluster();
}