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<object> 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<GalacticSystem[]> Read(string path)
{
using var json=JsonDocument.Parse(await File.ReadAllTextAsync(path));var e=json.RootElement;
return JsonSerializer.Deserialize<GalacticSystem[]>(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<craningTarget.Focus.Y,"A single original smoothing tick jumped to the crane target.");
map.FinishCameraInputForProbe();map.AdvanceCameraMotionForProbe(256);
Require(!map.CameraMotionPendingForProbe&&map.Centre.Y==Math.Floor(craningTarget.Focus.Y+.5),"Released crane did not settle target height and stop its timer.");
map.ClearSelection();map.Centre=new(0,0,0);map.ResetCamera();map.RenderNowForProbe();
var redirected=false;var redirectedFocus=new Coordinates(3,7,11);
void RedirectDuringMotion(object? sender,GalacticSystem selected)
{
if(redirected)return;redirected=true;
map.Centre=redirectedFocus;map.Zoom(.8);
}
map.SystemSelected+=RedirectDuringMotion;
try
{
map.ApplyKeyboardForProbe(.1,new HashSet<Windows.System.VirtualKey>{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>{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>{Windows.System.VirtualKey.T,Windows.System.VirtualKey.E});
var originalInputTarget=map.TargetCameraPoseForProbe!.Value;
Require(originalInputTarget.Pitch<beforeOriginalInput.Pitch&&originalInputTarget.Yaw>beforeOriginalInput.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<string>{"g"},IncludeUnknown=false};
map.RenderNowForProbe();var filtered=map.VisibleStars;Require(filtered>0&&filtered<localVisible,"Stellar class filter did not remove stars.");
await Save(map,"local-filter-g");
map.Filter=map.Filter with{Values=new HashSet<string>(),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<double>();
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<GalaxyFilterPanel>().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<Expander>().Single(e=>e.Header as string=="显示控制");displayPanel.IsExpanded=true;page.UpdateLayout();
var displayCheckStates=Descendants(displayPanel).OfType<CheckBox>().Select(check=>new
{
label=check.Content as string,check.IsChecked,
states=Descendants(check).OfType<FrameworkElement>().SelectMany(VisualStateManager.GetVisualStateGroups).Select(g=>g.CurrentState?.Name).OfType<string>().ToArray(),
glyphs=Descendants(check).OfType<FontIcon>().Select(icon=>new{icon.Glyph,font=icon.FontFamily.Source}).ToArray(),
animatedGlyphs=Descendants(check).OfType<AnimatedIcon>().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<Expander>().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<CheckBox>().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<Expander>().Single(e=>e.Header as string=="航行偏好");
var previousRouteExpanded=routeExpander.IsExpanded;routeExpander.IsExpanded=true;page.UpdateLayout();await Task.Delay(80);
var routePanel=Descendants(routeExpander).OfType<GalaxyRouteSettingsPanel>().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<ComboBox>().Single(c=>c.Header as string=="航线模式");
var routeBoost=Descendants(routePanel).OfType<ComboBox>().Single(c=>c.Header as string=="FSD 增益等级");
var routeJet=Descendants(routePanel).OfType<CheckBox>().Single(c=>c.Content as string=="使用喷流增益");
var routeCargo=Descendants(routePanel).OfType<NumberBox>().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<string>(GalaxyFilterDefinitions.ScoopableStarClasses)};
await Task.Delay(50);
var copyStar=Descendants(routePanel).OfType<Button>().Single(c=>c.Content as string=="采用星图所选类别");
((IInvokeProvider)new ButtonAutomationPeer(copyStar).GetPattern(PatternInterface.Invoke)).Invoke();await Task.Delay(80);
Require(ViewModel.NavigationRouteOptions.StarClassFilter?.OriginalMask==0x807F,"Scoopable classes did not map exactly to the original route mask.");
routeCargo.Value=13.5;await Task.Delay(50);
Require(ViewModel.NavigationRouteOptions.StarClassFilter?.OriginalMask==0x807F,"Changing cargo discarded the explicit star-class route filter.");
ViewModel.GalaxyFilter=ViewModel.GalaxyFilter with{Values=new HashSet<string>{"da"}};await Task.Delay(50);
((IInvokeProvider)new ButtonAutomationPeer(copyStar).GetPattern(PatternInterface.Invoke)).Invoke();await Task.Delay(80);
Require(ViewModel.NavigationRouteOptions.StarClassFilter?.OriginalMask==0x807F&&Descendants(routePanel).OfType<TextBlock>().Any(t=>t.Text.Contains("请选择该分组的全部子类")),"A partial white-dwarf group was silently widened for route plotting.");
ViewModel.GalaxyFilter=ViewModel.GalaxyFilter with{Values=new HashSet<string>(GalaxyFilterDefinitions.ScoopableStarClasses)};await Task.Delay(50);
((IInvokeProvider)new ButtonAutomationPeer(copyStar).GetPattern(PatternInterface.Invoke)).Invoke();await Task.Delay(80);
routeCargo.Value=12.5;await Task.Delay(50);
var routeOffset=routeExpander.TransformToVisual((UIElement)sidebarScroll.Content).TransformPoint(new(0,0)).Y;
sidebarScroll.ChangeView(null,Math.Max(0,routeOffset-8),null,true);await Task.Delay(150);
using(await pageMap.FreezeForXamlProbeAsync())await CapturePageAsync(page,Path.Combine(directory,"navigation-route-options.png"));
var chooseStars=Descendants(routePanel).OfType<Button>().Single(c=>c.Content as string=="选择恒星类别…");
MainWindow.AppWindow.Move(new(-30000,-30000));MainWindow.AppWindow.Show(false);await Task.Delay(60);
await CaptureRefinementElementAsync(routePanel,Path.Combine(directory,"navigation-route-panel.png"));
chooseStars.Flyout!.ShowAt(chooseStars);await Task.Delay(100);
await CaptureRefinementElementAsync((FrameworkElement)((Flyout)chooseStars.Flyout).Content,Path.Combine(directory,"navigation-route-star-groups.png"));
chooseStars.Flyout.Hide();MainWindow.AppWindow.Hide();
var mapRouteExpander=Descendants(routePanel).OfType<Expander>().Single(e=>e.Header as string=="其他分类路线筛选");
mapRouteExpander.IsExpanded=true;page.UpdateLayout();await Task.Delay(60);
ViewModel.GalaxyFilter=GalaxyOriginalSettings.Parse("<Root><RealisticView Value='1'/><ColourVisIndex Value='3'/><VisibilityFlags><government><Anarchy Value='1'/><Democracy Value='0'/><Corporate Value='0'/><affectsRoutePlotting Value='1'/></government></VisibilityFlags></Root>",ViewModel.GalaxyFilter).Filter with{Values=new HashSet<string>{"democracy"}};
await Task.Delay(50);
var copyMap=Descendants(routePanel).OfType<Button>().Single(c=>c.Content as string=="采用当前分类筛选");
((IInvokeProvider)new ButtonAutomationPeer(copyMap).GetPattern(PatternInterface.Invoke)).Invoke();await Task.Delay(80);
Require(ViewModel.NavigationRouteOptions.MapFilter is{CategoryId:3} government&&government.SelectedKeys.SequenceEqual(new[]{"democracy"})&&
ViewModel.NavigationRouteOptions.StarClassFilter?.OriginalMask==0x807F,"The current government route selection lost its exact original names or the existing star filter.");
var mapOffset=mapRouteExpander.TransformToVisual((UIElement)sidebarScroll.Content).TransformPoint(new(0,0)).Y;
sidebarScroll.ChangeView(null,Math.Max(0,mapOffset-8),null,true);await Task.Delay(100);
using(await pageMap.FreezeForXamlProbeAsync())await CapturePageAsync(page,Path.Combine(directory,"navigation-route-map-options.png"));
ViewModel.GalaxyFilter=GalaxyOriginalSettings.Parse("<Root><RealisticView Value='1'/><ColourVisIndex Value='7'/><VisibilityFlags><security><Anarchy Value='1'/><Lawless Value='0'/><LowSecurity Value='0'/><affectsRoutePlotting Value='0'/></security></VisibilityFlags></Root>",ViewModel.GalaxyFilter).Filter;
await Task.Delay(50);((IInvokeProvider)new ButtonAutomationPeer(copyMap).GetPattern(PatternInterface.Invoke)).Invoke();await Task.Delay(80);
Require(ViewModel.NavigationRouteOptions.MapFilter?.CategoryId==3&&Descendants(routePanel).OfType<TextBlock>().Any(t=>t.Text.Contains("工具合并了不同")),"Merged public aliases silently widened the original route selection.");
using(await pageMap.FreezeForXamlProbeAsync())await CapturePageAsync(page,Path.Combine(directory,"navigation-route-map-ambiguous.png"));
var savedMap=Descendants(routePanel).OfType<Button>().Single(c=>c.Content as string=="采用游戏保存的分类筛选");
((IInvokeProvider)new ButtonAutomationPeer(savedMap).GetPattern(PatternInterface.Invoke)).Invoke();await Task.Delay(80);
Require(ViewModel.NavigationRouteOptions.MapFilter is{CategoryId:7,AffectsRoutePlotting:false} security&&
security.ExpectedKeys.Count==3&&security.SelectedKeys.SequenceEqual(new[]{"anarchy"}),"Exact saved Anarchy/Lawless identities were merged in route options.");
var chooseMap=Descendants(routePanel).OfType<Button>().Single(c=>c.Content as string=="选择原分类选项…");
MainWindow.AppWindow.Move(new(-30000,-30000));MainWindow.AppWindow.Show(false);await Task.Delay(50);
chooseMap.Flyout!.ShowAt(chooseMap);await Task.Delay(80);
await CaptureRefinementElementAsync((FrameworkElement)((Flyout)chooseMap.Flyout).Content,Path.Combine(directory,"navigation-route-map-groups.png"));
chooseMap.Flyout.Hide();MainWindow.AppWindow.Hide();mapRouteExpander.IsExpanded=false;
}
finally
{
routePanel.CargoCapacity=previousCargoCapacity;ViewModel.NavigationRouteOptions=previousRouteOptions;
ViewModel.GalaxyFilter=previousRouteFilter;
routeExpander.IsExpanded=previousRouteExpanded;sidebar.IsExpanded=previousSidebarExpanded;page.UpdateLayout();
sidebarScroll.ChangeView(null,previousSidebarOffset,null,true);
}
var idleFrame=pageMap.FrameCount;await Task.Delay(150);var settledFrame=pageMap.FrameCount;await Task.Delay(150);
Require(pageMap.FrameCount==settledFrame,"Idle map kept redrawing.");
timings.Sort();
var stateOptions=await RunGalaxyStateOptionsProbeAsync(directory);
return new{source=Path.GetFullPath(source),recordedLocalSystems=systems.Length,localVisible,filteredGVisible=filtered,
renderer=map.MapGraphicsBackend,keyboardMovement=true,originalInputGainsAndSigns=true,homePreservesAnglesAndClampsDistance=true,homeSourceFallbackExplicit=true,missingHomeSourceDoesNotInventCentre=true,orbit=true,orbitFocusIndependentOfSelection=true,originalPerTickSmoothing=true,targetActualPoseSeparated=true,releasedCraneSettlesTargetOnly=true,motionTimerConverges=true,reentrantFocusCancelsOldMotion=true,originalMouseChords=true,craneUsesWorldY=true,bothButtonsUseXZ=true,chordChangeCancelsHoldAndClick=true,floorSelector=true,clickDoesNotSubmit=true,holdSubmissions=submissions,emptyFilterClearsStars=true,gridSwitch=true,
layerSwitches=new{labelsOn,linksOn,routeOn,markersChangePixels=true,disabledOverlaysEmitNoGeometry=true,originalBackgroundPresent,
originalNebulaBackgroundPresent,originalAuthoredBackgroundPresent,backgroundToggleChecked=originalBackgroundPresent},
localBackgroundState,
originalSettingsImport=new{importedOptions,importedGroups,originalFilesUnchanged},
filterPanelLayout=new{filterScrollableHeight,filterVerticalOffset,canReachLowerControls=true},
displayCheckStates,
originalPowerStateMaskPresentation=new{syntheticMasksOnly=true,mixedStateCount,disabledMaskShowsAll=true,enabledEmptyMaskShowsNone=true},
routeOptionsPanelFixture=true,
routeStarClassFixture=new{exactScoopableMask=0x807F,partialGroupsRejected=true,otherOptionsPreserveStarClasses=true,gameCommandsInvoked=false},
routeMapFilterFixture=new{exactOriginalNames=true,governmentSelection=true,independentAnarchyLawless=true,mergedAliasesRejected=true,starFilterPreserved=true,gameCommandsInvoked=false},
stateOptions,
nativeCoreVisible=map.VisibleStars,meanCpuMilliseconds=timings.Count>0?timings.Average():0,p95CpuMilliseconds=timings.Count>0?timings[(int)(timings.Count*.95)]:0,
idleStopsRendering=pageMap.FrameCount==settledFrame,filterPanelPresent=filters is not null,gameCommandsInvoked=false,generatedCatalogueCoordinates=false};
}
}
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<object> 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<GalacticSystem[]> Read(string path)
{
using var json=JsonDocument.Parse(await File.ReadAllTextAsync(path));var e=json.RootElement;
return JsonSerializer.Deserialize<GalacticSystem[]>(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<craningTarget.Focus.Y,"A single original smoothing tick jumped to the crane target.");
map.FinishCameraInputForProbe();map.AdvanceCameraMotionForProbe(256);
Require(!map.CameraMotionPendingForProbe&&map.Centre.Y==Math.Floor(craningTarget.Focus.Y+.5),"Released crane did not settle target height and stop its timer.");
map.ClearSelection();map.Centre=new(0,0,0);map.ResetCamera();map.RenderNowForProbe();
var redirected=false;var redirectedFocus=new Coordinates(3,7,11);
void RedirectDuringMotion(object? sender,GalacticSystem selected)
{
if(redirected)return;redirected=true;
map.Centre=redirectedFocus;map.Zoom(.8);
}
map.SystemSelected+=RedirectDuringMotion;
try
{
map.ApplyKeyboardForProbe(.1,new HashSet<Windows.System.VirtualKey>{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>{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>{Windows.System.VirtualKey.T,Windows.System.VirtualKey.E});
var originalInputTarget=map.TargetCameraPoseForProbe!.Value;
Require(originalInputTarget.Pitch<beforeOriginalInput.Pitch&&originalInputTarget.Yaw>beforeOriginalInput.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<string>{"g"},IncludeUnknown=false};
map.RenderNowForProbe();var filtered=map.VisibleStars;Require(filtered>0&&filtered<localVisible,"Stellar class filter did not remove stars.");
await Save(map,"local-filter-g");
map.Filter=map.Filter with{Values=new HashSet<string>(),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<double>();
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<GalaxyFilterPanel>().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<Expander>().Single(e=>e.Header as string=="显示控制");displayPanel.IsExpanded=true;page.UpdateLayout();
var displayCheckStates=Descendants(displayPanel).OfType<CheckBox>().Select(check=>new
{
label=check.Content as string,check.IsChecked,
states=Descendants(check).OfType<FrameworkElement>().SelectMany(VisualStateManager.GetVisualStateGroups).Select(g=>g.CurrentState?.Name).OfType<string>().ToArray(),
glyphs=Descendants(check).OfType<FontIcon>().Select(icon=>new{icon.Glyph,font=icon.FontFamily.Source}).ToArray(),
animatedGlyphs=Descendants(check).OfType<AnimatedIcon>().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<Expander>().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<CheckBox>().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<Expander>().Single(e=>e.Header as string=="航行偏好");
var previousRouteExpanded=routeExpander.IsExpanded;routeExpander.IsExpanded=true;page.UpdateLayout();await Task.Delay(80);
var routePanel=Descendants(routeExpander).OfType<GalaxyRouteSettingsPanel>().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<ComboBox>().Single(c=>c.Header as string=="航线模式");
var routeBoost=Descendants(routePanel).OfType<ComboBox>().Single(c=>c.Header as string=="FSD 增益等级");
var routeJet=Descendants(routePanel).OfType<CheckBox>().Single(c=>c.Content as string=="使用喷流增益");
var routeCargo=Descendants(routePanel).OfType<NumberBox>().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<string>(GalaxyFilterDefinitions.ScoopableStarClasses)};
await Task.Delay(50);
var copyStar=Descendants(routePanel).OfType<Button>().Single(c=>c.Content as string=="采用星图所选类别");
((IInvokeProvider)new ButtonAutomationPeer(copyStar).GetPattern(PatternInterface.Invoke)).Invoke();await Task.Delay(80);
Require(ViewModel.NavigationRouteOptions.StarClassFilter?.OriginalMask==0x807F,"Scoopable classes did not map exactly to the original route mask.");
routeCargo.Value=13.5;await Task.Delay(50);
Require(ViewModel.NavigationRouteOptions.StarClassFilter?.OriginalMask==0x807F,"Changing cargo discarded the explicit star-class route filter.");
ViewModel.GalaxyFilter=ViewModel.GalaxyFilter with{Values=new HashSet<string>{"da"}};await Task.Delay(50);
((IInvokeProvider)new ButtonAutomationPeer(copyStar).GetPattern(PatternInterface.Invoke)).Invoke();await Task.Delay(80);
Require(ViewModel.NavigationRouteOptions.StarClassFilter?.OriginalMask==0x807F&&Descendants(routePanel).OfType<TextBlock>().Any(t=>t.Text.Contains("请选择该分组的全部子类")),"A partial white-dwarf group was silently widened for route plotting.");
ViewModel.GalaxyFilter=ViewModel.GalaxyFilter with{Values=new HashSet<string>(GalaxyFilterDefinitions.ScoopableStarClasses)};await Task.Delay(50);
((IInvokeProvider)new ButtonAutomationPeer(copyStar).GetPattern(PatternInterface.Invoke)).Invoke();await Task.Delay(80);
routeCargo.Value=12.5;await Task.Delay(50);
var routeOffset=routeExpander.TransformToVisual((UIElement)sidebarScroll.Content).TransformPoint(new(0,0)).Y;
sidebarScroll.ChangeView(null,Math.Max(0,routeOffset-8),null,true);await Task.Delay(150);
using(await pageMap.FreezeForXamlProbeAsync())await CapturePageAsync(page,Path.Combine(directory,"navigation-route-options.png"));
var chooseStars=Descendants(routePanel).OfType<Button>().Single(c=>c.Content as string=="选择恒星类别…");
MainWindow.AppWindow.Move(new(-30000,-30000));MainWindow.AppWindow.Show(false);await Task.Delay(60);
await CaptureRefinementElementAsync(routePanel,Path.Combine(directory,"navigation-route-panel.png"));
chooseStars.Flyout!.ShowAt(chooseStars);await Task.Delay(100);
await CaptureRefinementElementAsync((FrameworkElement)((Flyout)chooseStars.Flyout).Content,Path.Combine(directory,"navigation-route-star-groups.png"));
chooseStars.Flyout.Hide();MainWindow.AppWindow.Hide();
var mapRouteExpander=Descendants(routePanel).OfType<Expander>().Single(e=>e.Header as string=="其他分类路线筛选");
mapRouteExpander.IsExpanded=true;page.UpdateLayout();await Task.Delay(60);
ViewModel.GalaxyFilter=GalaxyOriginalSettings.Parse("<Root><RealisticView Value='1'/><ColourVisIndex Value='3'/><VisibilityFlags><government><Anarchy Value='1'/><Democracy Value='0'/><Corporate Value='0'/><affectsRoutePlotting Value='1'/></government></VisibilityFlags></Root>",ViewModel.GalaxyFilter).Filter with{Values=new HashSet<string>{"democracy"}};
await Task.Delay(50);
var copyMap=Descendants(routePanel).OfType<Button>().Single(c=>c.Content as string=="采用当前分类筛选");
((IInvokeProvider)new ButtonAutomationPeer(copyMap).GetPattern(PatternInterface.Invoke)).Invoke();await Task.Delay(80);
Require(ViewModel.NavigationRouteOptions.MapFilter is{CategoryId:3} government&&government.SelectedKeys.SequenceEqual(new[]{"democracy"})&&
ViewModel.NavigationRouteOptions.StarClassFilter?.OriginalMask==0x807F,"The current government route selection lost its exact original names or the existing star filter.");
var mapOffset=mapRouteExpander.TransformToVisual((UIElement)sidebarScroll.Content).TransformPoint(new(0,0)).Y;
sidebarScroll.ChangeView(null,Math.Max(0,mapOffset-8),null,true);await Task.Delay(100);
using(await pageMap.FreezeForXamlProbeAsync())await CapturePageAsync(page,Path.Combine(directory,"navigation-route-map-options.png"));
ViewModel.GalaxyFilter=GalaxyOriginalSettings.Parse("<Root><RealisticView Value='1'/><ColourVisIndex Value='7'/><VisibilityFlags><security><Anarchy Value='1'/><Lawless Value='0'/><LowSecurity Value='0'/><affectsRoutePlotting Value='0'/></security></VisibilityFlags></Root>",ViewModel.GalaxyFilter).Filter;
await Task.Delay(50);((IInvokeProvider)new ButtonAutomationPeer(copyMap).GetPattern(PatternInterface.Invoke)).Invoke();await Task.Delay(80);
Require(ViewModel.NavigationRouteOptions.MapFilter?.CategoryId==3&&Descendants(routePanel).OfType<TextBlock>().Any(t=>t.Text.Contains("工具合并了不同")),"Merged public aliases silently widened the original route selection.");
using(await pageMap.FreezeForXamlProbeAsync())await CapturePageAsync(page,Path.Combine(directory,"navigation-route-map-ambiguous.png"));
var savedMap=Descendants(routePanel).OfType<Button>().Single(c=>c.Content as string=="采用游戏保存的分类筛选");
((IInvokeProvider)new ButtonAutomationPeer(savedMap).GetPattern(PatternInterface.Invoke)).Invoke();await Task.Delay(80);
Require(ViewModel.NavigationRouteOptions.MapFilter is{CategoryId:7,AffectsRoutePlotting:false} security&&
security.ExpectedKeys.Count==3&&security.SelectedKeys.SequenceEqual(new[]{"anarchy"}),"Exact saved Anarchy/Lawless identities were merged in route options.");
var chooseMap=Descendants(routePanel).OfType<Button>().Single(c=>c.Content as string=="选择原分类选项…");
MainWindow.AppWindow.Move(new(-30000,-30000));MainWindow.AppWindow.Show(false);await Task.Delay(50);
chooseMap.Flyout!.ShowAt(chooseMap);await Task.Delay(80);
await CaptureRefinementElementAsync((FrameworkElement)((Flyout)chooseMap.Flyout).Content,Path.Combine(directory,"navigation-route-map-groups.png"));
chooseMap.Flyout.Hide();MainWindow.AppWindow.Hide();mapRouteExpander.IsExpanded=false;
}
finally
{
routePanel.CargoCapacity=previousCargoCapacity;ViewModel.NavigationRouteOptions=previousRouteOptions;
ViewModel.GalaxyFilter=previousRouteFilter;
routeExpander.IsExpanded=previousRouteExpanded;sidebar.IsExpanded=previousSidebarExpanded;page.UpdateLayout();
sidebarScroll.ChangeView(null,previousSidebarOffset,null,true);
}
var idleFrame=pageMap.FrameCount;await Task.Delay(150);var settledFrame=pageMap.FrameCount;await Task.Delay(150);
Require(pageMap.FrameCount==settledFrame,"Idle map kept redrawing.");
timings.Sort();
var stateOptions=await RunGalaxyStateOptionsProbeAsync(directory);
return new{source=Path.GetFullPath(source),recordedLocalSystems=systems.Length,localVisible,filteredGVisible=filtered,
renderer=map.MapGraphicsBackend,keyboardMovement=true,originalInputGainsAndSigns=true,homePreservesAnglesAndClampsDistance=true,homeSourceFallbackExplicit=true,missingHomeSourceDoesNotInventCentre=true,orbit=true,orbitFocusIndependentOfSelection=true,originalPerTickSmoothing=true,targetActualPoseSeparated=true,releasedCraneSettlesTargetOnly=true,motionTimerConverges=true,reentrantFocusCancelsOldMotion=true,originalMouseChords=true,craneUsesWorldY=true,bothButtonsUseXZ=true,chordChangeCancelsHoldAndClick=true,floorSelector=true,clickDoesNotSubmit=true,holdSubmissions=submissions,emptyFilterClearsStars=true,gridSwitch=true,
layerSwitches=new{labelsOn,linksOn,routeOn,markersChangePixels=true,disabledOverlaysEmitNoGeometry=true,originalBackgroundPresent,
originalNebulaBackgroundPresent,originalAuthoredBackgroundPresent,backgroundToggleChecked=originalBackgroundPresent},
localBackgroundState,
originalSettingsImport=new{importedOptions,importedGroups,originalFilesUnchanged},
filterPanelLayout=new{filterScrollableHeight,filterVerticalOffset,canReachLowerControls=true},
displayCheckStates,
originalPowerStateMaskPresentation=new{syntheticMasksOnly=true,mixedStateCount,disabledMaskShowsAll=true,enabledEmptyMaskShowsNone=true},
routeOptionsPanelFixture=true,
routeStarClassFixture=new{exactScoopableMask=0x807F,partialGroupsRejected=true,otherOptionsPreserveStarClasses=true,gameCommandsInvoked=false},
routeMapFilterFixture=new{exactOriginalNames=true,governmentSelection=true,independentAnarchyLawless=true,mergedAliasesRejected=true,starFilterPreserved=true,gameCommandsInvoked=false},
stateOptions,
nativeCoreVisible=map.VisibleStars,meanCpuMilliseconds=timings.Count>0?timings.Average():0,p95CpuMilliseconds=timings.Count>0?timings[(int)(timings.Count*.95)]:0,
idleStopsRendering=pageMap.FrameCount==settledFrame,filterPanelPresent=filters is not null,gameCommandsInvoked=false,generatedCatalogueCoordinates=false};
}
}