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

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Text.Json;
using XFEEDToolBox.Core.Models;
namespace XFEEDToolBox.Core.Data;

public sealed class CommanderProfileProjector
{
    private readonly Dictionary<long,VisitedSystem> visited=[];
    private readonly HashSet<string> bodies=[];
    private readonly HashSet<string> discoveries=[];
    private readonly HashSet<string> jumps=[];
    private readonly Dictionary<string,CommanderMetric> ranks=[];
    public CommanderProfile State{get;private set;}=new();
    public void Reset(){visited.Clear();bodies.Clear();discoveries.Clear();jumps.Clear();ranks.Clear();State=new();}
    public void Apply(JsonElement e)
    {
        var name=e.Text("event");var at=e.Time();if(at is null)return;
        if(name is "Location" or "FSDJump" or "CarrierJump" && e.Long("SystemAddress") is >0 and var address && e.Position() is {} position)
        {
            var old=visited.GetValueOrDefault(address);var isJump=name=="FSDJump"&&jumps.Add($"{at:O}:{address}");
            visited[address]=old is null?new(address,e.Text("StarSystem"),position,"",at.Value,at.Value,1):old with{LastVisit=at.Value>old.LastVisit?at.Value:old.LastVisit,Visits=old.Visits+(isJump?1:0)};
            State=State with{VisitedSystems=visited.Values.OrderByDescending(v=>v.LastVisit).ToArray(),RecordedJumpDistance=State.RecordedJumpDistance+(isJump?e.Number("JumpDist")??0:0)};
        }
        if(name=="Scan")
        {
            var body=$"{e.Long("SystemAddress")}:{e.Text("BodyName")}";
            if(bodies.Count<200000&&e.Text("BodyName").Length>0)bodies.Add(body);
            if(e.Get("WasDiscovered").ValueKind==JsonValueKind.False)discoveries.Add(body);
            if(e.Long("SystemAddress") is >0 and var id&&e.Text("StarType").Length>0&&visited.TryGetValue(id,out var star)&&star.StarClass.Length==0)
            {visited[id]=star with{StarClass=e.Text("StarType")};State=State with{VisitedSystems=visited.Values.OrderByDescending(v=>v.LastVisit).ToArray()};}
            State=State with{ScannedBodies=bodies.Count,FirstDiscoveredBodies=discoveries.Count};
        }
        if(name=="Statistics"&&(State.StatisticsAt is null||at>=State.StatisticsAt))
        {
            var metrics=new List<CommanderMetric>();
            foreach(var (group,key,label,unit) in new[]{("Bank_Account","Current_Wealth","总资产"," Cr"),("Bank_Account","Owned_Ship_Count","拥有飞船",""),("Bank_Account","Insurance_Claims","保险理赔次数",""),("Exploration","Systems_Visited","访问星系",""),("Exploration","Total_Hyperspace_Distance","累计跃迁距离"," ly"),("Exploration","Total_Hyperspace_Jumps","累计跃迁次数",""),("Exploration","Greatest_Distance_From_Start","最远探索距离"," ly"),("Exploration","Planets_Scanned_To_Level_2","二级扫描天体",""),("Exploration","Planets_Scanned_To_Level_3","三级扫描天体",""),("Exploration","Exploration_Profits","探索收益"," Cr"),("Trading","Trading_Profit","贸易收益"," Cr"),("Combat","Bounty_Hunting_Profit","赏金收益"," Cr"),("Exobiology","Organic_Data_Profits","外星生物学收益"," Cr")})
                if(e.Get(group).Number(key) is {} value)metrics.Add(new(group+"."+key,label,key.Replace('_',' '),value.ToString(unit.Contains("ly")?"N1":"N0")+unit));
            State=State with{Statistics=metrics,StatisticsAt=at};
        }
        if(name is "Rank" or "Progress" or "Promotion")
        {
            foreach(var (key,label) in new[]{("Combat","战斗"),("Trade","贸易"),("Explore","探索"),("Soldier","佣兵"),("Exobiologist","外星生物学"),("Empire","帝国海军"),("Federation","联邦海军"),("CQC","竞技场")})
                if(e.Number(key) is {} value)
                {
                    var id=key+(name=="Progress"?".progress":".rank");
                    ranks[id]=new(id,label+(name=="Progress"?"进度":"等级"),key+(name=="Progress"?" progress":" rank"),name=="Progress"?$"{value:N0}%":$"{value:N0}");
                }
            State=State with{Ranks=ranks.Values.ToArray()};
        }
    }
}