using XFEEDToolBox.Core.Data; using XFEEDToolBox.Core.Models; using XFEEDToolBox.Core.Navigation; using XFEEDToolBox.Core.Session; using XFEEDToolBox.Services; internal sealed class FlightTestProtectionScope(JournalMonitor journal,NativeFlightTestProtection protection):IAsyncDisposable { public bool Stopped=>protection.Stopped; public string? LastIssue=>protection.LastIssue; public static async Task ArmAsync(int pid,bool automaticExit=true,bool exitForFailedHandoff=true,CancellationToken token=default) { if(!OperatingSystem.IsWindows())throw new PlatformNotSupportedException("原生飞行验收仅支持 Windows。"); var settings=ToolboxSettings.Load(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"XFEstudio","XFEEDToolBox","settings.json")); var journal=new JournalMonitor(settings.JournalDirectory); try { await journal.StartAsync(token); var hello=await new NavigationPipeClient(pid).CallAsync(new{op="describe"},token); var guardian=PersistentProtectionProcess.Current;guardian?.RequireReady(pid); var protection=await NativeFlightTestProtection.ArmAsync(pid,hello.GetProperty("gameSha256").GetString()!, new WindowsGameSessionDriver(()=>journal.State,()=>settings.PluginGameExecutable),()=>journal.State,()=>{},token,automaticExit:guardian is null&&automaticExit,exitForFailedHandoff:exitForFailedHandoff, externalProtectionCheck:guardian is null?null:()=>guardian.RequireReady(pid)); journal.JournalEvent+=protection.ObserveJournal; return new(journal,protection); } catch{await journal.DisposeAsync();throw;} } public async ValueTask DisposeAsync() { journal.JournalEvent-=protection.ObserveJournal; try{await protection.DisposeAsync();}finally{await journal.DisposeAsync();} } }