mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +01:00
feat: add wndproc nullref fix
This commit is contained in:
parent
3cf47f7ec4
commit
baad575c53
7 changed files with 112 additions and 3 deletions
|
|
@ -7,6 +7,7 @@ using System.Threading;
|
|||
|
||||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Data;
|
||||
using Dalamud.Fixes;
|
||||
using Dalamud.Game;
|
||||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.Command;
|
||||
|
|
@ -102,6 +103,10 @@ namespace Dalamud
|
|||
Service<SigScanner>.Set(new SigScanner(true));
|
||||
Service<HookManager>.Set();
|
||||
|
||||
// Initialize game fixes
|
||||
var gameFixes = Service<GameFixes>.Set();
|
||||
gameFixes.Apply();
|
||||
|
||||
// Initialize FFXIVClientStructs function resolver
|
||||
FFXIVClientStructs.Resolver.Initialize();
|
||||
Log.Information("[T1] FFXIVClientStructs initialized!");
|
||||
|
|
@ -347,6 +352,8 @@ namespace Dalamud
|
|||
Service<Framework>.GetNullable()?.ExplicitDispose();
|
||||
Service<ClientState>.GetNullable()?.ExplicitDispose();
|
||||
|
||||
Service<GameFixes>.GetNullable()?.ExplicitDispose();
|
||||
|
||||
this.unloadSignal?.Dispose();
|
||||
|
||||
Service<WinSockHandlers>.GetNullable()?.Dispose();
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ namespace Dalamud
|
|||
|
||||
var levelSwitch = new LoggingLevelSwitch(LogEventLevel.Verbose);
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.WriteTo.Async(a => a.File(logPath))
|
||||
.WriteTo.Async(a => a.File(logPath, fileSizeLimitBytes: null, buffered: false, flushToDiskInterval: TimeSpan.FromSeconds(1)))
|
||||
.WriteTo.Sink(SerilogEventSink.Instance)
|
||||
.MinimumLevel.ControlledBy(levelSwitch)
|
||||
.CreateLogger();
|
||||
|
|
|
|||
43
Dalamud/Fixes/GameFixes.cs
Normal file
43
Dalamud/Fixes/GameFixes.cs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Fixes;
|
||||
|
||||
/// <summary>
|
||||
/// Class responsible for executing game fixes.
|
||||
/// </summary>
|
||||
internal class GameFixes : IDisposable
|
||||
{
|
||||
private readonly IGameFix[] fixes =
|
||||
{
|
||||
new WndProcNullRefFix(),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Apply all game fixes.
|
||||
/// </summary>
|
||||
public void Apply()
|
||||
{
|
||||
foreach (var gameFix in this.fixes)
|
||||
{
|
||||
try
|
||||
{
|
||||
gameFix.Apply();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Could not apply game fix: {FixName}", gameFix.GetType().FullName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var disposable in this.fixes.OfType<IDisposable>())
|
||||
{
|
||||
disposable.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
14
Dalamud/Fixes/IGameFix.cs
Normal file
14
Dalamud/Fixes/IGameFix.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
|
||||
namespace Dalamud.Fixes;
|
||||
|
||||
/// <summary>
|
||||
/// Base interface to be implemented by game fixes.
|
||||
/// </summary>
|
||||
internal interface IGameFix
|
||||
{
|
||||
/// <summary>
|
||||
/// Apply the patch to the game.
|
||||
/// </summary>
|
||||
public void Apply();
|
||||
}
|
||||
45
Dalamud/Fixes/WndProcNullRefFix.cs
Normal file
45
Dalamud/Fixes/WndProcNullRefFix.cs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using Dalamud.Game;
|
||||
using Dalamud.Hooking;
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Fixes;
|
||||
|
||||
/// <summary>
|
||||
/// This fix is for the following issue:
|
||||
/// Null reference in the game's WndProc function when certain window messages arrive
|
||||
/// before an object on the game's input manager is initialized.
|
||||
/// </summary>
|
||||
internal class WndProcNullRefFix : IGameFix, IDisposable
|
||||
{
|
||||
private AsmHook? wndProcHook;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Apply()
|
||||
{
|
||||
var sigScanner = Service<SigScanner>.Get();
|
||||
|
||||
if (!sigScanner.TryScanText("E8 ?? ?? ?? ?? 48 83 38 00 74 14", out var patchAddress))
|
||||
{
|
||||
Log.Error("Failed to find WndProc patch address");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Information($"Applying WndProcNullRefFix at {patchAddress:X}");
|
||||
|
||||
var patchAsm = new byte[]
|
||||
{
|
||||
0x48, 0x85, 0xc0, // test rax, rax
|
||||
0x74, 0x15, // jz +0x1A
|
||||
};
|
||||
|
||||
this.wndProcHook = new AsmHook(patchAddress, patchAsm, "WndProcNullRefFix");
|
||||
this.wndProcHook.Enable();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
this.wndProcHook?.Dispose();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
using System.Numerics;
|
||||
|
||||
using Dalamud.Game.ClientState.Keys;
|
||||
using Dalamud.Game.Gui.Internal;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using ImGuiNET;
|
||||
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ namespace Dalamud.Plugin
|
|||
/// <summary>
|
||||
/// Gets a value indicating whether Dalamud is running in Debug mode or the /xldev menu is open. This can occur on release builds.
|
||||
/// </summary>
|
||||
public bool IsDevMenuOpen => Service<DalamudInterface>.GetNullable() is {IsDevMenuOpen: true}; // Can be null during boot
|
||||
public bool IsDevMenuOpen => Service<DalamudInterface>.GetNullable() is { IsDevMenuOpen: true }; // Can be null during boot
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether a debugger is attached.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue