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.Data;
using XFEEDToolBox.Core.Models;
using XFEEDToolBox.Core.Native;
using XFEEDToolBox.Core.Navigation;

internal static class LocalFlightFrameAcceptance
{
    public static async Task RunAsync(int pid,string exactName,string reportPath)
    {
        if(File.Exists(reportPath))throw new IOException("Use a new report path.");
        var settings=ToolboxSettings.Load(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"XFEstudio","XFEEDToolBox","settings.json"));
        await using var journal=new JournalMonitor(settings.JournalDirectory);await journal.StartAsync();var raw=new NavigationPipeClient(pid);
        var hash=(await raw.CallAsync(new{op="describe"})).GetProperty("gameSha256").GetString()!;
        using var source=new NativeCurrentSystemSource(pid,hash,()=>journal.State);var before=await source.ReadLocationsAsync();
        var row=before.Locations.Single(x=>x.Name.Equals(exactName,StringComparison.Ordinal));
        var target=new SystemNavigationTarget(before.SystemAddress,row.WorldAddress,row.Name,row.MarketId is >0?SystemTargetKind.Station:SystemTargetKind.Orbit,row.MarketId)
            {NativeKey=row.Key,NativeKind=row.NativeKind,NativeIdentity=row.Identity};
        var driver=new NativeSystemFlightControlDriver(pid,hash,()=>journal.State);var samples=new List<SystemFlightFrame>();string? failure=null;var suspended=false;
        try
        {
            using var timeout=new CancellationTokenSource(TimeSpan.FromSeconds(10));await driver.SelectAsync(target,timeout.Token);
            while(samples.Count<20)
            {
                SystemFlightFrame frame;
                try{frame=await driver.ReadSystemFlightAsync(timeout.Token);}
                catch(FlightTelemetryUnavailableException){await Task.Delay(40,timeout.Token);continue;}
                var independently=(await source.ReadLocationsAsync(timeout.Token)).Locations.Single(x=>x.Identity==row.Identity);
                if(!independently.Selected||independently.DistanceMetres is not {} distance||Math.Abs(frame.TargetDistance-distance)>Math.Max(10,distance*.0001))throw new InvalidDataException("Target or independently read distance does not agree.");
                if(frame.Speed>=1)throw new InvalidOperationException("Observation fixture requires a stationary ship.");
                samples.Add(frame);await Task.Delay(45,timeout.Token);
            }
            await driver.SuspendSystemFlightAsync();suspended=true;
            var after=await driver.ReadSystemFlightAsync(timeout.Token);if(after.SelectedTarget?.SameIdentity(target)!=true)throw new InvalidDataException("Suspension lost target identity.");
        }
        catch(Exception error){failure=error.ToString();}
        finally{await driver.ReleaseSystemFlightAsync();}
        var passed=failure is null&&samples.Count==20&&suspended;
        await File.WriteAllTextAsync(reportPath,JsonSerializer.Serialize(new{pid,target,samples,suspended,passed,failure,flightInputsSent=0},ToolboxSettings.JsonOptions));
        Console.WriteLine(JsonSerializer.Serialize(new{passed,samples=samples.Count,suspended,failure,flightInputsSent=0}));
        if(!passed)throw new InvalidOperationException("System-flight frame acceptance failed.");
    }
}