diff --git a/Penumbra.CrashHandler/CrashData.cs b/Penumbra.CrashHandler/CrashData.cs
index 956a3db7..cdac103f 100644
--- a/Penumbra.CrashHandler/CrashData.cs
+++ b/Penumbra.CrashHandler/CrashData.cs
@@ -24,6 +24,12 @@ public class CrashData
/// The time this crash data was generated.
public DateTimeOffset CrashTime { get; set; } = DateTimeOffset.UnixEpoch;
+ /// Penumbra's Version when this crash data was created.
+ public string Version { get; set; } = string.Empty;
+
+ /// The Game's Version when this crash data was created.
+ public string GameVersion { get; set; } = string.Empty;
+
/// The FFXIV process ID when this data was generated.
public int ProcessId { get; set; } = 0;
@@ -52,11 +58,11 @@ public class CrashData
=> LastVfxFuncsInvoked.Count == 0 ? default : LastVfxFuncsInvoked[0];
/// A collection of the last few characters loaded before this crash data was generated.
- public List LastCharactersLoaded { get; } = [];
+ public List LastCharactersLoaded { get; set; } = [];
/// A collection of the last few modded files loaded before this crash data was generated.
- public List LastModdedFilesLoaded { get; } = [];
+ public List LastModdedFilesLoaded { get; set; } = [];
/// A collection of the last few vfx functions invoked before this crash data was generated.
- public List LastVfxFuncsInvoked { get; } = [];
+ public List LastVfxFuncsInvoked { get; set; } = [];
}
diff --git a/Penumbra.CrashHandler/GameEventLogReader.cs b/Penumbra.CrashHandler/GameEventLogReader.cs
index 283be526..1ae49fa5 100644
--- a/Penumbra.CrashHandler/GameEventLogReader.cs
+++ b/Penumbra.CrashHandler/GameEventLogReader.cs
@@ -25,15 +25,17 @@ public sealed class GameEventLogReader : IDisposable
}
- public JsonObject Dump(string mode, int processId, int exitCode)
+ 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.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)
diff --git a/Penumbra.CrashHandler/Program.cs b/Penumbra.CrashHandler/Program.cs
index e4a46348..518e2d04 100644
--- a/Penumbra.CrashHandler/Program.cs
+++ b/Penumbra.CrashHandler/Program.cs
@@ -7,7 +7,7 @@ public class CrashHandler
{
public static void Main(string[] args)
{
- if (args.Length < 2 || !int.TryParse(args[1], out var pid))
+ if (args.Length < 4 || !int.TryParse(args[1], out var pid))
return;
try
@@ -17,7 +17,7 @@ public class CrashHandler
parent.WaitForExit();
var exitCode = parent.ExitCode;
- var obj = reader.Dump("Crash", pid, exitCode);
+ var obj = reader.Dump("Crash", pid, exitCode, args[2], args[3]);
using var fs = File.Open(args[0], FileMode.Create);
using var w = new Utf8JsonWriter(fs, new JsonWriterOptions { Indented = true });
obj.WriteTo(w, new JsonSerializerOptions() { WriteIndented = true });
diff --git a/Penumbra/Services/CrashHandlerService.cs b/Penumbra/Services/CrashHandlerService.cs
index 4e2bce0f..a3a35b78 100644
--- a/Penumbra/Services/CrashHandlerService.cs
+++ b/Penumbra/Services/CrashHandlerService.cs
@@ -22,15 +22,17 @@ public sealed class CrashHandlerService : IDisposable, IService
private readonly ActorManager _actors;
private readonly ResourceLoader _resourceLoader;
private readonly Configuration _config;
+ private readonly ValidityChecker _validityChecker;
public CrashHandlerService(FilenameService files, CommunicatorService communicator, ActorManager actors, ResourceLoader resourceLoader,
- Configuration config)
+ Configuration config, ValidityChecker validityChecker)
{
- _files = files;
- _communicator = communicator;
- _actors = actors;
- _resourceLoader = resourceLoader;
- _config = config;
+ _files = files;
+ _communicator = communicator;
+ _actors = actors;
+ _resourceLoader = resourceLoader;
+ _config = config;
+ _validityChecker = validityChecker;
if (!_config.UseCrashHandler)
return;
@@ -152,6 +154,8 @@ public sealed class CrashHandlerService : IDisposable, IService
};
info.ArgumentList.Add(_files.LogFileName);
info.ArgumentList.Add(Environment.ProcessId.ToString());
+ info.ArgumentList.Add($"{_validityChecker.Version} ({_validityChecker.CommitHash})");
+ info.ArgumentList.Add(_validityChecker.GameVersion);
_child = Process.Start(info);
if (_child == null)
throw new Exception("Child Process could not be created.");
@@ -177,7 +181,7 @@ public sealed class CrashHandlerService : IDisposable, IService
JsonObject jObj;
lock (_eventWriter)
{
- jObj = reader.Dump("Manual Dump", Environment.ProcessId, 0);
+ jObj = reader.Dump("Manual Dump", Environment.ProcessId, 0, $"{_validityChecker.Version} ({_validityChecker.CommitHash})", _validityChecker.GameVersion);
}
var logFile = _files.LogFileName;
diff --git a/Penumbra/Services/ValidityChecker.cs b/Penumbra/Services/ValidityChecker.cs
index 4d071f85..d4b5005f 100644
--- a/Penumbra/Services/ValidityChecker.cs
+++ b/Penumbra/Services/ValidityChecker.cs
@@ -1,5 +1,6 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Plugin;
+using FFXIVClientStructs.FFXIV.Client.System.Framework;
using OtterGui.Classes;
using OtterGui.Services;
@@ -20,6 +21,7 @@ public class ValidityChecker : IService
public readonly string Version;
public readonly string CommitHash;
+ public readonly string GameVersion;
public ValidityChecker(DalamudPluginInterface pi)
{
@@ -28,14 +30,19 @@ public class ValidityChecker : IService
IsValidSourceRepo = CheckSourceRepo(pi);
var assembly = GetType().Assembly;
- Version = assembly.GetName().Version?.ToString() ?? string.Empty;
- CommitHash = assembly.GetCustomAttribute()?.InformationalVersion ?? "Unknown";
+ Version = assembly.GetName().Version?.ToString() ?? string.Empty;
+ CommitHash = assembly.GetCustomAttribute()?.InformationalVersion ?? "Unknown";
+ GameVersion = GetGameVersion();
}
+ private static unsafe string GetGameVersion()
+ => Framework.Instance()->GameVersion[0];
+
public void LogExceptions()
{
if (ImcExceptions.Count > 0)
- Penumbra.Messager.NotificationMessage($"{ImcExceptions} IMC Exceptions thrown during Penumbra load. Please repair your game files.", NotificationType.Warning);
+ Penumbra.Messager.NotificationMessage($"{ImcExceptions} IMC Exceptions thrown during Penumbra load. Please repair your game files.",
+ NotificationType.Warning);
}
// Because remnants of penumbra in devPlugins cause issues, we check for them to warn users to remove them.
diff --git a/Penumbra/UI/Tabs/Debug/CrashDataExtensions.cs b/Penumbra/UI/Tabs/Debug/CrashDataExtensions.cs
index 3d32d267..78014054 100644
--- a/Penumbra/UI/Tabs/Debug/CrashDataExtensions.cs
+++ b/Penumbra/UI/Tabs/Debug/CrashDataExtensions.cs
@@ -13,6 +13,9 @@ public static class CrashDataExtensions
{
ImGui.TextUnformatted(nameof(data.Mode));
ImGui.TextUnformatted(nameof(data.CrashTime));
+ ImGui.TextUnformatted("Current Age");
+ ImGui.TextUnformatted(nameof(data.Version));
+ ImGui.TextUnformatted(nameof(data.GameVersion));
ImGui.TextUnformatted(nameof(data.ExitCode));
ImGui.TextUnformatted(nameof(data.ProcessId));
ImGui.TextUnformatted(nameof(data.TotalModdedFilesLoaded));
@@ -25,6 +28,9 @@ public static class CrashDataExtensions
{
ImGui.TextUnformatted(data.Mode);
ImGui.TextUnformatted(data.CrashTime.ToString());
+ ImGui.TextUnformatted((DateTimeOffset.UtcNow - data.CrashTime).ToString(@"dd\.hh\:mm\:ss"));
+ ImGui.TextUnformatted(data.Version);
+ ImGui.TextUnformatted(data.GameVersion);
ImGui.TextUnformatted(data.ExitCode.ToString());
ImGui.TextUnformatted(data.ProcessId.ToString());
ImGui.TextUnformatted(data.TotalModdedFilesLoaded.ToString());