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

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using XFEEDToolBox.Core.Galaxy;
using XFEEDToolBox.Core.Navigation;

namespace XFEEDToolBox.ViewModels;

public partial class ToolboxViewModel
{
    [ObservableProperty] public partial IReadOnlyList<GalaxyThargoidCountDisplay> GalaxyThargoidCounts { get;set; }=[];
    [ObservableProperty] public partial IReadOnlyList<GalaxyThargoidTarget> GalaxyThargoidSignals { get;set; }=[];
    [ObservableProperty] public partial IReadOnlyList<GalaxyThargoidTarget> GalaxyThargoidRecommendations { get;set; }=[];
    [ObservableProperty] public partial string GalaxyThargoidStatus { get;set; }="原游戏 Thargoid 缓存尚未连接;状态计数未知。";
    private DateTimeOffset galaxyThargoidReadAt;
    private string galaxyThargoidContext="";
    private IReadOnlyDictionary<long,int?> galaxyThargoidObservedStates=new Dictionary<long,int?>();
    private string ThargoidContext()=>CurrentPlayer.InGame&&runtime.FlightDriver is NativeFlightControlDriver driver
        ?$"{driver.ProcessId}|{CurrentPlayer.CommanderId}|{CurrentPlayer.LoadGameAt:O}":"";
    private void ClearGalaxyThargoid(string status)
    {
        if(GalaxyThargoidCounts.Count>0)GalaxyThargoidCounts=[];
        if(GalaxyThargoidSignals.Count>0)GalaxyThargoidSignals=[];
        if(GalaxyThargoidRecommendations.Count>0)GalaxyThargoidRecommendations=[];
        galaxyThargoidContext="";GalaxyThargoidStatus=status;
        if(galaxyThargoidObservedStates.Count>0){galaxyThargoidObservedStates=new Dictionary<long,int?>();galaxyNativeFactsVersion++;}
    }
    private async Task ReadGalaxyThargoidAsync(CancellationToken token)
    {
        var context=ThargoidContext();
        if(galaxyThargoidContext.Length>0&&galaxyThargoidContext!=context)
        {ClearGalaxyThargoid("游戏会话已变化;旧 Thargoid 缓存已清除。原计数未知。");galaxyThargoidReadAt=default;}
        if(DateTimeOffset.UtcNow-galaxyThargoidReadAt<TimeSpan.FromSeconds(2))return;
        galaxyThargoidReadAt=DateTimeOffset.UtcNow;
        if(context.Length==0||runtime.FlightDriver is not NativeFlightControlDriver{SupportsGalaxyThargoid:true} driver)
        {ClearGalaxyThargoid("原游戏 Thargoid 缓存尚未连接;状态计数未知。");return;}
        bool Latest()=>context==ThargoidContext();
        try
        {
            var snapshot=await new NativeGalaxyAccountCatalog(driver.ProcessId).ReadThargoidAsync(token);
            token.ThrowIfCancellationRequested();if(!Latest())return;
            if(!snapshot.Available){ClearGalaxyThargoid("原游戏 Thargoid 服务尚未就绪;状态计数未知。");return;}
            var addresses=snapshot.Signals.Select(s=>s.SystemAddress).Concat(snapshot.Recommended.Select(s=>s.SystemAddress)).ToHashSet();
            var names=galaxyCache.Values.Where(s=>s.SystemAddress is {} address&&addresses.Contains(address)&&s.Position.IsValid).GroupBy(s=>s.SystemAddress!.Value).ToDictionary(g=>g.Key,g=>g.First().Name);
            GalaxyThargoidTarget Name(GalaxyThargoidTarget item)=>names.TryGetValue(item.SystemAddress,out var name)?item with{SystemName=name}:item;
            var counts=GalaxyThargoidPresentation.Counts(snapshot);var signals=GalaxyThargoidPresentation.Signals(snapshot).Select(Name).ToArray();var recommendations=GalaxyThargoidPresentation.Recommendations(snapshot).Select(Name).ToArray();
            var observed=GalaxyThargoidPresentation.ObservedStates(snapshot);if(observed.Count!=galaxyThargoidObservedStates.Count||observed.Any(x=>!galaxyThargoidObservedStates.TryGetValue(x.Key,out var state)||state!=x.Value)){galaxyThargoidObservedStates=observed;galaxyNativeFactsVersion++;}
            if(!GalaxyThargoidCounts.SequenceEqual(counts))GalaxyThargoidCounts=counts;
            if(!GalaxyThargoidSignals.SequenceEqual(signals))GalaxyThargoidSignals=signals;
            if(!GalaxyThargoidRecommendations.SequenceEqual(recommendations))GalaxyThargoidRecommendations=recommendations;
            galaxyThargoidContext=context;
            GalaxyThargoidStatus=$"原缓存 · {signals.Length:N0} 个信号 · {recommendations.Length:N0} 个推荐"+(snapshot.Ready?";计数来自现有缓存,全球完整性未确认。":";源尚未就绪,保留已有条目,状态计数未知。");
        }
        catch(OperationCanceledException)when(!token.IsCancellationRequested)
        {if(Latest())ClearGalaxyThargoid("原游戏 Thargoid 缓存读取超时;计数保持未知。");}
        catch(Exception error)when(error is IOException or TimeoutException or InvalidDataException or InvalidOperationException or System.Text.Json.JsonException or KeyNotFoundException or FormatException)
        {if(Latest())ClearGalaxyThargoid("原游戏 Thargoid 缓存尚未确认:"+error.Message);}
    }
    [RelayCommand] private async Task SelectGalaxyThargoidTargetAsync(GalaxyThargoidTarget? target)
    {
        if(target is null||galaxyThargoidContext.Length==0||galaxyThargoidContext!=ThargoidContext())return;
        var context=galaxyThargoidContext;var request=++galaxyMapTargetSelectionVersion;
        bool Listed()=>GalaxyThargoidSignals.Concat(GalaxyThargoidRecommendations).Any(t=>t.Kind==target.Kind&&t.Id==target.Id&&t.SystemAddress==target.SystemAddress);
        bool Latest()=>request==galaxyMapTargetSelectionVersion&&context==ThargoidContext()&&context==galaxyThargoidContext&&Listed();
        if(!Listed())return;
        try
        {
            var system=galaxyCache.Values.FirstOrDefault(s=>s.SystemAddress==target.SystemAddress&&s.Position.IsValid&&!string.IsNullOrWhiteSpace(s.Name));
            if(system is null)
            {
                if(runtime.FlightDriver is not NativeFlightControlDriver{SupportsGalaxyResolveAddress:true}||NativeGalaxy() is not {} catalog)
                {GalaxyThargoidStatus="已知原信号地址,尚未连接精确地址解析;没有坐标时不能定位。";return;}
                GalaxyThargoidStatus="正在读取原目标的实际坐标…";
                system=await catalog.ResolveAddressAsync(target.SystemAddress,lifetime.Token);
            }
            if(!Latest())return;
            if(system.SystemAddress!=target.SystemAddress||!system.Position.IsValid)throw new InvalidDataException("目标地址与实际目录记录不一致。");
            system=RememberGalaxy(system);GalaxySelection=system;GalaxyCentre=system.Position;PublishGalaxy();
            GalaxyThargoidStatus=target.Label+" · 已按原星系地址定位 "+system.Name;
        }
        catch(OperationCanceledException){ }
        catch(Exception error)when(error is IOException or TimeoutException or InvalidDataException or InvalidOperationException or KeyNotFoundException or System.Text.Json.JsonException)
        {if(Latest())GalaxyThargoidStatus="原目标定位尚未完成:"+error.Message;}
    }
}