using System; using System.Collections.Generic; using System.Linq; using System.Text.Json.Nodes; using Penumbra.CrashHandler.Buffers; namespace Penumbra.CrashHandler; public interface IBufferReader { public uint TotalCount { get; } public IEnumerable GetLines(DateTimeOffset crashTime); } public sealed class GameEventLogReader(int pid) : IDisposable { public readonly (IBufferReader Reader, string TypeSingular, string TypePlural)[] Readers = [ (CharacterBaseBuffer.CreateReader(pid), "CharacterLoaded", "CharactersLoaded"), (ModdedFileBuffer.CreateReader(pid), "ModdedFileLoaded", "ModdedFilesLoaded"), (AnimationInvocationBuffer.CreateReader(pid), "VFXFuncInvoked", "VFXFuncsInvoked"), ]; public void Dispose() { foreach (var (reader, _, _) in Readers) (reader as IDisposable)?.Dispose(); } public JsonObject Dump(string mode, int processId, int exitCode, string version, string gameVersion) { var crashTime = DateTimeOffset.UtcNow; var obj = new JsonObject { [nameof(CrashData.Mode)] = mode, [nameof(CrashData.CrashTime)] = DateTimeOffset.UtcNow, [nameof(CrashData.ProcessId)] = processId, [nameof(CrashData.ExitCode)] = exitCode, [nameof(CrashData.Version)] = version, [nameof(CrashData.GameVersion)] = gameVersion, }; foreach (var (reader, singular, _) in Readers) obj["Last" + singular] = reader.GetLines(crashTime).FirstOrDefault(); foreach (var (reader, _, plural) in Readers) { obj["Total" + plural] = reader.TotalCount; var array = new JsonArray(); foreach (var file in reader.GetLines(crashTime)) array.Add(file); obj["Last" + plural] = array; } return obj; } }