Make some stuff safer maybe.

This commit is contained in:
Ottermandias 2024-03-20 22:38:39 +01:00
parent fda77b49cd
commit 978f41a4d9
3 changed files with 67 additions and 56 deletions

View file

@ -9,15 +9,15 @@ public class MemoryMappedBuffer : IDisposable
{ {
private const int MinHeaderLength = 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4; private const int MinHeaderLength = 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4;
private readonly MemoryMappedFile _file; private readonly MemoryMappedFile _file;
private readonly MemoryMappedViewAccessor _header; private readonly MemoryMappedViewAccessor _header;
private readonly MemoryMappedViewAccessor[] _lines; private readonly MemoryMappedViewAccessor[] _lines;
public readonly int Version; public readonly int Version;
public readonly uint LineCount; public readonly uint LineCount;
public readonly uint LineCapacity; public readonly uint LineCapacity;
private readonly uint _lineMask; private readonly uint _lineMask;
private bool _disposed; private bool _disposed;
protected uint CurrentLineCount protected uint CurrentLineCount
{ {
@ -39,20 +39,20 @@ public class MemoryMappedBuffer : IDisposable
public MemoryMappedBuffer(string mapName, int version, uint lineCount, uint lineCapacity) public MemoryMappedBuffer(string mapName, int version, uint lineCount, uint lineCapacity)
{ {
Version = version; Version = version;
LineCount = BitOperations.RoundUpToPowerOf2(Math.Clamp(lineCount, 2, int.MaxValue >> 3)); LineCount = BitOperations.RoundUpToPowerOf2(Math.Clamp(lineCount, 2, int.MaxValue >> 3));
LineCapacity = BitOperations.RoundUpToPowerOf2(Math.Clamp(lineCapacity, 2, int.MaxValue >> 3)); LineCapacity = BitOperations.RoundUpToPowerOf2(Math.Clamp(lineCapacity, 2, int.MaxValue >> 3));
_lineMask = LineCount - 1; _lineMask = LineCount - 1;
var fileName = Encoding.UTF8.GetBytes(mapName); var fileName = Encoding.UTF8.GetBytes(mapName);
var headerLength = (uint)(4 + 4 + 4 + 4 + 4 + 4 + 4 + fileName.Length + 1); var headerLength = (uint)(4 + 4 + 4 + 4 + 4 + 4 + 4 + fileName.Length + 1);
headerLength = (headerLength & 0b111) > 0 ? (headerLength & ~0b111u) + 0b1000 : headerLength; headerLength = (headerLength & 0b111) > 0 ? (headerLength & ~0b111u) + 0b1000 : headerLength;
var capacity = LineCount * LineCapacity + headerLength; var capacity = LineCount * LineCapacity + headerLength;
_file = MemoryMappedFile.CreateNew(mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, _file = MemoryMappedFile.CreateNew(mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None,
HandleInheritability.Inheritable); HandleInheritability.Inheritable);
_header = _file.CreateViewAccessor(0, headerLength); _header = _file.CreateViewAccessor(0, headerLength);
_header.Write(0, headerLength); _header.Write(0, headerLength);
_header.Write(4, Version); _header.Write(4, Version);
_header.Write(8, LineCount); _header.Write(8, LineCount);
_header.Write(12, LineCapacity); _header.Write(12, LineCapacity);
_header.WriteArray(28, fileName, 0, fileName.Length); _header.WriteArray(28, fileName, 0, fileName.Length);
_header.Write(fileName.Length + 28, (byte)0); _header.Write(fileName.Length + 28, (byte)0);
@ -65,16 +65,16 @@ public class MemoryMappedBuffer : IDisposable
uint? expectedMinLineCapacity = null) uint? expectedMinLineCapacity = null)
{ {
_file = MemoryMappedFile.OpenExisting(mapName, MemoryMappedFileRights.ReadWrite, HandleInheritability.Inheritable); _file = MemoryMappedFile.OpenExisting(mapName, MemoryMappedFileRights.ReadWrite, HandleInheritability.Inheritable);
using var headerLine = _file.CreateViewAccessor(0, 4, MemoryMappedFileAccess.Read); using var headerLine = _file.CreateViewAccessor(0, 4, MemoryMappedFileAccess.Read);
var headerLength = headerLine.ReadUInt32(0); var headerLength = headerLine.ReadUInt32(0);
if (headerLength < MinHeaderLength) if (headerLength < MinHeaderLength)
Throw($"Map {mapName} did not contain a valid header."); Throw($"Map {mapName} did not contain a valid header.");
_header = _file.CreateViewAccessor(0, headerLength, MemoryMappedFileAccess.ReadWrite); _header = _file.CreateViewAccessor(0, headerLength, MemoryMappedFileAccess.ReadWrite);
Version = _header.ReadInt32(4); Version = _header.ReadInt32(4);
LineCount = _header.ReadUInt32(8); LineCount = _header.ReadUInt32(8);
LineCapacity = _header.ReadUInt32(12); LineCapacity = _header.ReadUInt32(12);
_lineMask = LineCount - 1; _lineMask = LineCount - 1;
if (expectedVersion.HasValue && expectedVersion.Value != Version) if (expectedVersion.HasValue && expectedVersion.Value != Version)
Throw($"Map {mapName} has version {Version} instead of {expectedVersion.Value}."); Throw($"Map {mapName} has version {Version} instead of {expectedVersion.Value}.");
@ -122,25 +122,25 @@ public class MemoryMappedBuffer : IDisposable
protected static int WriteString(string text, Span<byte> span) protected static int WriteString(string text, Span<byte> span)
{ {
var bytes = Encoding.UTF8.GetBytes(text); var bytes = Encoding.UTF8.GetBytes(text);
var length = bytes.Length + 1; var source = (Span<byte>)bytes;
var length = source.Length + 1;
if (length > span.Length) if (length > span.Length)
throw new Exception($"String {text} is too long to write into span."); source = source[..(span.Length - 1)];
source.CopyTo(span);
bytes.CopyTo(span);
span[bytes.Length] = 0; span[bytes.Length] = 0;
return length; return source.Length + 1;
} }
protected static int WriteSpan(ReadOnlySpan<byte> input, Span<byte> span) protected static int WriteSpan(ReadOnlySpan<byte> input, Span<byte> span)
{ {
var length = input.Length + 1; var length = input.Length + 1;
if (length > span.Length) if (length > span.Length)
throw new Exception("Byte array is too long to write into span."); input = input[..(span.Length - 1)];
input.CopyTo(span); input.CopyTo(span);
span[input.Length] = 0; span[input.Length] = 0;
return length; return input.Length + 1;
} }
protected Span<byte> GetLine(int i) protected Span<byte> GetLine(int i)
@ -150,7 +150,7 @@ public class MemoryMappedBuffer : IDisposable
lock (_header) lock (_header)
{ {
var lineIdx = CurrentLinePosition + i & _lineMask; var lineIdx = (CurrentLinePosition + i) & _lineMask;
if (lineIdx > CurrentLineCount) if (lineIdx > CurrentLineCount)
return null; return null;
@ -168,8 +168,8 @@ public class MemoryMappedBuffer : IDisposable
if (currentLineCount == LineCount) if (currentLineCount == LineCount)
{ {
var currentLinePos = CurrentLinePosition; var currentLinePos = CurrentLinePosition;
view = _lines[currentLinePos]!; view = _lines[currentLinePos]!;
CurrentLinePosition = currentLinePos + 1 & _lineMask; CurrentLinePosition = (currentLinePos + 1) & _lineMask;
} }
else else
{ {

View file

@ -14,12 +14,21 @@ public class CrashHandler
{ {
using var reader = new GameEventLogReader(); using var reader = new GameEventLogReader();
var parent = Process.GetProcessById(pid); var parent = Process.GetProcessById(pid);
using var handle = parent.SafeHandle;
parent.WaitForExit(); parent.WaitForExit();
var exitCode = parent.ExitCode; int exitCode;
var obj = reader.Dump("Crash", pid, exitCode, args[2], args[3]); try
using var fs = File.Open(args[0], FileMode.Create); {
using var w = new Utf8JsonWriter(fs, new JsonWriterOptions { Indented = true }); exitCode = parent.ExitCode;
}
catch (Exception ex)
{
exitCode = -1;
}
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 }); obj.WriteTo(w, new JsonSerializerOptions() { WriteIndented = true });
} }
catch (Exception ex) catch (Exception ex)

View file

@ -21,7 +21,15 @@ public class ValidityChecker : IService
public readonly string Version; public readonly string Version;
public readonly string CommitHash; public readonly string CommitHash;
public readonly string GameVersion;
public unsafe string GameVersion
{
get
{
var framework = Framework.Instance();
return framework == null ? string.Empty : framework->GameVersion[0];
}
}
public ValidityChecker(DalamudPluginInterface pi) public ValidityChecker(DalamudPluginInterface pi)
{ {
@ -30,14 +38,10 @@ public class ValidityChecker : IService
IsValidSourceRepo = CheckSourceRepo(pi); IsValidSourceRepo = CheckSourceRepo(pi);
var assembly = GetType().Assembly; var assembly = GetType().Assembly;
Version = assembly.GetName().Version?.ToString() ?? string.Empty; Version = assembly.GetName().Version?.ToString() ?? string.Empty;
CommitHash = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? "Unknown"; CommitHash = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? "Unknown";
GameVersion = GetGameVersion();
} }
private static unsafe string GetGameVersion()
=> Framework.Instance()->GameVersion[0];
public void LogExceptions() public void LogExceptions()
{ {
if (ImcExceptions.Count > 0) if (ImcExceptions.Count > 0)
@ -49,16 +53,16 @@ public class ValidityChecker : IService
private static bool CheckDevPluginPenumbra(DalamudPluginInterface pi) private static bool CheckDevPluginPenumbra(DalamudPluginInterface pi)
{ {
#if !DEBUG #if !DEBUG
var path = Path.Combine( pi.DalamudAssetDirectory.Parent?.FullName ?? "INVALIDPATH", "devPlugins", "Penumbra" ); var path = Path.Combine(pi.DalamudAssetDirectory.Parent?.FullName ?? "INVALIDPATH", "devPlugins", "Penumbra");
var dir = new DirectoryInfo( path ); var dir = new DirectoryInfo(path);
try try
{ {
return dir.Exists && dir.EnumerateFiles( "*.dll", SearchOption.AllDirectories ).Any(); return dir.Exists && dir.EnumerateFiles("*.dll", SearchOption.AllDirectories).Any();
} }
catch( Exception e ) catch (Exception e)
{ {
Penumbra.Log.Error( $"Could not check for dev plugin Penumbra:\n{e}" ); Penumbra.Log.Error($"Could not check for dev plugin Penumbra:\n{e}");
return true; return true;
} }
#else #else
@ -71,11 +75,9 @@ public class ValidityChecker : IService
{ {
#if !DEBUG #if !DEBUG
var checkedDirectory = pi.AssemblyLocation.Directory?.Parent?.Parent?.Name; var checkedDirectory = pi.AssemblyLocation.Directory?.Parent?.Parent?.Name;
var ret = checkedDirectory?.Equals( "installedPlugins", StringComparison.OrdinalIgnoreCase ) ?? false; var ret = checkedDirectory?.Equals("installedPlugins", StringComparison.OrdinalIgnoreCase) ?? false;
if( !ret ) if (!ret)
{ Penumbra.Log.Error($"Penumbra is not correctly installed. Application loaded from \"{pi.AssemblyLocation.Directory!.FullName}\".");
Penumbra.Log.Error( $"Penumbra is not correctly installed. Application loaded from \"{pi.AssemblyLocation.Directory!.FullName}\"." );
}
return !ret; return !ret;
#else #else
@ -89,10 +91,10 @@ public class ValidityChecker : IService
#if !DEBUG #if !DEBUG
return pi.SourceRepository?.Trim().ToLowerInvariant() switch return pi.SourceRepository?.Trim().ToLowerInvariant() switch
{ {
null => false, null => false,
RepositoryLower => true, RepositoryLower => true,
SeaOfStarsLower => true, SeaOfStarsLower => true,
_ => false, _ => false,
}; };
#else #else
return true; return true;