mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
Make some stuff safer maybe.
This commit is contained in:
parent
fda77b49cd
commit
978f41a4d9
3 changed files with 67 additions and 56 deletions
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue