using XFEEDToolBox.Core.Localization;
namespace XFEEDToolBox.Core.Models;
public sealed record EngineeringModifier(string Label, double? Value, double? OriginalValue, bool LessIsGood, string ValueText = "")
{
public string Display => ValueText.Length > 0 ? $"{ChineseNames.Translate(Label)}: {ChineseNames.Value(ValueText)}" : $"{ChineseNames.Translate(Label)}: {OriginalValue:G5} → {Value:G5}";
public string EnglishDisplay => ValueText.Length > 0 ? $"{ChineseNames.English(Label)}: {ChineseNames.English(ValueText)}" : $"{ChineseNames.English(Label)}: {OriginalValue:G5} → {Value:G5}";
}
public sealed record ModuleEngineering
{
public string Engineer { get; init; } = "";
public string Blueprint { get; init; } = "";
public int Level { get; init; }
public double? Quality { get; init; }
public string ExperimentalEffect { get; init; } = "";
public string ExperimentalEffectId { get; init; } = "";
public IReadOnlyList<EngineeringModifier> Modifiers { get; init; } = [];
private string EffectKey=>ExperimentalEffectId.Length>0?ExperimentalEffectId:ExperimentalEffect;
public string Summary => $"{ChineseNames.Translate(Blueprint)} · G{Level}" + (EffectKey.Length > 0 ? " · " + ChineseNames.Translate(EffectKey) : "");
public string EnglishSummary => $"{ChineseNames.English(Blueprint)} · G{Level}" + (EffectKey.Length > 0 ? " · " + ChineseNames.English(EffectKey) : "");
}
public sealed record FittedModule
{
public string Slot { get; init; } = "";
public string Item { get; init; } = "";
public string Name { get; init; } = "";
public bool Enabled { get; init; }
public int Priority { get; init; }
public double? Health { get; init; }
public long? Value { get; init; }
public int? AmmoInClip { get; init; }
public int? AmmoInHopper { get; init; }
public ModuleEngineering? Engineering { get; init; }
public string State => $"{(Enabled ? "启用" : "关闭")} · 优先级 {Priority + 1}";
public string HealthText => Health is { } h ? h.ToString("P1") : "未记录";
public string EngineeringText => Engineering?.Summary ?? "无工程改造记录";
public string ModifierText => Engineering is null ? "" : string.Join("\n", Engineering.Modifiers.Select(x => x.Display));
public string DisplayName => ChineseNames.Module(Item,Name);
public string OriginalName => ChineseNames.ModuleEnglish(Item,Name);
public string SlotName => ChineseNames.Slot(Slot);
public string SlotOriginal => ChineseNames.SlotEnglish(Slot);
public string EngineeringOriginal => Engineering?.EnglishSummary ?? "Unmodified";
public string AmmoText => AmmoInClip is null && AmmoInHopper is null ? "—" : $"{AmmoInClip?.ToString() ?? "?"} / {AmmoInHopper?.ToString() ?? "?"}";
}
public sealed record ShipRecord
{
public long ShipId { get; init; }
public string Type { get; init; } = "";
public string Name { get; init; } = "";
public string Ident { get; init; } = "";
public string SystemName { get; init; } = "";
public long? MarketId { get; init; }
public bool Hot { get; init; }
public bool InTransit { get; init; }
public long? Value { get; init; }
public long? TransferPrice { get; init; }
public int? TransferSeconds { get; init; }
public int? CargoCapacity { get; init; }
public double? UnladenMass { get; init; }
public double? MaxJumpRange { get; init; }
public double? FuelMain { get; init; }
public double? FuelReserve { get; init; }
public double? HullHealth { get; init; }
public DateTimeOffset? HullHealthAt { get; init; }
public decimal? Rebuy { get; init; }
public DateTimeOffset? ConfigurationAt { get; init; }
public bool ConfigurationChanged { get; init; }
public DateTimeOffset LastSeen { get; init; }
public IReadOnlyList<FittedModule> Modules { get; init; } = [];
public string DisplayName => string.IsNullOrWhiteSpace(Name) ? $"{ChineseNames.Ship(Type)} · #{ShipId}" : $"{Name} · {ChineseNames.Ship(Type)}";
public string OriginalName => ChineseNames.ShipEnglish(Type);
public string Location => SystemName.Length > 0 ? SystemName : "位置未记录";
public string ConfigurationStatus => ConfigurationAt == null ? "未读取装配" : ConfigurationChanged ? "装配已变化 · 等待完整快照" : $"{Modules.Count} 个模块 · {CommodityQuote.FormatAge(DateTimeOffset.UtcNow - ConfigurationAt.Value)}";
}
public sealed record StoredModule
{
public string Name { get; init; } = "";
public string Item { get; init; } = "";
public long StorageSlot { get; init; }
public string SystemName { get; init; } = "";
public long MarketId { get; init; }
public long BuyPrice { get; init; }
public long TransferCost { get; init; }
public int TransferTime { get; init; }
public bool Hot { get; init; }
public bool InTransit { get; init; }
public string Engineering { get; init; } = "";
public int? EngineeringLevel { get; init; }
public double? EngineeringQuality { get; init; }
public DateTimeOffset ObservedAt { get; init; }
public string TransferText => InTransit ? "运输中" : $"转运 {TransferCost:N0} Cr · {TimeSpan.FromSeconds(TransferTime):g}";
public string EngineeringText => Engineering.Length > 0 ? $"{ChineseNames.Translate(Engineering)} · G{EngineeringLevel?.ToString() ?? "?"}" : "无工程记录";
public string EngineeringOriginal => Engineering.Length>0?$"{ChineseNames.English(Engineering)} · G{EngineeringLevel?.ToString()??"?"}":"Unmodified";
}
public sealed record ShipStatus(long Flags, long Flags2, double? FuelMain, double? FuelReserve, double? Cargo, double? Latitude, double? Longitude, double? Altitude, double? Heading, IReadOnlyList<int> Pips)
{
public string FuelText => $"主油箱 {FuelMain?.ToString("F2") ?? "—"} t · 备用 {FuelReserve?.ToString("F2") ?? "—"} t";
public string PipsText => Pips.Count == 3 ? $"系统 {Pips[0] / 2.0:g} / 引擎 {Pips[1] / 2.0:g} / 武器 {Pips[2] / 2.0:g}" : "电容分配未记录";
}
public sealed record ReadVerificationItem(string Category, string Status, int Count, DateTimeOffset? UpdatedAt, string Source, string Note)
{
public string Updated => UpdatedAt is { } t ? t.ToLocalTime().ToString("MM-dd HH:mm:ss") : "无记录";
}
using XFEEDToolBox.Core.Localization;
namespace XFEEDToolBox.Core.Models;
public sealed record EngineeringModifier(string Label, double? Value, double? OriginalValue, bool LessIsGood, string ValueText = "")
{
public string Display => ValueText.Length > 0 ? $"{ChineseNames.Translate(Label)}: {ChineseNames.Value(ValueText)}" : $"{ChineseNames.Translate(Label)}: {OriginalValue:G5} → {Value:G5}";
public string EnglishDisplay => ValueText.Length > 0 ? $"{ChineseNames.English(Label)}: {ChineseNames.English(ValueText)}" : $"{ChineseNames.English(Label)}: {OriginalValue:G5} → {Value:G5}";
}
public sealed record ModuleEngineering
{
public string Engineer { get; init; } = "";
public string Blueprint { get; init; } = "";
public int Level { get; init; }
public double? Quality { get; init; }
public string ExperimentalEffect { get; init; } = "";
public string ExperimentalEffectId { get; init; } = "";
public IReadOnlyList<EngineeringModifier> Modifiers { get; init; } = [];
private string EffectKey=>ExperimentalEffectId.Length>0?ExperimentalEffectId:ExperimentalEffect;
public string Summary => $"{ChineseNames.Translate(Blueprint)} · G{Level}" + (EffectKey.Length > 0 ? " · " + ChineseNames.Translate(EffectKey) : "");
public string EnglishSummary => $"{ChineseNames.English(Blueprint)} · G{Level}" + (EffectKey.Length > 0 ? " · " + ChineseNames.English(EffectKey) : "");
}
public sealed record FittedModule
{
public string Slot { get; init; } = "";
public string Item { get; init; } = "";
public string Name { get; init; } = "";
public bool Enabled { get; init; }
public int Priority { get; init; }
public double? Health { get; init; }
public long? Value { get; init; }
public int? AmmoInClip { get; init; }
public int? AmmoInHopper { get; init; }
public ModuleEngineering? Engineering { get; init; }
public string State => $"{(Enabled ? "启用" : "关闭")} · 优先级 {Priority + 1}";
public string HealthText => Health is { } h ? h.ToString("P1") : "未记录";
public string EngineeringText => Engineering?.Summary ?? "无工程改造记录";
public string ModifierText => Engineering is null ? "" : string.Join("\n", Engineering.Modifiers.Select(x => x.Display));
public string DisplayName => ChineseNames.Module(Item,Name);
public string OriginalName => ChineseNames.ModuleEnglish(Item,Name);
public string SlotName => ChineseNames.Slot(Slot);
public string SlotOriginal => ChineseNames.SlotEnglish(Slot);
public string EngineeringOriginal => Engineering?.EnglishSummary ?? "Unmodified";
public string AmmoText => AmmoInClip is null && AmmoInHopper is null ? "—" : $"{AmmoInClip?.ToString() ?? "?"} / {AmmoInHopper?.ToString() ?? "?"}";
}
public sealed record ShipRecord
{
public long ShipId { get; init; }
public string Type { get; init; } = "";
public string Name { get; init; } = "";
public string Ident { get; init; } = "";
public string SystemName { get; init; } = "";
public long? MarketId { get; init; }
public bool Hot { get; init; }
public bool InTransit { get; init; }
public long? Value { get; init; }
public long? TransferPrice { get; init; }
public int? TransferSeconds { get; init; }
public int? CargoCapacity { get; init; }
public double? UnladenMass { get; init; }
public double? MaxJumpRange { get; init; }
public double? FuelMain { get; init; }
public double? FuelReserve { get; init; }
public double? HullHealth { get; init; }
public DateTimeOffset? HullHealthAt { get; init; }
public decimal? Rebuy { get; init; }
public DateTimeOffset? ConfigurationAt { get; init; }
public bool ConfigurationChanged { get; init; }
public DateTimeOffset LastSeen { get; init; }
public IReadOnlyList<FittedModule> Modules { get; init; } = [];
public string DisplayName => string.IsNullOrWhiteSpace(Name) ? $"{ChineseNames.Ship(Type)} · #{ShipId}" : $"{Name} · {ChineseNames.Ship(Type)}";
public string OriginalName => ChineseNames.ShipEnglish(Type);
public string Location => SystemName.Length > 0 ? SystemName : "位置未记录";
public string ConfigurationStatus => ConfigurationAt == null ? "未读取装配" : ConfigurationChanged ? "装配已变化 · 等待完整快照" : $"{Modules.Count} 个模块 · {CommodityQuote.FormatAge(DateTimeOffset.UtcNow - ConfigurationAt.Value)}";
}
public sealed record StoredModule
{
public string Name { get; init; } = "";
public string Item { get; init; } = "";
public long StorageSlot { get; init; }
public string SystemName { get; init; } = "";
public long MarketId { get; init; }
public long BuyPrice { get; init; }
public long TransferCost { get; init; }
public int TransferTime { get; init; }
public bool Hot { get; init; }
public bool InTransit { get; init; }
public string Engineering { get; init; } = "";
public int? EngineeringLevel { get; init; }
public double? EngineeringQuality { get; init; }
public DateTimeOffset ObservedAt { get; init; }
public string TransferText => InTransit ? "运输中" : $"转运 {TransferCost:N0} Cr · {TimeSpan.FromSeconds(TransferTime):g}";
public string EngineeringText => Engineering.Length > 0 ? $"{ChineseNames.Translate(Engineering)} · G{EngineeringLevel?.ToString() ?? "?"}" : "无工程记录";
public string EngineeringOriginal => Engineering.Length>0?$"{ChineseNames.English(Engineering)} · G{EngineeringLevel?.ToString()??"?"}":"Unmodified";
}
public sealed record ShipStatus(long Flags, long Flags2, double? FuelMain, double? FuelReserve, double? Cargo, double? Latitude, double? Longitude, double? Altitude, double? Heading, IReadOnlyList<int> Pips)
{
public string FuelText => $"主油箱 {FuelMain?.ToString("F2") ?? "—"} t · 备用 {FuelReserve?.ToString("F2") ?? "—"} t";
public string PipsText => Pips.Count == 3 ? $"系统 {Pips[0] / 2.0:g} / 引擎 {Pips[1] / 2.0:g} / 武器 {Pips[2] / 2.0:g}" : "电容分配未记录";
}
public sealed record ReadVerificationItem(string Category, string Status, int Count, DateTimeOffset? UpdatedAt, string Source, string Note)
{
public string Updated => UpdatedAt is { } t ? t.ToLocalTime().ToString("MM-dd HH:mm:ss") : "无记录";
}