namespace Pulsar.Features.Journal; using Observatory.Framework.Files.Journal; public interface IJournalService : IJournalHandler> { /// /// Gets the Latest of the following (start of game) events: /// Commander /// Materials /// Rank /// Progress /// Reputation /// EngineerProgress /// LoadGame /// Statistics /// /// Task> GetLastStartupEvents(); /// /// Get the Latest of the following events: ///

/// Location
/// Powerplay
/// Music
/// ShipLocker
/// Missions
/// Loadout

///

When there are none of an event since the last game start, no event will be given.

///
/// Task> GetLatestState(); } public class JournalService( ILogger logger, IJournalStore store, PulsarContext context ) : IJournalService { public string FileName => FileHandlerService.JournalLogFileName; public Task HandleFile(string filePath, CancellationToken token = new()) { if (!FileHelper.ValidateFile(filePath)) { return Task.CompletedTask; } store.EnqueueFile(filePath); return Task.CompletedTask; } // Start of game events/order: /** Commander * Materials Rank Progress Reputation EngineerProgress LoadGame --Some time later-- Statistics -- Game Events (e.g. FSSSignalDiscovered) -- Location Powerplay ShipLocker Missions Loadout Cargo */ // StartupEvents: // Commander // Materials // Rank // Progress // Reputation // EngineerProgress // LoadGame // -- ... // Statistics public async Task> GetLastStartupEvents() { 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(); // if any null, return empty list if (materials == null || rank == null || progress == null || reputation == null || engineerProgress == null || loadGame == null || statistics == null || commander == null) { return []; } // dont check the time of statistics as it may occur a few moments after 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 are invalid"); } return [commander, materials, rank, progress, reputation, engineerProgress, loadGame, statistics]; } /// /// StateEvents: /// Location /// Powerplay /// Music /// ShipLocker /// Missions /// Loadout /// Cargo /// /// public async Task> 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 { location, powerplay, shiplocker, missions, loadout, cargo } .Where(x => x != null).Cast().ToList(); } public async Task> Get() { return []; } }