using System.Diagnostics; using System.Text.Json; using Microsoft.UI.Xaml.Automation.Peers; using Microsoft.UI.Xaml.Automation.Provider; using XFEEDToolBox.Controls; using XFEEDToolBox.Core.Galaxy; using XFEEDToolBox.Core.Models; using XFEEDToolBox.Views; namespace XFEEDToolBox; public partial class App { // Offscreen application rendering and own-control interactions only. The // original catalogue captures are explicit input, never written to user data. private static async Task RunGalaxyReworkProbeAsync(string directory) { if(Environment.GetCommandLineArgs().Contains("--probe-galaxy-streaming"))return await RunGalaxyStreamingProbeAsync(directory); static void Require(bool condition,string message){if(!condition)throw new InvalidOperationException(message);} async Task Read(string path) { using var json=JsonDocument.Parse(await File.ReadAllTextAsync(path));var e=json.RootElement; return JsonSerializer.Deserialize(e.ValueKind==JsonValueKind.Array?e:e.GetProperty("systems"),Core.Models.ToolboxSettings.JsonOptions)??[]; } async Task Save(GalaxyMapView map,string name) { map.RenderNowForProbe();var f=map.CapturePixelsForProbe(); await SaveModelFrameAsync(new(f.Width,f.Height,f.Pixels,0),Path.Combine(directory,name+".png")); } var args=Environment.GetCommandLineArgs();var source=GetArgument(args,"--galaxy-fixture")??throw new ArgumentException("Recorded native catalogue fixture is required."); var systems=await Read(source);Require(systems.Length>100,"Native catalogue fixture is empty."); var shell=MainWindow.Content;var host=new Grid();MainWindow.Content=host; var map=new GalaxyMapView{Systems=systems,Centre=new(0,0,0),CurrentSystem="Sol",Filter=GalaxyMapFilter.Default}; host.Children.Add(map);await Task.Delay(250);map.RenderNowForProbe(); Require(map.MapGraphicsBackend.StartsWith("Direct3D"),map.GraphicsError); var localVisible=map.VisibleStars;Require(localVisible>50,"Recorded local systems were not projected."); var localBackgroundState=new{map.GalaxyDensityReady,map.VisibleNebulae,map.PendingNebulaLoads,map.ResidentNebulaTextures,map.SkyboxSource,scale=map.CameraState.Scale}; Require(map.VisibleFloorSelectorSegments>0,"The Galactic floor selector was not drawn."); await Save(map,"local-realistic"); var mousePose=map.CameraState;var mouseCentre=map.Centre!; map.ApplyMouseDragDelta(0,12,GalaxyMouseButtons.Right); Require(map.CameraMotionPendingForProbe&&map.Centre==mouseCentre,"Mouse input skipped target/actual camera separation."); map.AdvanceCameraMotionForProbe();map.RenderNowForProbe(); Require(map.Centre!.Y>mouseCentre.Y&&map.Centre.X==mouseCentre.X&&map.Centre.Z==mouseCentre.Z&&map.CameraState.Pitch==mousePose.Pitch,"Right-button crane did not use world Y independently of pitch."); var craningTarget=map.TargetCameraPoseForProbe!.Value; Require(map.Centre.Y{Windows.System.VirtualKey.W});map.AdvanceCameraMotionForProbe(); Require(redirected&&map.CameraMotionPendingForProbe&&map.Centre==redirectedFocus,"An old camera tick overwrote/cancelled an event-driven external focus and replacement zoom."); map.AdvanceCameraMotionForProbe(256); Require(map.Centre==redirectedFocus&&!map.CameraMotionPendingForProbe,"A replacement camera target retained stale motion."); } finally{map.SystemSelected-=RedirectDuringMotion;} map.ClearSelection();map.Centre=new(0,0,0);map.ResetCamera();mousePose=map.CameraState; map.ApplyMouseDragDelta(20,12,GalaxyMouseButtons.Left|GalaxyMouseButtons.Right);map.AdvanceCameraMotionForProbe(256);map.RenderNowForProbe(); Require(map.Centre!.Y==0&&map.Centre.DistanceTo(new(0,0,0))>0&&map.CameraState.Yaw==mousePose.Yaw&&map.CameraState.Pitch==mousePose.Pitch,"Both-button translation changed height or camera rotation."); map.BeginMousePointer(new(5,5),GalaxyMouseButtons.Left);map.ChangeMouseButtons(new(5,5),GalaxyMouseButtons.Left|GalaxyMouseButtons.Right); Require(!map.ShowsHold,"Changing the mouse chord left a route hold active."); var chordSelection=map.Selection; map.ChangeMouseButtons(new(5,5),GalaxyMouseButtons.Left);map.EndPointer(new(5,5)); Require(ReferenceEquals(map.Selection,chordSelection),"A mouse chord transition generated a left click."); map.ClearSelection(); map.Centre=new(0,0,0);map.ResetCamera();map.RenderNowForProbe(); map.Selection=systems.Where(s=>Math.Abs(s.Position.Y)>1).MinBy(s=>s.Position.DistanceTo(new(0,0,0))); var orbitFocus=map.Centre;var orbitScale=map.CameraState.Scale; var pose=map.CameraState;map.ApplyDragDelta(100,35,false);map.AdvanceCameraMotionForProbe(256);map.RenderNowForProbe(); Require(map.CameraState.Yaw!=pose.Yaw&&map.CameraState.Pitch!=pose.Pitch,"Orbit did not change camera."); Require(map.Centre==orbitFocus&&map.CameraState.Scale==orbitScale,"Orbit rebased its focus to a selected star's height."); await Save(map,"local-orbit"); map.ApplyKeyboardForProbe(.1,new HashSet{Windows.System.VirtualKey.W,Windows.System.VirtualKey.R});map.AdvanceCameraMotionForProbe(256); Require(map.Centre?.Y>0,"Keyboard vertical movement did not move in Galactic Y."); map.ResetCamera();map.Centre=new(0,0,0);map.RenderNowForProbe(); var chosen=systems.FirstOrDefault(s=>s.Name=="Sol")??systems.MinBy(s=>s.Position.DistanceTo(new(0,0,0)))!; var beforeOriginalInput=map.ActualCameraPoseForProbe; map.ApplyKeyboardForProbe(.1,new HashSet{Windows.System.VirtualKey.T,Windows.System.VirtualKey.E}); var originalInputTarget=map.TargetCameraPoseForProbe!.Value; Require(originalInputTarget.PitchbeforeOriginalInput.Yaw, "Original T/E pitch/yaw bindings were reversed."); map.AdvanceCameraMotionForProbe(256); map.CurrentSystem=chosen.Name;var beforeHome=map.ActualCameraPoseForProbe; Require(map.ReturnCameraHome()&&!map.LastHomeUsedOriginalCentreForProbe,"Known-current fallback Home did not retain its explicit source boundary."); var homeTarget=map.TargetCameraPoseForProbe!.Value; Require(homeTarget.Focus==new Coordinates(chosen.Position.X,Math.Floor(chosen.Position.Y),chosen.Position.Z)&& homeTarget.Yaw==beforeHome.Yaw&&homeTarget.Pitch==beforeHome.Pitch&&homeTarget.Distance==Math.Min(beforeHome.Distance,17.75), "Home reset angles/distance or did not use the real known centre."); map.AdvanceCameraMotionForProbe(256);map.CurrentSystem="unavailable-home-source"; Require(!map.ReturnCameraHome()&&!map.CameraMotionPendingForProbe,"Missing Home source invented a navigation centre."); map.CurrentSystem=chosen.Name;map.ResetCamera(); map.FocusSystem(chosen,false);await Task.Delay(300);map.RenderNowForProbe(); var selectedAt=map.ProjectForProbe(chosen.Position);var submissions=0; map.TargetChosen+=(_,s)=>{Require(s.Name==chosen.Name,"Hold changed target.");submissions++;map.Planning=false;}; map.BeginPointer(selectedAt,false);map.EndPointer(selectedAt);Require(submissions==0,"Click submitted a route."); map.BeginPointer(selectedAt,false);await Task.Delay(760);map.EndPointer(selectedAt);Require(submissions==1,"Hold did not submit exactly once."); map.ClearSelection();map.CurrentSystem="";map.Filter=GalaxyMapFilter.Default with{Mode=GalaxyMapMode.Map,Values=new HashSet{"g"},IncludeUnknown=false}; map.RenderNowForProbe();var filtered=map.VisibleStars;Require(filtered>0&&filtered(),ShowGrid=false,ShowLabels=false,ShowMarkers=false,ShowBackground=false};map.RenderNowForProbe(); Require(map.VisibleStars==0&&map.GridLinesVisible==0,"Empty filter or grid switch did not take effect."); map.Filter=GalaxyMapFilter.Default;map.CurrentSystem="Sol";map.Centre=new(0,0,0);map.ResetCamera(); var neighbour=systems.Where(s=>s.Name!="Sol").MinBy(s=>s.Position.DistanceTo(chosen.Position))!; map.Route=[new(chosen.SystemAddress??1,chosen.Name,chosen.Position,chosen.StarClass),new(neighbour.SystemAddress??2,neighbour.Name,neighbour.Position,neighbour.StarClass)]; map.Filter=GalaxyMapFilter.Default with{ShowLinks=true};map.RenderNowForProbe(); var labelsOn=map.VisibleNameLabels;var linksOn=map.VisibleLinkSegments;var routeOn=map.VisibleRouteSegments; Require(labelsOn>0&&linksOn>0&&routeOn>0,"Enabled overlay geometry was missing."); var withMarkers=map.CapturePixelsForProbe();map.Filter=map.Filter with{ShowMarkers=false};map.RenderNowForProbe();var withoutMarkers=map.CapturePixelsForProbe(); Require(!withMarkers.Pixels.SequenceEqual(withoutMarkers.Pixels),"Marker switch did not alter GPU pixels."); map.Filter=map.Filter with{ShowLabels=false,ShowRoute=false,ShowLinks=false};map.RenderNowForProbe(); Require(map.VisibleNameLabels==0&&map.VisibleRouteSegments==0&&map.VisibleLinkSegments==0,"Overlay switches left visible geometry."); var originalNebulaBackgroundPresent=map.VisibleNebulae>0; var originalAuthoredBackgroundPresent=map.OriginalBackgroundHdrDrawnForProbe; var originalBackgroundPresent=originalNebulaBackgroundPresent||originalAuthoredBackgroundPresent; var backgroundOn=map.CapturePixelsForProbe();map.Filter=map.Filter with{ShowBackground=false};map.RenderNowForProbe();var backgroundOff=map.CapturePixelsForProbe(); if(originalBackgroundPresent)Require(!backgroundOn.Pixels.SequenceEqual(backgroundOff.Pixels),"Background switch did not alter GPU pixels."); Require(!map.OriginalBackgroundHdrDrawnForProbe,"Background switch retained authored HDR layers."); map.Route=[];map.Filter=GalaxyMapFilter.Default; var timings=new List(); if(GetArgument(args,"--core-fixture") is {} core) { map.Systems=await Read(core);map.Centre=new(25.21875,-20.90625,25899.96875);map.Zoom(.125);map.AdvanceCameraMotionForProbe(256);map.RenderNowForProbe(); await Save(map,"native-core-realistic"); for(var i=0;i<30;i++){map.ApplyDragDelta(.1,.02,false);map.AdvanceCameraMotionForProbe();map.RenderNowForProbe();timings.Add(map.LastFrameMilliseconds);} map.AdvanceCameraMotionForProbe(256);Require(!map.CameraMotionPendingForProbe,"Camera motion did not converge after input stopped."); } // Freeze the exact GPU surface into XAML for a truthful composited page // export; RenderTargetBitmap alone omits native composition surfaces. map.SuspendPage();MainWindow.Content=shell; ViewModel.SetGalaxyRegionQueryForProbe(async(centre,radius,token)=> {await Task.Yield();token.ThrowIfCancellationRequested();return GalaxyRegionResult.Covered(systems.Where(s=>s.Position.DistanceTo(centre)<=radius).ToArray());}); ViewModel.SeedGalaxyForProbe(systems);ViewModel.GalaxyCentre=new(0,0,0);ViewModel.GalaxyFilter=GalaxyMapFilter.Default; AppShellPage.Current!.Navigate(typeof(NavigationPage));await Task.Delay(250); var page=(NavigationPage)AppShellPage.Current.CurrentPage!;var pageMap=(GalaxyMapView)page.FindName("Map");pageMap.ResetCamera(); using(await pageMap.FreezeForXamlProbeAsync())await CapturePageAsync(page,Path.Combine(directory,"navigation-realistic.png")); if(page.FindName("FiltersExpander") is HorizontalPanel filterExpander)filterExpander.IsExpanded=true; await Task.Delay(150); var filters=Descendants(page).OfType().FirstOrDefault(); if(filters is not null) { ViewModel.GalaxyFilter=GalaxyMapFilter.Default with{Mode=GalaxyMapMode.Map}; await Task.Delay(100); using(await pageMap.FreezeForXamlProbeAsync())await CapturePageAsync(page,Path.Combine(directory,"navigation-filters.png")); } Require(filters is not null,"Expanded filter panel did not enter the visual tree."); Require(ViewModel.GalaxySystems.Count>100&&pageMap.VisibleStars>50,"Catalogue disappeared during composited filter capture."); var displayPanel=Descendants(filters).OfType().Single(e=>e.Header as string=="显示控制");displayPanel.IsExpanded=true;page.UpdateLayout(); var displayCheckStates=Descendants(displayPanel).OfType().Select(check=>new { label=check.Content as string,check.IsChecked, states=Descendants(check).OfType().SelectMany(VisualStateManager.GetVisualStateGroups).Select(g=>g.CurrentState?.Name).OfType().ToArray(), glyphs=Descendants(check).OfType().Select(icon=>new{icon.Glyph,font=icon.FontFamily.Source}).ToArray(), animatedGlyphs=Descendants(check).OfType().Select(icon=>new{state=AnimatedIcon.GetState(icon),source=icon.Source?.GetType().FullName, fallback=icon.FallbackIconSource is FontIconSource fallback?fallback.Glyph:null,icon.ActualWidth,icon.ActualHeight}).ToArray() }).ToArray(); var sidebarScroll=(ScrollViewer)page.FindName("SidebarScroll"); var displayOffset=displayPanel.TransformToVisual((UIElement)sidebarScroll.Content).TransformPoint(new(0,0)).Y; sidebarScroll.ChangeView(null,displayOffset,null,true);await Task.Delay(650); using(await pageMap.FreezeForXamlProbeAsync())await CapturePageAsync(page,Path.Combine(directory,"navigation-display-options.png")); sidebarScroll.ChangeView(null,sidebarScroll.ScrollableHeight,null,true);await Task.Delay(120); var filterScrollableHeight=sidebarScroll.ScrollableHeight;var filterVerticalOffset=sidebarScroll.VerticalOffset; Require(filterScrollableHeight>0&&filterVerticalOffset>0,"Long filter panel cannot scroll to its lower controls."); using(await pageMap.FreezeForXamlProbeAsync())await CapturePageAsync(page,Path.Combine(directory,"navigation-lower-controls.png")); // Synthetic masks exercise the production panel's true / false / null // presentation. They do not claim any live power metadata is available. ViewModel.GalaxyFilter=GalaxyMapFilter.Default with{Mode=GalaxyMapMode.Powerplay,Category=GalaxyFilterCategory.Power,TerritoryStateMask=0x82}; await Task.Delay(80);page.UpdateLayout(); var powerStatePanel=Descendants(filters).OfType().Single(e=>(e.Header as string)?.StartsWith("领土状态",StringComparison.Ordinal)==true); powerStatePanel.IsExpanded=true;page.UpdateLayout(); var stateOffset=powerStatePanel.TransformToVisual((UIElement)sidebarScroll.Content).TransformPoint(new(0,0)).Y; sidebarScroll.ChangeView(null,stateOffset,null,true);await Task.Delay(120); var stateChecks=Descendants(powerStatePanel).OfType().ToArray(); var mixedStateCount=stateChecks.Count(c=>c.IsChecked is null); Require(stateChecks.Length==6&&mixedStateCount==2&&stateChecks.Count(c=>c.IsChecked==false)==4,"Original state bit groups lost their partial selection."); using(await pageMap.FreezeForXamlProbeAsync())await CapturePageAsync(page,Path.Combine(directory,"navigation-power-states-mixed.png")); ViewModel.GalaxyFilter=ViewModel.GalaxyFilter with{TerritoryStateMask=null};await Task.Delay(80); Require(stateChecks.All(c=>c.IsChecked==true),"Disabled original state mask did not display all groups selected."); using(await pageMap.FreezeForXamlProbeAsync())await CapturePageAsync(page,Path.Combine(directory,"navigation-power-states-all.png")); ViewModel.GalaxyFilter=ViewModel.GalaxyFilter with{TerritoryStateMask=0};await Task.Delay(80); Require(stateChecks.All(c=>c.IsChecked==false),"An enabled empty state mask became all groups selected."); using(await pageMap.FreezeForXamlProbeAsync())await CapturePageAsync(page,Path.Combine(directory,"navigation-power-states-none.png")); ViewModel.GalaxyFilter=GalaxyMapFilter.Default with{Mode=GalaxyMapMode.Map}; var originalDirectory=Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"Frontier Developments","Elite Dangerous","Options","Player"); var originalFiles=Directory.Exists(originalDirectory)?Directory.GetFiles(originalDirectory,"*.misc"):[]; var originalHashes=originalFiles.ToDictionary(p=>p,p=>Convert.ToHexString(System.Security.Cryptography.SHA256.HashData(File.ReadAllBytes(p)))); await ViewModel.ImportOriginalGalaxySettingsCommand.ExecuteAsync(null); var importedOptions=ViewModel.GalaxyOriginalOptions.Count;var importedGroups=ViewModel.GalaxyFilter.SavedValues.Count; var originalFilesUnchanged=originalHashes.All(p=>Convert.ToHexString(System.Security.Cryptography.SHA256.HashData(File.ReadAllBytes(p.Key)))==p.Value); Require(originalFilesUnchanged,"Read-only import changed original game configuration."); if(originalFiles.Length>0)Require(importedOptions>0&&importedGroups>0,"Original game options import failed: "+ViewModel.GalaxyOriginalSettingsStatus); using(await pageMap.FreezeForXamlProbeAsync())await CapturePageAsync(page,Path.Combine(directory,"navigation-original-import.png")); ViewModel.GalaxyFilter=GalaxyMapFilter.Default with{Mode=GalaxyMapMode.Map}; var sidebar=(HorizontalPanel)page.FindName("SidebarExpander");var previousSidebarExpanded=sidebar.IsExpanded; var previousRouteOptions=ViewModel.NavigationRouteOptions;var previousSidebarOffset=sidebarScroll.VerticalOffset; sidebar.IsExpanded=true;page.UpdateLayout();await Task.Delay(80); var routeExpander=Descendants(page).OfType().Single(e=>e.Header as string=="航行偏好"); var previousRouteExpanded=routeExpander.IsExpanded;routeExpander.IsExpanded=true;page.UpdateLayout();await Task.Delay(80); var routePanel=Descendants(routeExpander).OfType().Single(); var previousCargoCapacity=routePanel.CargoCapacity; var previousRouteFilter=ViewModel.GalaxyFilter; try { // This is an explicit own-control fixture. It does not inspect the // game cargo or invoke any planning/navigation command. routePanel.CargoCapacity=64;ViewModel.NavigationRouteOptions=new();await Task.Delay(50); var routeMode=Descendants(routePanel).OfType().Single(c=>c.Header as string=="航线模式"); var routeBoost=Descendants(routePanel).OfType().Single(c=>c.Header as string=="FSD 增益等级"); var routeJet=Descendants(routePanel).OfType().Single(c=>c.Content as string=="使用喷流增益"); var routeCargo=Descendants(routePanel).OfType().Single(c=>c.Header as string=="规划货重 / t"); routeMode.SelectedIndex=3;routeBoost.SelectedIndex=4;routeJet.IsChecked=true; // ValueChanged commits all four current control values, including // the checkbox whose programmatic IsChecked does not raise Click. routeCargo.Value=12.5;await Task.Delay(80);page.UpdateLayout(); var editedRouteOptions=ViewModel.NavigationRouteOptions; Require(editedRouteOptions.Mode==XFEEDToolBox.Core.Navigation.GameRoutePlotMode.FsdBoost&& editedRouteOptions.FsdBoostLevel==3&&editedRouteOptions.UseJetConeBoost==true&&editedRouteOptions.VirtualCargoMass==12.5, "Route settings controls did not update all four VM options through the two-way binding."); ViewModel.GalaxyFilter=GalaxyMapFilter.Default.WithCategory(GalaxyFilterCategory.StarClass) with{Values=new HashSet(GalaxyFilterDefinitions.ScoopableStarClasses)}; await Task.Delay(50); var copyStar=Descendants(routePanel).OfType