2
0
mirror of https://github.com/9ParsonsB/Pulsar.git synced 2025-04-05 17:39:39 -04:00

Implement Other state events

now emitted to websocket connections on connect
This commit is contained in:
Ben Parsons 2024-05-25 22:49:08 +10:00
parent 68eff73dbd
commit 7eae5e5ee6
68 changed files with 222 additions and 182 deletions

View File

@ -13,17 +13,17 @@ public class BackpackFile : JournalBase
/// <summary>
/// List of all items carried.
/// </summary>
public IReadOnlyCollection<BackpackItem> Items { get; init; }
public List<BackpackItem> Items { get; init; }
/// <summary>
/// List of all components carried.
/// </summary>
public IReadOnlyCollection<BackpackItem> Components { get; init; }
public List<BackpackItem> Components { get; init; }
/// <summary>
/// List of player consumable items carried.
/// </summary>
public IReadOnlyCollection<BackpackItem> Consumables { get; init; }
public List<BackpackItem> Consumables { get; init; }
/// <summary>
/// List of all data currently stored by the player.
/// </summary>
public IReadOnlyCollection<BackpackItem> Data { get; init; }
public List<BackpackItem> Data { get; init; }
}

View File

@ -21,5 +21,5 @@ public class CargoFile : JournalBase
/// <summary>
/// List of full cargo details.
/// </summary>
public IReadOnlyCollection<CargoType> Inventory { get; init; }
public List<CargoType> Inventory { get; init; }
}

View File

@ -9,9 +9,9 @@ namespace Observatory.Framework.Files.Converters;
/// The format used for materials changed from an object with a key for each material to an array of objects containing "name" and "percent".
/// Need to handle both if we're going to read historical data. This reads the old format into a class reflecting the new structure.
/// </summary>
public class MaterialCompositionConverter : JsonConverter<IReadOnlyCollection<MaterialComposition>>
public class MaterialCompositionConverter : JsonConverter<List<MaterialComposition>>
{
public override IReadOnlyCollection<MaterialComposition> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
public override List<MaterialComposition> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.StartObject)
{
@ -42,10 +42,10 @@ public class MaterialCompositionConverter : JsonConverter<IReadOnlyCollection<Ma
return materialComposition;
}
return JsonSerializer.Deserialize<IReadOnlyCollection<MaterialComposition>>(ref reader, options)!;
return JsonSerializer.Deserialize<List<MaterialComposition>>(ref reader, options)!;
}
public override void Write(Utf8JsonWriter writer, IReadOnlyCollection<MaterialComposition> value,
public override void Write(Utf8JsonWriter writer, List<MaterialComposition> value,
JsonSerializerOptions options)
{
JsonSerializer.Serialize(writer, value, options);

View File

@ -9,9 +9,9 @@ namespace Observatory.Framework.Files.Converters;
/// The format used for materials changed from an object with a key for each material to an array of objects containing "name" and "percent".
/// Need to handle both if we're going to read historical data. This reads the old format into a class reflecting the new structure.
/// </summary>
public class MaterialConverter : JsonConverter<IReadOnlyCollection<Material>>
public class MaterialConverter : JsonConverter<List<Material>>
{
public override IReadOnlyCollection<Material> Read(ref Utf8JsonReader reader, Type typeToConvert,
public override List<Material> Read(ref Utf8JsonReader reader, Type typeToConvert,
JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.StartObject)
@ -44,10 +44,10 @@ public class MaterialConverter : JsonConverter<IReadOnlyCollection<Material>>
return materialComposition;
}
return JsonSerializer.Deserialize<IReadOnlyCollection<Material>>(ref reader, options)!;
return JsonSerializer.Deserialize<List<Material>>(ref reader, options)!;
}
public override void Write(Utf8JsonWriter writer, IReadOnlyCollection<Material> value, JsonSerializerOptions options)
public override void Write(Utf8JsonWriter writer, List<Material> value, JsonSerializerOptions options)
{
JsonSerializer.Serialize(writer, value, options);
}

View File

@ -13,5 +13,5 @@ public class FCMaterialsFile : JournalBase
/// <summary>
/// List of items in stock and in demand from the carrier bartender.
/// </summary>
public IReadOnlyCollection<FCMaterial> Items { get; init; }
public List<FCMaterial> Items { get; init; }
}

View File

@ -6,7 +6,7 @@ namespace Observatory.Framework.Files.Journal.Combat;
public class Bounty : JournalBase
{
public override string Event => "Bounty";
public IReadOnlyCollection<Rewards> Rewards { get; init; }
public List<Rewards> Rewards { get; init; }
public string PilotName { get; set; }
public string PilotName_Localised { get; set; }
public string Target { get; init; }

View File

@ -10,5 +10,5 @@ public class Died : JournalBase
public string KillerName_Localised { get; init; }
public string KillerShip { get; init; }
public string KillerRank { get; init; }
public IReadOnlyCollection<Killer> Killers { get; init; }
public List<Killer> Killers { get; init; }
}

View File

@ -71,7 +71,7 @@ public class CodexEntry : JournalBase
/// <summary>
/// List of trais of the scanned item.
/// </summary>
public ICollection<string> Traits { get; init; }
public IList<string> Traits { get; init; }
/// <summary>
/// Value of the codex entry when sold to Universal Cartographics.
/// </summary>

View File

@ -12,7 +12,7 @@ public class MultiSellExplorationData : JournalBase
/// <summary>
/// List of all sold first discoveries.
/// </summary>
public IReadOnlyCollection<Discovered> Discovered { get; init; }
public List<Discovered> Discovered { get; init; }
/// <summary>
/// Base value of total sold data.
/// </summary>

View File

@ -23,11 +23,11 @@ public class SAAScanComplete : JournalBase
/// <summary>
/// This property is indicated with strikethrough in Frontier's documentation and is likely unused.
/// </summary>
public ICollection<string> Discoverers { get; init; }
public IList<string> Discoverers { get; init; }
/// <summary>
/// This property is indicated with strikethrough in Frontier's documentation and is likely unused.
/// </summary>
public ICollection<string> Mappers { get; init; }
public IList<string> Mappers { get; init; }
/// <summary>
/// Number of probes fired to complete the surface scan.
/// </summary>

View File

@ -24,9 +24,9 @@ public class SAASignalsFound : JournalBase
/// <summary>
/// List of signals found.
/// </summary>
public IReadOnlyCollection<Signal> Signals { get; init; }
public List<Signal> Signals { get; init; }
/// <summary>
/// List of genuses present.
/// </summary>
public IReadOnlyCollection<GenusType> Genuses { get; init; }
public List<GenusType> Genuses { get; init; }
}

View File

@ -22,7 +22,7 @@ public class Scan : ScanBaryCentre
/// <summary>
/// List which reflects Frontier's JSON structure for the "Parents" object. Use of Parent property is recommended instead.
/// </summary>
public IReadOnlyCollection<Parent> Parents {
public List<Parent> Parents {
get => _Parents;
init
{
@ -51,8 +51,8 @@ public class Scan : ScanBaryCentre
/// "Parents" object rearranged into more intuitive structure for ease of use.
/// </summary>
[JsonIgnore]
public IReadOnlyCollection<(ParentType ParentType, int Body)> Parent { get; init; }
private IReadOnlyCollection<Parent> _Parents;
public List<(ParentType ParentType, int Body)> Parent { get; init; }
private List<Parent> _Parents;
/// <summary>
/// Body distance from system arrival point in light-seconds.
/// </summary>
@ -80,7 +80,7 @@ public class Scan : ScanBaryCentre
/// <summary>
/// List containing full breakdown of atmospheric components and their relative percentages.
/// </summary>
public IReadOnlyCollection<MaterialComposition> AtmosphereComposition { get; init; }
public List<MaterialComposition> AtmosphereComposition { get; init; }
/// <summary>
/// Descriptive string for type of volcanism present, or an empty string for none, e.g. "major silicate vapour geysers volcanism".
/// </summary>
@ -113,7 +113,7 @@ public class Scan : ScanBaryCentre
/// List containing full breakdown of prospectable surface materials and their relative percentages.
/// </summary>
[JsonConverter(typeof(MaterialCompositionConverter))]
public IReadOnlyCollection<MaterialComposition> Materials { get; init; }
public List<MaterialComposition> Materials { get; init; }
/// <summary>
/// Overall composition of body, expressed as percentages of ice, rock, and metal.
/// </summary>
@ -130,7 +130,7 @@ public class Scan : ScanBaryCentre
/// <summary>
/// List of all planetary or stellar ring systems around the body.
/// </summary>
public IReadOnlyCollection<Ring> Rings { get; init; }
public List<Ring> Rings { get; init; }
/// <summary>
/// Description of the minable material abundance.<br/>Possible values inclue "PristineResources", "MajorResources", "CommonResources", "LowResources", and "DepletedResources".
/// </summary>

View File

@ -11,11 +11,11 @@ public class SellExplorationData : JournalBase
/// <summary>
/// List of systems for which data was sold.
/// </summary>
public ICollection<string> Systems { get; init; }
public IList<string> Systems { get; init; }
/// <summary>
/// List of first discovered bodies.
/// </summary>
public ICollection<string> Discovered { get; init; }
public IList<string> Discovered { get; init; }
/// <summary>
/// Base value of sold data.
/// </summary>

View File

@ -24,5 +24,5 @@ public class CarrierJump : FSDJump
public StationService StationServices { get; init; }
public string StationEconomy { get; init; }
public string StationEconomy_Localised { get; init; }
public IReadOnlyCollection<StationEconomy> StationEconomies { get; init; }
public List<StationEconomy> StationEconomies { get; init; }
}

View File

@ -19,7 +19,7 @@ public class CarrierStats : JournalBase
public bool PendingDecommission { get; init; }
public CarrierSpaceUsage SpaceUsage { get; init; }
public ParameterTypes.CarrierFinance Finance { get; init; }
public IReadOnlyCollection<CarrierCrew> Crew { get; init; }
public IReadOnlyCollection<CarrierPack> ShipPacks { get; init; }
public IReadOnlyCollection<CarrierPack> ModulePacks { get; init; }
public List<CarrierCrew> Crew { get; init; }
public List<CarrierPack> ShipPacks { get; init; }
public List<CarrierPack> ModulePacks { get; init; }
}

View File

@ -6,6 +6,6 @@ namespace Observatory.Framework.Files.Journal.Odyssey;
public class BackpackChange : JournalBase
{
public override string Event => "BackpackChange";
public IReadOnlyCollection<BackpackItemChange> Added { get; init; }
public IReadOnlyCollection<BackpackItemChange> Removed { get; init; }
public List<BackpackItemChange> Added { get; init; }
public List<BackpackItemChange> Removed { get; init; }
}

View File

@ -6,8 +6,8 @@ namespace Observatory.Framework.Files.Journal.Odyssey;
public class BackpackMaterials : JournalBase
{
public override string Event => "BackpackMaterials";
public IReadOnlyCollection<BackpackItem> Items { get; init; }
public IReadOnlyCollection<BackpackItem> Components { get; init; }
public IReadOnlyCollection<BackpackItem> Consumables { get; init; }
public IReadOnlyCollection<BackpackItem> Data { get; init; }
public List<BackpackItem> Items { get; init; }
public List<BackpackItem> Components { get; init; }
public List<BackpackItem> Consumables { get; init; }
public List<BackpackItem> Data { get; init; }
}

View File

@ -15,5 +15,5 @@ public class BuyMicroResources : JournalBase
public int Price { get; init; }
public ulong MarketID { get; init; }
public int TotalCount { get; init; }
public IReadOnlyCollection<MicroResource> MicroResources { get; init; }
public List<MicroResource> MicroResources { get; init; }
}

View File

@ -6,6 +6,6 @@ namespace Observatory.Framework.Files.Journal.Odyssey;
public class CreateSuitLoadout : DeleteSuitLoadout
{
public override string Event => "CreateSuitLoadout";
public IReadOnlyCollection<SuitModule> Modules { get; init; }
public ICollection<string> SuitMods { get; init; }
public List<SuitModule> Modules { get; init; }
public IList<string> SuitMods { get; init; }
}

View File

@ -6,7 +6,7 @@ namespace Observatory.Framework.Files.Journal.Odyssey;
public class SellMicroResources : JournalBase
{
public override string Event => "SellMicroResources";
public IReadOnlyCollection<MicroResource> MicroResources { get; init; }
public List<MicroResource> MicroResources { get; init; }
public int Price { get; init; }
public ulong MarketID { get; init; }
}

View File

@ -7,5 +7,5 @@ public class SellOrganicData : JournalBase
{
public override string Event => "SellOrganicData";
public ulong MarketID { get; init; }
public IReadOnlyCollection<BioData> BioData { get; init; }
public List<BioData> BioData { get; init; }
}

View File

@ -6,8 +6,8 @@ namespace Observatory.Framework.Files.Journal.Odyssey;
public class ShipLockerMaterials : JournalBase
{
public override string Event => "ShipLockerMaterials";
public IReadOnlyCollection<BackpackItem> Items { get; init; }
public IReadOnlyCollection<BackpackItem> Components { get; init; }
public IReadOnlyCollection<BackpackItem> Consumables { get; init; }
public IReadOnlyCollection<BackpackItem> Data { get; init; }
public List<BackpackItem> Items { get; init; }
public List<BackpackItem> Components { get; init; }
public List<BackpackItem> Consumables { get; init; }
public List<BackpackItem> Data { get; init; }
}

View File

@ -7,7 +7,7 @@ namespace Observatory.Framework.Files.Journal.Odyssey;
public class TradeMicroResources : JournalBase
{
public override string Event => "TradeMicroResources";
public IReadOnlyCollection<MicroResource> Offered { get; init; }
public List<MicroResource> Offered { get; init; }
public string Received { get; init; }
[JsonConverter(typeof(JsonStringEnumConverter))]
public MicroCategory Category { get; init; }

View File

@ -6,5 +6,5 @@ namespace Observatory.Framework.Files.Journal.Odyssey;
public class TransferMicroResources : JournalBase
{
public override string Event => "TransferMicroResources";
public IReadOnlyCollection<MicroTransfer> Transfers { get; init; }
public List<MicroTransfer> Transfers { get; init; }
}

View File

@ -16,7 +16,7 @@ public class ApproachSettlement : JournalBase
public float Longitude { get; init; }
public int BodyID { get; init; }
public string BodyName { get; init; }
public IReadOnlyCollection<StationEconomy> StationEconomies { get; init; }
public List<StationEconomy> StationEconomies { get; init; }
public string StationEconomy { get; init; }
public string StationEconomy_Localised { get; init; }
public Faction StationFaction { get; init; }

View File

@ -6,5 +6,5 @@ namespace Observatory.Framework.Files.Journal.Other;
public class CargoTransfer : JournalBase
{
public override string Event => "CargoTransfer";
public IReadOnlyCollection<CargoTransferDetail> Transfers { get; init; }
public List<CargoTransferDetail> Transfers { get; init; }
}

View File

@ -6,7 +6,7 @@ namespace Observatory.Framework.Files.Journal.Other;
public class ProspectedAsteroid : JournalBase
{
public override string Event => "ProspectedAsteroid";
public IReadOnlyCollection<ProspectMaterial> Materials { get; init; }
public List<ProspectMaterial> Materials { get; init; }
public string Content { get; init; }
public string Content_Localised { get; init; }
public string MotherlodeMaterial { get; init; }

View File

@ -5,5 +5,5 @@ namespace Observatory.Framework.Files.Journal.Other;
public class RebootRepair : JournalBase
{
public override string Event => "RebootRepair";
public ICollection<string> Modules { get; init; }
public IList<string> Modules { get; init; }
}

View File

@ -11,5 +11,5 @@ public class Synthesis : JournalBase
public string Name { get; init; }
[JsonConverter(typeof(MaterialConverter))]
public IReadOnlyCollection<Material> Materials { get; init; }
public List<Material> Materials { get; init; }
}

View File

@ -5,5 +5,5 @@ namespace Observatory.Framework.Files.Journal.Other;
public class WingJoin : JournalBase
{
public override string Event => "WingJoin";
public ICollection<string> Others { get; init; }
public IList<string> Others { get; init; }
}

View File

@ -5,5 +5,5 @@ namespace Observatory.Framework.Files.Journal.Powerplay;
public class PowerplayVoucher : PowerplayJoin
{
public override string Event => "PowerplayVoucher";
public ICollection<string> Systems { get; init; }
public IList<string> Systems { get; init; }
}

View File

@ -8,5 +8,5 @@ public class Cargo : JournalBase
public override string Event => "Cargo";
public string Vessel { get; init; }
public int Count { get; init; }
public IReadOnlyCollection<CargoType> Inventory { get; init; }
public List<CargoType> Inventory { get; init; }
}

View File

@ -19,5 +19,5 @@ public class Loadout : JournalBase
public double MaxJumpRange { get; init; }
public ulong Rebuy { get; init; }
public bool Hot { get; init; }
public IReadOnlyCollection<Modules> Modules { get; init; }
public List<Modules> Modules { get; init; }
}

View File

@ -6,8 +6,8 @@ using ParameterTypes;
public class Materials : JournalBase
{
public override string Event => "Materials";
public virtual IReadOnlyCollection<Material> Raw { get; init; }
public virtual IReadOnlyCollection<Material> Manufactured { get; init; }
public virtual IReadOnlyCollection<Material> Encoded { get; init; }
public virtual List<Material> Raw { get; init; }
public virtual List<Material> Manufactured { get; init; }
public virtual List<Material> Encoded { get; init; }
}

View File

@ -6,7 +6,7 @@ namespace Observatory.Framework.Files.Journal.Startup;
public class Missions : JournalBase
{
public override string Event => "Missions";
public IReadOnlyCollection<Mission> Active { get; init; }
public IReadOnlyCollection<Mission> Failed { get; init; }
public IReadOnlyCollection<Mission> Complete { get; init; }
public List<Mission> Active { get; init; }
public List<Mission> Failed { get; init; }
public List<Mission> Complete { get; init; }
}

View File

@ -6,5 +6,5 @@ namespace Observatory.Framework.Files.Journal.StationServices;
public class CommunityGoal : JournalBase
{
public override string Event => "CommunityGoal";
public IReadOnlyCollection<CurrentGoal> CurrentGoals { get; init; }
public List<CurrentGoal> CurrentGoals { get; init; }
}

View File

@ -21,6 +21,6 @@ public class EngineerCraft : JournalBase
public float Quality { get; init; }
public string ApplyExperimentalEffect { get; init; }
[JsonConverter(typeof(MaterialConverter))]
public IReadOnlyCollection<Material> Ingredients { get; init; }
public IReadOnlyCollection<Modifier> Modifiers { get; init; }
public List<Material> Ingredients { get; init; }
public List<Modifier> Modifiers { get; init; }
}

View File

@ -15,7 +15,7 @@ public class EngineerProgress : JournalBase
[JsonConverter(typeof(JsonStringEnumConverter))]
public Progress? Progress { get; set; }
public IReadOnlyCollection<EngineerType> Engineers { get; set; }
public List<EngineerType> Engineers { get; set; }
}
//{ "timestamp":"2024-05-25T04:44:34Z", "event":"EngineerProgress",
//"Engineers":[

View File

@ -9,5 +9,5 @@ public class MassModuleStore : JournalBase
public ulong MarketID { get; init; }
public string Ship { get; init; }
public ulong ShipID { get; init; }
public IReadOnlyCollection<Item> Items { get; init; }
public List<Item> Items { get; init; }
}

View File

@ -23,9 +23,9 @@ public class MissionCompleted : JournalBase
[JsonConverter(typeof(StringIntConverter))]
public int Donation { get; init; }
public long Donated { get; init; }
public ICollection<string> PermitsAwarded { get; init; }
public IReadOnlyCollection<CommodityReward> CommodityReward { get; init; }
public IReadOnlyCollection<MaterialReward> MaterialsReward { get; init; }
public IList<string> PermitsAwarded { get; init; }
public List<CommodityReward> CommodityReward { get; init; }
public List<MaterialReward> MaterialsReward { get; init; }
public string DestinationSystem { get; init; }
public string DestinationStation { get; init; }
public string DestinationSettlement { get; init; }
@ -33,5 +33,5 @@ public class MissionCompleted : JournalBase
public string NewDestinationStation { get; init; }
public int KillCount { get; init; }
public string TargetFaction { get; init; }
public IReadOnlyCollection<FactionEffect> FactionEffects { get; init; }
public List<FactionEffect> FactionEffects { get; init; }
}

View File

@ -13,6 +13,6 @@ public class RedeemVoucher : JournalBase
public long Amount { get; init; }
public string Faction { get; init; }
public float BrokerPercentage { get; init; }
public IReadOnlyCollection<VoucherFaction> Factions { get; init; }
public List<VoucherFaction> Factions { get; init; }
}

View File

@ -7,5 +7,5 @@ public class Repair : JournalBase
public override string Event => "Repair";
public string Item { get; init; }
public int Cost { get; init; }
public ICollection<string> Items { get; init; }
public IList<string> Items { get; init; }
}

View File

@ -12,5 +12,5 @@ public class StoredModules : JournalBase
/// </summary>
public string StationName { get; init; }
public ulong MarketID { get; init; }
public IReadOnlyCollection<StoredItem> Items { get; init; }
public List<StoredItem> Items { get; init; }
}

View File

@ -12,6 +12,6 @@ public class StoredShips : JournalBase
/// </summary>
public string StationName { get; init; }
public string StarSystem { get; init; }
public IReadOnlyCollection<StoredShip> ShipsHere { get; init; }
public IReadOnlyCollection<StoredShip> ShipsRemote { get; init; }
public List<StoredShip> ShipsHere { get; init; }
public List<StoredShip> ShipsRemote { get; init; }
}

View File

@ -8,7 +8,7 @@ public class TechnologyBroker : JournalBase
public override string Event => "TechnologyBroker";
public string BrokerType { get; init; }
public ulong MarketID { get; init; }
public IReadOnlyCollection<ItemName> ItemsUnlocked { get; init; }
public IReadOnlyCollection<CommodityReward> Commodities { get; init; }
public IReadOnlyCollection<MaterialReward> Materials { get; init; }
public List<ItemName> ItemsUnlocked { get; init; }
public List<CommodityReward> Commodities { get; init; }
public List<MaterialReward> Materials { get; init; }
}

View File

@ -81,7 +81,7 @@ public class Docked : JournalBase
private get => StationEconomy_Localised;
init => StationEconomy_Localised = value;
}
public IReadOnlyCollection<StationEconomy> StationEconomies { get; init; }
public List<StationEconomy> StationEconomies { get; init; }
[Obsolete("StationState is a rundundant property. Use StationEconomy to potentially reduce unnecessary checks.")]
public string StationState { get; init; }

View File

@ -33,9 +33,9 @@ public class FSDJump : JournalBase
public string SystemSecurity_Localised { get; init; }
public long Population { get; init; }
public bool Wanted { get; init; }
public IReadOnlyCollection<SystemFaction> Factions { get; init; }
public IReadOnlyCollection<Conflict> Conflicts { get; init; }
public ICollection<string> Powers { get; init; }
public List<SystemFaction> Factions { get; init; }
public List<Conflict> Conflicts { get; init; }
public IList<string> Powers { get; init; }
public string PowerplayState { get; init; }
public bool Taxi { get; init; }
public bool Multicrew { get; init; }

View File

@ -30,10 +30,10 @@ public class Location : JournalBase
public string StationGovernment { get; init; }
public string StationGovernment_Localised { get; init; }
public string StationAllegiance { get; init; }
public ICollection<string> StationServices { get; init; }
public IList<string> StationServices { get; init; }
public string StationEconomy { get; init; }
public string StationEconomy_Localised { get; init; }
public IReadOnlyCollection<StationEconomy> StationEconomies { get; init; }
public List<StationEconomy> StationEconomies { get; init; }
public string StarSystem { get; init; }
public ulong SystemAddress { get; init; }
@ -53,13 +53,13 @@ public class Location : JournalBase
public string Body { get; init; }
public int BodyID { get; init; }
public string BodyType { get; init; }
public IReadOnlyCollection<DetailedFaction> Factions { get; init; }
public List<DetailedFaction> Factions { get; init; }
[JsonConverter(typeof(LegacyFactionConverter<DetailedFaction>))]
public DetailedFaction SystemFaction { get; init; }
public IReadOnlyCollection<Conflict> Conflicts { get; init; }
public ICollection<string> Powers { get; init; }
public List<Conflict> Conflicts { get; init; }
public IList<string> Powers { get; init; }
public string PowerplayState { get; init; }
public bool Taxi { get; init; }
public bool Multicrew { get; init; }

View File

@ -29,5 +29,5 @@ public class MarketFile : JournalBase
/// <summary>
/// List of all commodities available in the market.
/// </summary>
public IReadOnlyCollection<MarketItem> Items { get; init; }
public List<MarketItem> Items { get; init; }
}

View File

@ -13,5 +13,5 @@ public class ModuleInfoFile : JournalBase
/// <summary>
/// List of all equipped modules.
/// </summary>
public IReadOnlyCollection<Module> Modules { get; init; }
public List<Module> Modules { get; init; }
}

View File

@ -13,5 +13,5 @@ public class NavRouteFile : JournalBase
/// <summary>
/// List of star systems and their locations in the current route.
/// </summary>
public IReadOnlyCollection<Route> Route { get; init; }
public List<Route> Route { get; init; }
}

View File

@ -29,5 +29,5 @@ public class OutfittingFile : JournalBase
/// <summary>
/// List of all available parts in shipyard.
/// </summary>
public IReadOnlyCollection<OutfittingModule> Items { get; init; }
public List<OutfittingModule> Items { get; init; }
}

View File

@ -10,6 +10,6 @@ public class DetailedFaction : Faction
public string Happiness { get; init; }
public string Happiness_Localised { get; init; }
public float MyReputation { get; init; }
public IReadOnlyCollection<FactionStateTrend> RecoveringStates { get; init; }
public IReadOnlyCollection<FactionState> ActiveStates { get; init; }
public List<FactionStateTrend> RecoveringStates { get; init; }
public List<FactionState> ActiveStates { get; init; }
}

View File

@ -18,5 +18,5 @@ public class Engineering
public string ExperimentalEffect { get; init; }
public IReadOnlyCollection<Modifiers> Modifiers { get; init; }
public List<Modifiers> Modifiers { get; init; }
}

View File

@ -7,8 +7,8 @@ namespace Observatory.Framework.Files.ParameterTypes;
public class FactionEffect
{
public string Faction { get; init; }
public IReadOnlyCollection<EffectType> Effects { get; init; }
public IReadOnlyCollection<InfluenceType> Influence { get; init; }
public List<EffectType> Effects { get; init; }
public List<InfluenceType> Influence { get; init; }
[JsonConverter(typeof(RepInfConverter))]
public int Reputation { get; init; }
[JsonConverter(typeof(JsonStringEnumConverter))]

View File

@ -8,5 +8,5 @@ public class SuitModule
public string ModuleName { get; init; }
public ulong SuitModuleID { get; init; }
public int Class { get; init; }
public ICollection<string> WeaponMods { get; init; }
public IList<string> WeaponMods { get; init; }
}

View File

@ -14,11 +14,11 @@ public class SystemFaction : Faction
public double MyReputation { get; init; }
public IReadOnlyCollection<FactionStateTrend> PendingStates { get; init; }
public List<FactionStateTrend> PendingStates { get; init; }
public IReadOnlyCollection<FactionStateTrend> RecoveringStates { get; init; }
public List<FactionStateTrend> RecoveringStates { get; init; }
public IReadOnlyCollection<FactionState> ActiveStates { get; init; }
public List<FactionState> ActiveStates { get; init; }
public bool? SquadronFaction { get; init; }

View File

@ -34,5 +34,5 @@ public class ShipyardFile : JournalBase
/// <summary>
/// List of all ships and prices for them at the current shipyard.
/// </summary>
public IReadOnlyCollection<ShipyardPrice> PriceList { get; init; }
public List<ShipyardPrice> PriceList { get; init; }
}

View File

@ -1,9 +1,8 @@
using Microsoft.EntityFrameworkCore;
namespace Pulsar.Context.Configuration;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Observatory.Framework.Files.Journal.Startup;
namespace Pulsar.Context.Configuration;
public class CargoConfiguration : IEntityTypeConfiguration<Cargo>
{
public void Configure(EntityTypeBuilder<Cargo> builder)

View File

@ -1,9 +1,8 @@
using Microsoft.EntityFrameworkCore;
namespace Pulsar.Context.Configuration;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Observatory.Framework.Files.Journal.Odyssey;
namespace Pulsar.Context.Configuration;
public class ShipLockerConfiguration : IEntityTypeConfiguration<ShipLockerMaterials>
{
public void Configure(EntityTypeBuilder<ShipLockerMaterials> builder)

View File

@ -1,12 +1,11 @@
namespace Pulsar.Context;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Observatory.Framework.Files.Journal;
using Observatory.Framework.Files.Journal.Odyssey;
using Observatory.Framework.Files.Journal.Startup;
using Observatory.Framework.Files.Journal.StationServices;
using Observatory.Framework.Files.Journal.Travel;
using Pulsar.Features.ShipLocker;
/// <summary>
/// An in-memory database context for Pulsar.
@ -15,7 +14,6 @@ public class PulsarContext : DbContext
{
public SqliteConnection Connection { get; private set; }
public DbSet<Commander> Commander { get; set; }
public DbSet<Materials> Materials { get; set; }
public DbSet<Rank> Rank { get; set; }

View File

@ -1,5 +1,3 @@
using Pulsar.Features.Journal;
namespace Pulsar.Features;
using Observatory.Framework.Files;
@ -12,6 +10,11 @@ public class EventsHub(IJournalService journalService) : Hub<IEventsHub>
{
await base.OnConnectedAsync();
await Clients.Caller.JournalUpdated(await journalService.GetLastStartupEvents());
var state = await journalService.GetLatestState();
if (state.Any())
{
await Clients.Caller.JournalUpdated(state);
}
}
public async Task Status([FromServices] IStatusService statusService)
@ -30,7 +33,7 @@ public class EventsHub(IJournalService journalService) : Hub<IEventsHub>
public async Task MarketUpdated(MarketFile market) => await Clients.All.MarketUpdated(market);
public async Task JournalUpdated(IReadOnlyCollection<JournalBase> journals) => await Clients.All.JournalUpdated(journals);
public async Task JournalUpdated(List<JournalBase> journals) => await Clients.All.JournalUpdated(journals);
public async Task ModuleInfoUpdated(ModuleInfoFile moduleInfo) => await Clients.All.ModuleInfoUpdated(moduleInfo);
@ -55,7 +58,7 @@ public interface IEventsHub
Task MarketUpdated(MarketFile market);
Task JournalUpdated(IReadOnlyCollection<JournalBase> journals);
Task JournalUpdated(List<JournalBase> journals);
Task ModuleInfoUpdated(ModuleInfoFile moduleInfo);

View File

@ -1,8 +1,8 @@
using System.Collections.Concurrent;
namespace Pulsar.Features;
using Observatory.Framework.Files;
using Observatory.Framework.Files.Journal;
using Observatory.Framework.Files.Journal.Odyssey;
namespace Pulsar.Features;
public interface IFileHandler
{

View File

@ -1,10 +1,9 @@
using Observatory.Framework.Files.Journal.StationServices;
namespace Pulsar.Features.Journal;
using Observatory.Framework;
using Observatory.Framework.Files.Journal;
using Observatory.Framework.Files.Journal.Startup;
using Observatory.Framework.Files.Journal.StationServices;
public class JournalProcessor(
ILogger<JournalProcessor> logger,

View File

@ -1,14 +1,36 @@
using Microsoft.EntityFrameworkCore;
using Observatory.Framework.Files.Journal.Startup;
using Observatory.Framework.Files.Journal.StationServices;
namespace Pulsar.Features.Journal;
using Observatory.Framework.Files.Journal;
public interface IJournalService : IJournalHandler<List<JournalBase>>
{
/// <summary>
/// Gets the Latest of the following (start of game) events:
/// Commander
/// Materials
/// Rank
/// Progress
/// Reputation
/// EngineerProgress
/// LoadGame
/// Statistics
/// </summary>
/// <returns></returns>
Task<List<JournalBase>> GetLastStartupEvents();
/// <summary>
/// Get the Latest of the following events:
/// <p>
/// Location<br/>
/// Powerplay<br/>
/// Music<br/>
/// ShipLocker<br/>
/// Missions<br/>
/// Loadout</p>
/// <p>When there are none of an event since the last game start, no event will be given.</p>
/// </summary>
/// <returns></returns>
Task<List<JournalBase>> GetLatestState();
}
public class JournalService(
@ -31,8 +53,6 @@ public class JournalService(
}
// Start of game events/order:
/** Commander
* Materials
@ -60,45 +80,19 @@ public class JournalService(
// Reputation
// EngineerProgress
// LoadGame
// StateEvents:
// Location
// Powerplay
// Music
// ShipLocker
// Missions
// Loadout
// Cargo
// -- ...
// Statistics
public async Task<List<JournalBase>> GetLastStartupEvents()
{
//TODO: add other state events
var commanderTask = context.Commander.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var materialsTask = context.Materials.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var rankTask = context.Rank.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var progressTask = context.Progress.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var reputationTask = context.Reputation.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var engineerProgressTask = context.EngineerProgress.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var loadGameTask = context.LoadGames.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var statisticsTask = context.Statistics.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var commander = await context.Commander.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var materials = await context.Materials.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var rank = await context.Rank.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var progress = await context.Progress.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var reputation = await context.Reputation.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var engineerProgress = await context.EngineerProgress.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var loadGame = await context.LoadGames.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var statistics = await context.Statistics.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
await Task.WhenAll(
commanderTask,
materialsTask,
rankTask,
progressTask,
reputationTask,
engineerProgressTask,
loadGameTask,
statisticsTask);
var commander = await commanderTask;
var materials = await materialsTask;
var rank = await rankTask;
var progress = await progressTask;
var reputation = await reputationTask;
var engineerProgress = await engineerProgressTask;
var loadGame = await loadGameTask;
var statistics = await statisticsTask;
// if any null, return empty list
if (materials == null || rank == null || progress == null || reputation == null || engineerProgress == null ||
@ -108,20 +102,62 @@ public class JournalService(
}
// dont check the time of statistics as it may occur a few moments after
if (commander.Timestamp != materials.Timestamp ||
materials.Timestamp != rank.Timestamp ||
rank.Timestamp != progress.Timestamp ||
progress.Timestamp != reputation.Timestamp ||
reputation.Timestamp != engineerProgress.Timestamp ||
engineerProgress.Timestamp != loadGame.Timestamp ||
statistics.Timestamp < materials.Timestamp)
if (commander.Timestamp > materials.Timestamp ||
commander.Timestamp > materials.Timestamp ||
commander.Timestamp > rank.Timestamp ||
commander.Timestamp > progress.Timestamp ||
commander.Timestamp > reputation.Timestamp ||
commander.Timestamp > engineerProgress.Timestamp ||
commander.Timestamp > loadGame.Timestamp ||
commander.Timestamp > statistics.Timestamp)
{
throw new InvalidOperationException("Timestamps do not match");
throw new InvalidOperationException("Timestamps are invalid");
}
return [commander, materials, rank, progress, reputation, engineerProgress, loadGame, statistics];
}
/// <summary>
/// StateEvents:
/// Location
/// Powerplay
/// Music
/// ShipLocker
/// Missions
/// Loadout
/// Cargo
/// </summary>
/// <returns></returns>
public async Task<List<JournalBase>> GetLatestState()
{
// dont get anything before the last command timestamp
var commander = await context.Commander.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
if (commander == null) return [];
var location = await context.Locations
.Where(x => x.Timestamp > commander.Timestamp)
.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var powerplay = await context.PowerPlay
.Where(x => x.Timestamp > commander.Timestamp)
.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var shiplocker = await context.ShipLocker
.Where(x => x.Timestamp > commander.Timestamp)
.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var missions = await context.Missions
.Where(x => x.Timestamp > commander.Timestamp)
.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var loadout = await context.Loadout
.Where(x => x.Timestamp > commander.Timestamp)
.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
var cargo = await context.Cargo
.Where(x => x.Timestamp > commander.Timestamp)
.OrderByDescending(x => x.Timestamp).FirstOrDefaultAsync();
return new List<JournalBase?> { location, powerplay, shiplocker, missions, loadout, cargo }
.Where(x => x != null).Cast<JournalBase>().ToList();
}
public async Task<List<JournalBase>> Get()
{
return [];

View File

@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore;
using Observatory.Framework.Files.Journal.Startup;
using Pulsar.Context;
namespace Pulsar.Features.Status;

View File

@ -1,6 +1,9 @@
global using Pulsar;
global using Pulsar.Utils;
global using Pulsar.Context;
global using Pulsar.Features;
global using Pulsar.Features.Status;
global using Pulsar.Features.Journal;
global using System.Text;
global using System.Text.Json;
global using System.Text.Json.Nodes;
@ -8,4 +11,5 @@ global using System.Text.Json.Serialization;
global using Microsoft.AspNetCore.Mvc;
global using Microsoft.AspNetCore.SignalR;
global using Microsoft.Extensions.Options;
global using Microsoft.EntityFrameworkCore;
global using IEventHubContext = Microsoft.AspNetCore.SignalR.IHubContext<Pulsar.Features.EventsHub, Pulsar.Features.IEventsHub>;

View File

@ -1,15 +1,16 @@
using Lamar.Microsoft.DependencyInjection;
using Microsoft.AspNetCore.Cors.Infrastructure;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileProviders;
using Pulsar.Features;
using Pulsar.Features.Journal;
Console.WriteLine((string?)null!);
var builder = WebApplication.CreateBuilder(new WebApplicationOptions()
{
Args = args, WebRootPath = "static", ContentRootPath = "WebApp", ApplicationName = "Pulsar", EnvironmentName =
Args = args,
WebRootPath = "static",
ContentRootPath = "WebApp",
ApplicationName = "Pulsar",
EnvironmentName =
#if DEBUG
"Development"
#else