Creating temp havok file to not crash the analyzer

This commit is contained in:
defnotken
2026-01-02 10:23:32 -06:00
parent 2af0b5774b
commit e8c157d8ac

View File

@@ -164,12 +164,25 @@ public sealed class XivDataAnalyzer
var output = new Dictionary<string, List<ushort>>(StringComparer.OrdinalIgnoreCase);
var tempHavokDataPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()) + ".hkx";
var tempHavokDataPathAnsi = Marshal.StringToHGlobalAnsi(tempHavokDataPath);
// write to temp file
var tempHavokDataPath = Path.Combine(Path.GetTempPath(), $"lightless_{Guid.NewGuid():N}.hkx");
var tempHavokDataPathAnsi = IntPtr.Zero;
try
{
File.WriteAllBytes(tempHavokDataPath, havokData);
using (var tempFs = new FileStream(tempHavokDataPath, FileMode.CreateNew, FileAccess.Write, FileShare.None, 4096, FileOptions.DeleteOnClose))
{
tempFs.Write(havokData, 0, havokData.Length);
tempFs.Flush(true);
}
if (!File.Exists(tempHavokDataPath))
{
_logger.LogWarning("Temporary havok file was deleted before it could be loaded: {path}", tempHavokDataPath);
return null;
}
tempHavokDataPathAnsi = Marshal.StringToHGlobalAnsi(tempHavokDataPath);
var loadoptions = stackalloc hkSerializeUtil.LoadOptions[1];
loadoptions->TypeInfoRegistry = hkBuiltinTypeRegistry.Instance()->GetTypeInfoRegistry();
@@ -181,7 +194,10 @@ public sealed class XivDataAnalyzer
var resource = hkSerializeUtil.LoadFromFile((byte*)tempHavokDataPathAnsi, null, loadoptions);
if (resource == null)
throw new InvalidOperationException("Resource was null after loading");
{
_logger.LogWarning("Havok resource was null after loading from {path}", tempHavokDataPath);
return null;
}
var rootLevelName = @"hkRootLevelContainer"u8;
fixed (byte* n1 = rootLevelName)
@@ -229,8 +245,8 @@ public sealed class XivDataAnalyzer
foreach (var key in output.Keys.ToList())
{
output[key] = [.. output[key]
.Distinct()
.Order()];
.Distinct()
.Order()];
}
}
catch (Exception ex)
@@ -240,8 +256,18 @@ public sealed class XivDataAnalyzer
}
finally
{
Marshal.FreeHGlobal(tempHavokDataPathAnsi);
try { File.Delete(tempHavokDataPath); } catch { /* ignore */ }
if (tempHavokDataPathAnsi != IntPtr.Zero)
Marshal.FreeHGlobal(tempHavokDataPathAnsi);
try
{
if (File.Exists(tempHavokDataPath))
File.Delete(tempHavokDataPath);
}
catch (Exception ex)
{
_logger.LogTrace(ex, "Could not delete temporary havok file: {path}", tempHavokDataPath);
}
}
_configService.Current.BonesDictionary[hash] = output;