using XFEEDToolBox.Core.Galaxy;
using XFEEDToolBox.Core.Navigation;
using CommunityToolkit.Mvvm.Input;
namespace XFEEDToolBox.ViewModels;
public partial class ToolboxViewModel
{
private DateTimeOffset galaxyPowerOptionsReadAt;
private string galaxyPowerOptionsContext="";
private string PowerOptionsContext()=>CurrentPlayer.InGame&&runtime.FlightDriver is NativeFlightControlDriver driver?$"{driver.ProcessId}|{CurrentPlayer.CommanderId}|{CurrentPlayer.LoadGameAt:O}":"";
private string galaxyPowerOptionsStatus="原游戏势力定义表尚未连接;不按公开列表次序猜测原编号。";
private void SetGalaxyPowerOptions(IReadOnlyList<GalaxyNativePowerOption> options)
{
if(options.Count==0)galaxyPowerOptionsContext="";
var filter=GalaxyFilter;
var resolved=GalaxyOriginalPowerSelection.WithOptions(filter,options);
if(filter.Category==GalaxyFilterCategory.PowerActivityEligibility&&(options.Count>0||GalaxyQueryChoices.Count==0))
{
var choices=new[]{new GalaxyFilterChoice("__allpowers","全部势力(原活动选项)")}.Concat(options.Select(p=>new GalaxyFilterChoice(GalaxyPowerActivities.ChoiceKey(p.InternalPowerId),p.Name))).ToArray();
if(!GalaxyQueryChoices.SequenceEqual(choices))GalaxyQueryChoices=choices;
}
else if(filter.Category==GalaxyFilterCategory.Power)
{
var choices=GalaxyQueryChoices.Concat(options.Select(p=>new GalaxyFilterChoice(GalaxyMapFilter.Normalize(p.Name),p.Name))).DistinctBy(c=>c.Key).ToArray();
if(!GalaxyQueryChoices.SequenceEqual(choices))GalaxyQueryChoices=choices;
}
if(!ReferenceEquals(filter,resolved))GalaxyFilter=resolved;
LocateGalaxyPowerHeadquartersCommand.NotifyCanExecuteChanged();
}
private async Task ReadGalaxyPowerOptionsAsync(CancellationToken token)
{
if(DateTimeOffset.UtcNow-galaxyPowerOptionsReadAt<TimeSpan.FromSeconds(2))return;galaxyPowerOptionsReadAt=DateTimeOffset.UtcNow;
if(runtime.FlightDriver is not NativeFlightControlDriver{SupportsGalaxyPowerOptions:true} driver||!CurrentPlayer.InGame)
{SetGalaxyPowerOptions([]);galaxyPowerOptionsStatus="原游戏势力定义表尚未连接;原编号保持未知。";return;}
var account=CurrentPlayer.CommanderId;var session=CurrentPlayer.LoadGameAt;
bool Latest()=>account==CurrentPlayer.CommanderId&&session==CurrentPlayer.LoadGameAt&&CurrentPlayer.InGame&&runtime.FlightDriver is NativeFlightControlDriver current&¤t.ProcessId==driver.ProcessId;
try
{
var snapshot=await new NativeGalaxyAccountCatalog(driver.ProcessId).ReadPowerOptionsAsync(token);
token.ThrowIfCancellationRequested();if(!Latest())return;galaxyPowerOptionsContext=PowerOptionsContext();SetGalaxyPowerOptions(snapshot.Available?snapshot.Options:[]);
galaxyPowerOptionsStatus=snapshot.Available?$"原游戏定义表 · {snapshot.Options.Count} 个实际势力;原内部ID、UI索引与颜色分别保留。":"原游戏势力定义表尚未就绪;原编号保持未知。";
}
catch(OperationCanceledException)when(!token.IsCancellationRequested)
{if(Latest()){SetGalaxyPowerOptions([]);galaxyPowerOptionsStatus="原游戏势力定义表读取超时;原编号保持未知。";}}
catch(Exception error)when(error is IOException or TimeoutException or InvalidDataException or InvalidOperationException or System.Text.Json.JsonException or FormatException)
{if(Latest()){SetGalaxyPowerOptions([]);galaxyPowerOptionsStatus="原游戏势力定义表尚未确认:"+error.Message;}}
}
private GalaxyNativePowerOption? SelectedGalaxyPower()
{
if(galaxyPowerOptionsContext.Length==0||galaxyPowerOptionsContext!=PowerOptionsContext())return null;
var filter=GalaxyFilter;
if(filter.UsesPowerOuter||filter.Category==GalaxyFilterCategory.PowerActivityEligibility||filter.UsesPowerActivityCounter)
return !filter.ActivityAllPowers&&filter.ActivityInternalPowerId is {} id?filter.OriginalPowerOptions.FirstOrDefault(p=>p.InternalPowerId==id):null;
if(filter.Category==GalaxyFilterCategory.Power&&filter.Values is {Count:1})
{var candidates=filter.OriginalPowerOptions.Where(p=>filter.Values.Contains(GalaxyMapFilter.Normalize(p.Name))).ToArray();return candidates.Length==1?candidates[0]:null;}
return null;
}
private bool CanLocateGalaxyPowerHeadquarters()=>SelectedGalaxyPower()?.HeadquartersSystemAddress is >0;
[RelayCommand(CanExecute=nameof(CanLocateGalaxyPowerHeadquarters))] private async Task LocateGalaxyPowerHeadquartersAsync()
{
if(SelectedGalaxyPower() is not {HeadquartersSystemAddress:{} address} selected)return;
var context=galaxyPowerOptionsContext;var request=++galaxyMapTargetSelectionVersion;
bool Latest()=>request==galaxyMapTargetSelectionVersion&&context==PowerOptionsContext()&&context==galaxyPowerOptionsContext&&SelectedGalaxyPower() is {} current&¤t.InternalPowerId==selected.InternalPowerId&¤t.HeadquartersSystemAddress==address;
try
{
var system=galaxyCache.Values.FirstOrDefault(s=>s.SystemAddress==address&&s.Position.IsValid&&!string.IsNullOrWhiteSpace(s.Name));
if(system is null)
{
if(runtime.FlightDriver is not NativeFlightControlDriver{SupportsGalaxyResolveAddress:true}||NativeGalaxy() is not {} catalog)
{GalaxyStatus="已读取势力总部地址,尚未连接精确地址解析。";return;}
system=await catalog.ResolveAddressAsync(address,lifetime.Token);
}
if(!Latest())return;if(system.SystemAddress!=address||!system.Position.IsValid)throw new InvalidDataException("总部地址与实际目录记录不一致。");
system=RememberGalaxy(system);GalaxySelection=system;GalaxyCentre=system.Position;PublishGalaxy();GalaxyStatus=selected.Name+" 总部 · "+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())GalaxyStatus="势力总部定位尚未完成:"+error.Message;}
}
}
using XFEEDToolBox.Core.Galaxy;
using XFEEDToolBox.Core.Navigation;
using CommunityToolkit.Mvvm.Input;
namespace XFEEDToolBox.ViewModels;
public partial class ToolboxViewModel
{
private DateTimeOffset galaxyPowerOptionsReadAt;
private string galaxyPowerOptionsContext="";
private string PowerOptionsContext()=>CurrentPlayer.InGame&&runtime.FlightDriver is NativeFlightControlDriver driver?$"{driver.ProcessId}|{CurrentPlayer.CommanderId}|{CurrentPlayer.LoadGameAt:O}":"";
private string galaxyPowerOptionsStatus="原游戏势力定义表尚未连接;不按公开列表次序猜测原编号。";
private void SetGalaxyPowerOptions(IReadOnlyList<GalaxyNativePowerOption> options)
{
if(options.Count==0)galaxyPowerOptionsContext="";
var filter=GalaxyFilter;
var resolved=GalaxyOriginalPowerSelection.WithOptions(filter,options);
if(filter.Category==GalaxyFilterCategory.PowerActivityEligibility&&(options.Count>0||GalaxyQueryChoices.Count==0))
{
var choices=new[]{new GalaxyFilterChoice("__allpowers","全部势力(原活动选项)")}.Concat(options.Select(p=>new GalaxyFilterChoice(GalaxyPowerActivities.ChoiceKey(p.InternalPowerId),p.Name))).ToArray();
if(!GalaxyQueryChoices.SequenceEqual(choices))GalaxyQueryChoices=choices;
}
else if(filter.Category==GalaxyFilterCategory.Power)
{
var choices=GalaxyQueryChoices.Concat(options.Select(p=>new GalaxyFilterChoice(GalaxyMapFilter.Normalize(p.Name),p.Name))).DistinctBy(c=>c.Key).ToArray();
if(!GalaxyQueryChoices.SequenceEqual(choices))GalaxyQueryChoices=choices;
}
if(!ReferenceEquals(filter,resolved))GalaxyFilter=resolved;
LocateGalaxyPowerHeadquartersCommand.NotifyCanExecuteChanged();
}
private async Task ReadGalaxyPowerOptionsAsync(CancellationToken token)
{
if(DateTimeOffset.UtcNow-galaxyPowerOptionsReadAt<TimeSpan.FromSeconds(2))return;galaxyPowerOptionsReadAt=DateTimeOffset.UtcNow;
if(runtime.FlightDriver is not NativeFlightControlDriver{SupportsGalaxyPowerOptions:true} driver||!CurrentPlayer.InGame)
{SetGalaxyPowerOptions([]);galaxyPowerOptionsStatus="原游戏势力定义表尚未连接;原编号保持未知。";return;}
var account=CurrentPlayer.CommanderId;var session=CurrentPlayer.LoadGameAt;
bool Latest()=>account==CurrentPlayer.CommanderId&&session==CurrentPlayer.LoadGameAt&&CurrentPlayer.InGame&&runtime.FlightDriver is NativeFlightControlDriver current&¤t.ProcessId==driver.ProcessId;
try
{
var snapshot=await new NativeGalaxyAccountCatalog(driver.ProcessId).ReadPowerOptionsAsync(token);
token.ThrowIfCancellationRequested();if(!Latest())return;galaxyPowerOptionsContext=PowerOptionsContext();SetGalaxyPowerOptions(snapshot.Available?snapshot.Options:[]);
galaxyPowerOptionsStatus=snapshot.Available?$"原游戏定义表 · {snapshot.Options.Count} 个实际势力;原内部ID、UI索引与颜色分别保留。":"原游戏势力定义表尚未就绪;原编号保持未知。";
}
catch(OperationCanceledException)when(!token.IsCancellationRequested)
{if(Latest()){SetGalaxyPowerOptions([]);galaxyPowerOptionsStatus="原游戏势力定义表读取超时;原编号保持未知。";}}
catch(Exception error)when(error is IOException or TimeoutException or InvalidDataException or InvalidOperationException or System.Text.Json.JsonException or FormatException)
{if(Latest()){SetGalaxyPowerOptions([]);galaxyPowerOptionsStatus="原游戏势力定义表尚未确认:"+error.Message;}}
}
private GalaxyNativePowerOption? SelectedGalaxyPower()
{
if(galaxyPowerOptionsContext.Length==0||galaxyPowerOptionsContext!=PowerOptionsContext())return null;
var filter=GalaxyFilter;
if(filter.UsesPowerOuter||filter.Category==GalaxyFilterCategory.PowerActivityEligibility||filter.UsesPowerActivityCounter)
return !filter.ActivityAllPowers&&filter.ActivityInternalPowerId is {} id?filter.OriginalPowerOptions.FirstOrDefault(p=>p.InternalPowerId==id):null;
if(filter.Category==GalaxyFilterCategory.Power&&filter.Values is {Count:1})
{var candidates=filter.OriginalPowerOptions.Where(p=>filter.Values.Contains(GalaxyMapFilter.Normalize(p.Name))).ToArray();return candidates.Length==1?candidates[0]:null;}
return null;
}
private bool CanLocateGalaxyPowerHeadquarters()=>SelectedGalaxyPower()?.HeadquartersSystemAddress is >0;
[RelayCommand(CanExecute=nameof(CanLocateGalaxyPowerHeadquarters))] private async Task LocateGalaxyPowerHeadquartersAsync()
{
if(SelectedGalaxyPower() is not {HeadquartersSystemAddress:{} address} selected)return;
var context=galaxyPowerOptionsContext;var request=++galaxyMapTargetSelectionVersion;
bool Latest()=>request==galaxyMapTargetSelectionVersion&&context==PowerOptionsContext()&&context==galaxyPowerOptionsContext&&SelectedGalaxyPower() is {} current&¤t.InternalPowerId==selected.InternalPowerId&¤t.HeadquartersSystemAddress==address;
try
{
var system=galaxyCache.Values.FirstOrDefault(s=>s.SystemAddress==address&&s.Position.IsValid&&!string.IsNullOrWhiteSpace(s.Name));
if(system is null)
{
if(runtime.FlightDriver is not NativeFlightControlDriver{SupportsGalaxyResolveAddress:true}||NativeGalaxy() is not {} catalog)
{GalaxyStatus="已读取势力总部地址,尚未连接精确地址解析。";return;}
system=await catalog.ResolveAddressAsync(address,lifetime.Token);
}
if(!Latest())return;if(system.SystemAddress!=address||!system.Position.IsValid)throw new InvalidDataException("总部地址与实际目录记录不一致。");
system=RememberGalaxy(system);GalaxySelection=system;GalaxyCentre=system.Position;PublishGalaxy();GalaxyStatus=selected.Name+" 总部 · "+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())GalaxyStatus="势力总部定位尚未完成:"+error.Message;}
}
}