mirror of
https://github.com/goatcorp/Dalamud.git
synced 2026-02-18 22:07:44 +01:00
chore: convert Dalamud to file-scoped namespaces
This commit is contained in:
parent
b093323acc
commit
987ff8dc8f
368 changed files with 55081 additions and 55450 deletions
|
|
@ -6,126 +6,125 @@ using Dalamud.Configuration.Internal;
|
|||
#endif
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Game.Internal
|
||||
namespace Dalamud.Game.Internal;
|
||||
|
||||
/// <summary>
|
||||
/// This class disables anti-debug functionality in the game client.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal sealed partial class AntiDebug : IServiceType
|
||||
{
|
||||
/// <summary>
|
||||
/// This class disables anti-debug functionality in the game client.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal sealed partial class AntiDebug : IServiceType
|
||||
private readonly byte[] nop = new byte[] { 0x31, 0xC0, 0x90, 0x90, 0x90, 0x90 };
|
||||
private byte[] original;
|
||||
private IntPtr debugCheckAddress;
|
||||
|
||||
[ServiceManager.ServiceConstructor]
|
||||
private AntiDebug(SigScanner sigScanner)
|
||||
{
|
||||
private readonly byte[] nop = new byte[] { 0x31, 0xC0, 0x90, 0x90, 0x90, 0x90 };
|
||||
private byte[] original;
|
||||
private IntPtr debugCheckAddress;
|
||||
|
||||
[ServiceManager.ServiceConstructor]
|
||||
private AntiDebug(SigScanner sigScanner)
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
this.debugCheckAddress = sigScanner.ScanText("FF 15 ?? ?? ?? ?? 85 C0 74 11 41");
|
||||
}
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
this.debugCheckAddress = IntPtr.Zero;
|
||||
}
|
||||
this.debugCheckAddress = sigScanner.ScanText("FF 15 ?? ?? ?? ?? 85 C0 74 11 41");
|
||||
}
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
this.debugCheckAddress = IntPtr.Zero;
|
||||
}
|
||||
|
||||
Log.Verbose($"Debug check address 0x{this.debugCheckAddress.ToInt64():X}");
|
||||
Log.Verbose($"Debug check address 0x{this.debugCheckAddress.ToInt64():X}");
|
||||
|
||||
if (!this.IsEnabled)
|
||||
{
|
||||
if (!this.IsEnabled)
|
||||
{
|
||||
#if DEBUG
|
||||
this.Enable();
|
||||
#else
|
||||
if (Service<DalamudConfiguration>.Get().IsAntiAntiDebugEnabled)
|
||||
this.Enable();
|
||||
if (Service<DalamudConfiguration>.Get().IsAntiAntiDebugEnabled)
|
||||
this.Enable();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the anti-debugging is enabled.
|
||||
/// </summary>
|
||||
public bool IsEnabled { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Enables the anti-debugging by overwriting code in memory.
|
||||
/// </summary>
|
||||
public void Enable()
|
||||
{
|
||||
this.original = new byte[this.nop.Length];
|
||||
if (this.debugCheckAddress != IntPtr.Zero && !this.IsEnabled)
|
||||
{
|
||||
Log.Information($"Overwriting debug check at 0x{this.debugCheckAddress.ToInt64():X}");
|
||||
SafeMemory.ReadBytes(this.debugCheckAddress, this.nop.Length, out this.original);
|
||||
SafeMemory.WriteBytes(this.debugCheckAddress, this.nop);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Information("Debug check already overwritten?");
|
||||
}
|
||||
|
||||
this.IsEnabled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disable the anti-debugging by reverting the overwritten code in memory.
|
||||
/// </summary>
|
||||
public void Disable()
|
||||
{
|
||||
if (this.debugCheckAddress != IntPtr.Zero && this.original != null)
|
||||
{
|
||||
Log.Information($"Reverting debug check at 0x{this.debugCheckAddress.ToInt64():X}");
|
||||
SafeMemory.WriteBytes(this.debugCheckAddress, this.original);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Information("Debug check was not overwritten?");
|
||||
}
|
||||
|
||||
this.IsEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implementing IDisposable.
|
||||
/// Gets a value indicating whether the anti-debugging is enabled.
|
||||
/// </summary>
|
||||
internal sealed partial class AntiDebug : IDisposable
|
||||
public bool IsEnabled { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Enables the anti-debugging by overwriting code in memory.
|
||||
/// </summary>
|
||||
public void Enable()
|
||||
{
|
||||
private bool disposed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="AntiDebug"/> class.
|
||||
/// </summary>
|
||||
~AntiDebug() => this.Dispose(false);
|
||||
|
||||
/// <summary>
|
||||
/// Disposes of managed and unmanaged resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
this.original = new byte[this.nop.Length];
|
||||
if (this.debugCheckAddress != IntPtr.Zero && !this.IsEnabled)
|
||||
{
|
||||
this.Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
Log.Information($"Overwriting debug check at 0x{this.debugCheckAddress.ToInt64():X}");
|
||||
SafeMemory.ReadBytes(this.debugCheckAddress, this.nop.Length, out this.original);
|
||||
SafeMemory.WriteBytes(this.debugCheckAddress, this.nop);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Information("Debug check already overwritten?");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes of managed and unmanaged resources.
|
||||
/// </summary>
|
||||
/// <param name="disposing">If this was disposed through calling Dispose() or from being finalized.</param>
|
||||
private void Dispose(bool disposing)
|
||||
this.IsEnabled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disable the anti-debugging by reverting the overwritten code in memory.
|
||||
/// </summary>
|
||||
public void Disable()
|
||||
{
|
||||
if (this.debugCheckAddress != IntPtr.Zero && this.original != null)
|
||||
{
|
||||
if (this.disposed)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
// If anti-debug is enabled and is being disposed, odds are either the game is exiting, or Dalamud is being reloaded.
|
||||
// If it is the latter, there's half a chance a debugger is currently attached. There's no real need to disable the
|
||||
// check in either situation anyways. However if Dalamud is being reloaded, the sig may fail so may as well undo it.
|
||||
this.Disable();
|
||||
}
|
||||
|
||||
this.disposed = true;
|
||||
Log.Information($"Reverting debug check at 0x{this.debugCheckAddress.ToInt64():X}");
|
||||
SafeMemory.WriteBytes(this.debugCheckAddress, this.original);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Information("Debug check was not overwritten?");
|
||||
}
|
||||
|
||||
this.IsEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implementing IDisposable.
|
||||
/// </summary>
|
||||
internal sealed partial class AntiDebug : IDisposable
|
||||
{
|
||||
private bool disposed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="AntiDebug"/> class.
|
||||
/// </summary>
|
||||
~AntiDebug() => this.Dispose(false);
|
||||
|
||||
/// <summary>
|
||||
/// Disposes of managed and unmanaged resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
this.Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes of managed and unmanaged resources.
|
||||
/// </summary>
|
||||
/// <param name="disposing">If this was disposed through calling Dispose() or from being finalized.</param>
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (this.disposed)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
// If anti-debug is enabled and is being disposed, odds are either the game is exiting, or Dalamud is being reloaded.
|
||||
// If it is the latter, there's half a chance a debugger is currently attached. There's no real need to disable the
|
||||
// check in either situation anyways. However if Dalamud is being reloaded, the sig may fail so may as well undo it.
|
||||
this.Disable();
|
||||
}
|
||||
|
||||
this.disposed = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,227 +1,226 @@
|
|||
namespace Dalamud.Game.Internal.DXGI.Definitions
|
||||
namespace Dalamud.Game.Internal.DXGI.Definitions;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a full list of ID3D11Device functions to be used as an indexer into the DirectX Virtual Function Table entries.
|
||||
/// </summary>
|
||||
internal enum ID3D11DeviceVtbl
|
||||
{
|
||||
// IUnknown
|
||||
|
||||
/// <summary>
|
||||
/// Contains a full list of ID3D11Device functions to be used as an indexer into the DirectX Virtual Function Table entries.
|
||||
/// IUnknown::QueryInterface method (unknwn.h).
|
||||
/// </summary>
|
||||
internal enum ID3D11DeviceVtbl
|
||||
{
|
||||
// IUnknown
|
||||
QueryInterface = 0,
|
||||
|
||||
/// <summary>
|
||||
/// IUnknown::QueryInterface method (unknwn.h).
|
||||
/// </summary>
|
||||
QueryInterface = 0,
|
||||
/// <summary>
|
||||
/// IUnknown::AddRef method (unknwn.h).
|
||||
/// </summary>
|
||||
AddRef = 1,
|
||||
|
||||
/// <summary>
|
||||
/// IUnknown::AddRef method (unknwn.h).
|
||||
/// </summary>
|
||||
AddRef = 1,
|
||||
/// <summary>
|
||||
/// IUnknown::Release method (unknwn.h).
|
||||
/// </summary>
|
||||
Release = 2,
|
||||
|
||||
/// <summary>
|
||||
/// IUnknown::Release method (unknwn.h).
|
||||
/// </summary>
|
||||
Release = 2,
|
||||
// ID3D11Device
|
||||
|
||||
// ID3D11Device
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateBuffer method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateBuffer = 3,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateBuffer method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateBuffer = 3,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateTexture1D method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateTexture1D = 4,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateTexture1D method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateTexture1D = 4,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateTexture2D method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateTexture2D = 5,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateTexture2D method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateTexture2D = 5,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateTexture3D method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateTexture3D = 6,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateTexture3D method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateTexture3D = 6,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateShaderResourceView method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateShaderResourceView = 7,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateShaderResourceView method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateShaderResourceView = 7,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateUnorderedAccessView method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateUnorderedAccessView = 8,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateUnorderedAccessView method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateUnorderedAccessView = 8,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateRenderTargetView method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateRenderTargetView = 9,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateRenderTargetView method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateRenderTargetView = 9,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateDepthStencilView method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateDepthStencilView = 10,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateDepthStencilView method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateDepthStencilView = 10,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateInputLayout method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateInputLayout = 11,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateInputLayout method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateInputLayout = 11,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateVertexShader method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateVertexShader = 12,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateVertexShader method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateVertexShader = 12,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateGeometryShader method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateGeometryShader = 13,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateGeometryShader method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateGeometryShader = 13,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateGeometryShaderWithStreamOutput method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateGeometryShaderWithStreamOutput = 14,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateGeometryShaderWithStreamOutput method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateGeometryShaderWithStreamOutput = 14,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreatePixelShader method (d3d11.h).
|
||||
/// </summary>
|
||||
CreatePixelShader = 15,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreatePixelShader method (d3d11.h).
|
||||
/// </summary>
|
||||
CreatePixelShader = 15,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateHullShader method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateHullShader = 16,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateHullShader method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateHullShader = 16,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateDomainShader method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateDomainShader = 17,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateDomainShader method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateDomainShader = 17,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateComputeShader method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateComputeShader = 18,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateComputeShader method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateComputeShader = 18,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateClassLinkage method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateClassLinkage = 19,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateClassLinkage method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateClassLinkage = 19,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateBlendState method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateBlendState = 20,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateBlendState method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateBlendState = 20,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateDepthStencilState method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateDepthStencilState = 21,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateDepthStencilState method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateDepthStencilState = 21,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateRasterizerState method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateRasterizerState = 22,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateRasterizerState method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateRasterizerState = 22,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateSamplerState method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateSamplerState = 23,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateSamplerState method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateSamplerState = 23,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateQuery method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateQuery = 24,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateQuery method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateQuery = 24,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreatePredicate method (d3d11.h).
|
||||
/// </summary>
|
||||
CreatePredicate = 25,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreatePredicate method (d3d11.h).
|
||||
/// </summary>
|
||||
CreatePredicate = 25,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateCounter method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateCounter = 26,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateCounter method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateCounter = 26,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateDeferredContext method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateDeferredContext = 27,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CreateDeferredContext method (d3d11.h).
|
||||
/// </summary>
|
||||
CreateDeferredContext = 27,
|
||||
/// <summary>
|
||||
/// ID3D11Device::OpenSharedResource method (d3d11.h).
|
||||
/// </summary>
|
||||
OpenSharedResource = 28,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::OpenSharedResource method (d3d11.h).
|
||||
/// </summary>
|
||||
OpenSharedResource = 28,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CheckFormatSupport method (d3d11.h).
|
||||
/// </summary>
|
||||
CheckFormatSupport = 29,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CheckFormatSupport method (d3d11.h).
|
||||
/// </summary>
|
||||
CheckFormatSupport = 29,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CheckMultisampleQualityLevels method (d3d11.h).
|
||||
/// </summary>
|
||||
CheckMultisampleQualityLevels = 30,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CheckMultisampleQualityLevels method (d3d11.h).
|
||||
/// </summary>
|
||||
CheckMultisampleQualityLevels = 30,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CheckCounterInfo method (d3d11.h).
|
||||
/// </summary>
|
||||
CheckCounterInfo = 31,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CheckCounterInfo method (d3d11.h).
|
||||
/// </summary>
|
||||
CheckCounterInfo = 31,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CheckCounter method (d3d11.h).
|
||||
/// </summary>
|
||||
CheckCounter = 32,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CheckCounter method (d3d11.h).
|
||||
/// </summary>
|
||||
CheckCounter = 32,
|
||||
/// <summary>
|
||||
/// ID3D11Device::CheckFeatureSupport method (d3d11.h).
|
||||
/// </summary>
|
||||
CheckFeatureSupport = 33,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::CheckFeatureSupport method (d3d11.h).
|
||||
/// </summary>
|
||||
CheckFeatureSupport = 33,
|
||||
/// <summary>
|
||||
/// ID3D11Device::GetPrivateData method (d3d11.h).
|
||||
/// </summary>
|
||||
GetPrivateData = 34,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::GetPrivateData method (d3d11.h).
|
||||
/// </summary>
|
||||
GetPrivateData = 34,
|
||||
/// <summary>
|
||||
/// ID3D11Device::SetPrivateData method (d3d11.h).
|
||||
/// </summary>
|
||||
SetPrivateData = 35,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::SetPrivateData method (d3d11.h).
|
||||
/// </summary>
|
||||
SetPrivateData = 35,
|
||||
/// <summary>
|
||||
/// ID3D11Device::SetPrivateDataInterface method (d3d11.h).
|
||||
/// </summary>
|
||||
SetPrivateDataInterface = 36,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::SetPrivateDataInterface method (d3d11.h).
|
||||
/// </summary>
|
||||
SetPrivateDataInterface = 36,
|
||||
/// <summary>
|
||||
/// ID3D11Device::GetFeatureLevel method (d3d11.h).
|
||||
/// </summary>
|
||||
GetFeatureLevel = 37,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::GetFeatureLevel method (d3d11.h).
|
||||
/// </summary>
|
||||
GetFeatureLevel = 37,
|
||||
/// <summary>
|
||||
/// ID3D11Device::GetCreationFlags method (d3d11.h).
|
||||
/// </summary>
|
||||
GetCreationFlags = 38,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::GetCreationFlags method (d3d11.h).
|
||||
/// </summary>
|
||||
GetCreationFlags = 38,
|
||||
/// <summary>
|
||||
/// ID3D11Device::GetDeviceRemovedReason method (d3d11.h).
|
||||
/// </summary>
|
||||
GetDeviceRemovedReason = 39,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::GetDeviceRemovedReason method (d3d11.h).
|
||||
/// </summary>
|
||||
GetDeviceRemovedReason = 39,
|
||||
/// <summary>
|
||||
/// ID3D11Device::GetImmediateContext method (d3d11.h).
|
||||
/// </summary>
|
||||
GetImmediateContext = 40,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::GetImmediateContext method (d3d11.h).
|
||||
/// </summary>
|
||||
GetImmediateContext = 40,
|
||||
/// <summary>
|
||||
/// ID3D11Device::SetExceptionMode method (d3d11.h).
|
||||
/// </summary>
|
||||
SetExceptionMode = 41,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::SetExceptionMode method (d3d11.h).
|
||||
/// </summary>
|
||||
SetExceptionMode = 41,
|
||||
|
||||
/// <summary>
|
||||
/// ID3D11Device::GetExceptionMode method (d3d11.h).
|
||||
/// </summary>
|
||||
GetExceptionMode = 42,
|
||||
}
|
||||
/// <summary>
|
||||
/// ID3D11Device::GetExceptionMode method (d3d11.h).
|
||||
/// </summary>
|
||||
GetExceptionMode = 42,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,107 +1,106 @@
|
|||
namespace Dalamud.Game.Internal.DXGI.Definitions
|
||||
namespace Dalamud.Game.Internal.DXGI.Definitions;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a full list of IDXGISwapChain functions to be used as an indexer into the SwapChain Virtual Function Table
|
||||
/// entries.
|
||||
/// </summary>
|
||||
internal enum IDXGISwapChainVtbl
|
||||
{
|
||||
// IUnknown
|
||||
|
||||
/// <summary>
|
||||
/// Contains a full list of IDXGISwapChain functions to be used as an indexer into the SwapChain Virtual Function Table
|
||||
/// entries.
|
||||
/// IUnknown::QueryInterface method (unknwn.h).
|
||||
/// </summary>
|
||||
internal enum IDXGISwapChainVtbl
|
||||
{
|
||||
// IUnknown
|
||||
QueryInterface = 0,
|
||||
|
||||
/// <summary>
|
||||
/// IUnknown::QueryInterface method (unknwn.h).
|
||||
/// </summary>
|
||||
QueryInterface = 0,
|
||||
/// <summary>
|
||||
/// IUnknown::AddRef method (unknwn.h).
|
||||
/// </summary>
|
||||
AddRef = 1,
|
||||
|
||||
/// <summary>
|
||||
/// IUnknown::AddRef method (unknwn.h).
|
||||
/// </summary>
|
||||
AddRef = 1,
|
||||
/// <summary>
|
||||
/// IUnknown::Release method (unknwn.h).
|
||||
/// </summary>
|
||||
Release = 2,
|
||||
|
||||
/// <summary>
|
||||
/// IUnknown::Release method (unknwn.h).
|
||||
/// </summary>
|
||||
Release = 2,
|
||||
// IDXGIObject
|
||||
|
||||
// IDXGIObject
|
||||
/// <summary>
|
||||
/// IDXGIObject::SetPrivateData method (dxgi.h).
|
||||
/// </summary>
|
||||
SetPrivateData = 3,
|
||||
|
||||
/// <summary>
|
||||
/// IDXGIObject::SetPrivateData method (dxgi.h).
|
||||
/// </summary>
|
||||
SetPrivateData = 3,
|
||||
/// <summary>
|
||||
/// IDXGIObject::SetPrivateDataInterface method (dxgi.h).
|
||||
/// </summary>
|
||||
SetPrivateDataInterface = 4,
|
||||
|
||||
/// <summary>
|
||||
/// IDXGIObject::SetPrivateDataInterface method (dxgi.h).
|
||||
/// </summary>
|
||||
SetPrivateDataInterface = 4,
|
||||
/// <summary>
|
||||
/// IDXGIObject::GetPrivateData method (dxgi.h).
|
||||
/// </summary>
|
||||
GetPrivateData = 5,
|
||||
|
||||
/// <summary>
|
||||
/// IDXGIObject::GetPrivateData method (dxgi.h).
|
||||
/// </summary>
|
||||
GetPrivateData = 5,
|
||||
/// <summary>
|
||||
/// IDXGIObject::GetParent method (dxgi.h).
|
||||
/// </summary>
|
||||
GetParent = 6,
|
||||
|
||||
/// <summary>
|
||||
/// IDXGIObject::GetParent method (dxgi.h).
|
||||
/// </summary>
|
||||
GetParent = 6,
|
||||
// IDXGIDeviceSubObject
|
||||
|
||||
// IDXGIDeviceSubObject
|
||||
/// <summary>
|
||||
/// IDXGIDeviceSubObject::GetDevice method (dxgi.h).
|
||||
/// </summary>
|
||||
GetDevice = 7,
|
||||
|
||||
/// <summary>
|
||||
/// IDXGIDeviceSubObject::GetDevice method (dxgi.h).
|
||||
/// </summary>
|
||||
GetDevice = 7,
|
||||
// IDXGISwapChain
|
||||
|
||||
// IDXGISwapChain
|
||||
/// <summary>
|
||||
/// IDXGISwapChain::Present method (dxgi.h).
|
||||
/// </summary>
|
||||
Present = 8,
|
||||
|
||||
/// <summary>
|
||||
/// IDXGISwapChain::Present method (dxgi.h).
|
||||
/// </summary>
|
||||
Present = 8,
|
||||
/// <summary>
|
||||
/// IUnknIDXGISwapChainown::GetBuffer method (dxgi.h).
|
||||
/// </summary>
|
||||
GetBuffer = 9,
|
||||
|
||||
/// <summary>
|
||||
/// IUnknIDXGISwapChainown::GetBuffer method (dxgi.h).
|
||||
/// </summary>
|
||||
GetBuffer = 9,
|
||||
/// <summary>
|
||||
/// IDXGISwapChain::SetFullscreenState method (dxgi.h).
|
||||
/// </summary>
|
||||
SetFullscreenState = 10,
|
||||
|
||||
/// <summary>
|
||||
/// IDXGISwapChain::SetFullscreenState method (dxgi.h).
|
||||
/// </summary>
|
||||
SetFullscreenState = 10,
|
||||
/// <summary>
|
||||
/// IDXGISwapChain::GetFullscreenState method (dxgi.h).
|
||||
/// </summary>
|
||||
GetFullscreenState = 11,
|
||||
|
||||
/// <summary>
|
||||
/// IDXGISwapChain::GetFullscreenState method (dxgi.h).
|
||||
/// </summary>
|
||||
GetFullscreenState = 11,
|
||||
/// <summary>
|
||||
/// IDXGISwapChain::GetDesc method (dxgi.h).
|
||||
/// </summary>
|
||||
GetDesc = 12,
|
||||
|
||||
/// <summary>
|
||||
/// IDXGISwapChain::GetDesc method (dxgi.h).
|
||||
/// </summary>
|
||||
GetDesc = 12,
|
||||
/// <summary>
|
||||
/// IDXGISwapChain::ResizeBuffers method (dxgi.h).
|
||||
/// </summary>
|
||||
ResizeBuffers = 13,
|
||||
|
||||
/// <summary>
|
||||
/// IDXGISwapChain::ResizeBuffers method (dxgi.h).
|
||||
/// </summary>
|
||||
ResizeBuffers = 13,
|
||||
/// <summary>
|
||||
/// IDXGISwapChain::ResizeTarget method (dxgi.h).
|
||||
/// </summary>
|
||||
ResizeTarget = 14,
|
||||
|
||||
/// <summary>
|
||||
/// IDXGISwapChain::ResizeTarget method (dxgi.h).
|
||||
/// </summary>
|
||||
ResizeTarget = 14,
|
||||
/// <summary>
|
||||
/// IDXGISwapChain::GetContainingOutput method (dxgi.h).
|
||||
/// </summary>
|
||||
GetContainingOutput = 15,
|
||||
|
||||
/// <summary>
|
||||
/// IDXGISwapChain::GetContainingOutput method (dxgi.h).
|
||||
/// </summary>
|
||||
GetContainingOutput = 15,
|
||||
/// <summary>
|
||||
/// IDXGISwapChain::GetFrameStatistics method (dxgi.h).
|
||||
/// </summary>
|
||||
GetFrameStatistics = 16,
|
||||
|
||||
/// <summary>
|
||||
/// IDXGISwapChain::GetFrameStatistics method (dxgi.h).
|
||||
/// </summary>
|
||||
GetFrameStatistics = 16,
|
||||
|
||||
/// <summary>
|
||||
/// IDXGISwapChain::GetLastPresentCount method (dxgi.h).
|
||||
/// </summary>
|
||||
GetLastPresentCount = 17,
|
||||
}
|
||||
/// <summary>
|
||||
/// IDXGISwapChain::GetLastPresentCount method (dxgi.h).
|
||||
/// </summary>
|
||||
GetLastPresentCount = 17,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,19 @@
|
|||
using System;
|
||||
|
||||
namespace Dalamud.Game.Internal.DXGI
|
||||
namespace Dalamud.Game.Internal.DXGI;
|
||||
|
||||
/// <summary>
|
||||
/// An interface binding for the address resolvers that attempt to find native D3D11 methods.
|
||||
/// </summary>
|
||||
public interface ISwapChainAddressResolver
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface binding for the address resolvers that attempt to find native D3D11 methods.
|
||||
/// Gets or sets the address of the native D3D11.Present method.
|
||||
/// </summary>
|
||||
public interface ISwapChainAddressResolver
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the address of the native D3D11.Present method.
|
||||
/// </summary>
|
||||
IntPtr Present { get; set; }
|
||||
IntPtr Present { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the address of the native D3D11.ResizeBuffers method.
|
||||
/// </summary>
|
||||
IntPtr ResizeBuffers { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the address of the native D3D11.ResizeBuffers method.
|
||||
/// </summary>
|
||||
IntPtr ResizeBuffers { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,33 +4,32 @@ using System.Linq;
|
|||
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Game.Internal.DXGI
|
||||
namespace Dalamud.Game.Internal.DXGI;
|
||||
|
||||
/// <summary>
|
||||
/// The address resolver for native D3D11 methods to facilitate displaying the Dalamud UI.
|
||||
/// </summary>
|
||||
[Obsolete("This has been deprecated in favor of the VTable resolver.")]
|
||||
public sealed class SwapChainSigResolver : BaseAddressResolver, ISwapChainAddressResolver
|
||||
{
|
||||
/// <summary>
|
||||
/// The address resolver for native D3D11 methods to facilitate displaying the Dalamud UI.
|
||||
/// </summary>
|
||||
[Obsolete("This has been deprecated in favor of the VTable resolver.")]
|
||||
public sealed class SwapChainSigResolver : BaseAddressResolver, ISwapChainAddressResolver
|
||||
/// <inheritdoc/>
|
||||
public IntPtr Present { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IntPtr ResizeBuffers { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Setup64Bit(SigScanner sig)
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public IntPtr Present { get; set; }
|
||||
var module = Process.GetCurrentProcess().Modules.Cast<ProcessModule>().First(m => m.ModuleName == "dxgi.dll");
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IntPtr ResizeBuffers { get; set; }
|
||||
Log.Debug($"Found DXGI: 0x{module.BaseAddress.ToInt64():X}");
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Setup64Bit(SigScanner sig)
|
||||
{
|
||||
var module = Process.GetCurrentProcess().Modules.Cast<ProcessModule>().First(m => m.ModuleName == "dxgi.dll");
|
||||
var scanner = new SigScanner(module);
|
||||
|
||||
Log.Debug($"Found DXGI: 0x{module.BaseAddress.ToInt64():X}");
|
||||
// This(code after the function head - offset of it) was picked to avoid running into issues with other hooks being installed into this function.
|
||||
this.Present = scanner.ScanModule("41 8B F0 8B FA 89 54 24 ?? 48 8B D9 48 89 4D ?? C6 44 24 ?? 00") - 0x37;
|
||||
|
||||
var scanner = new SigScanner(module);
|
||||
|
||||
// This(code after the function head - offset of it) was picked to avoid running into issues with other hooks being installed into this function.
|
||||
this.Present = scanner.ScanModule("41 8B F0 8B FA 89 54 24 ?? 48 8B D9 48 89 4D ?? C6 44 24 ?? 00") - 0x37;
|
||||
|
||||
this.ResizeBuffers = scanner.ScanModule("48 8B C4 55 41 54 41 55 41 56 41 57 48 8D 68 B1 48 81 EC ?? ?? ?? ?? 48 C7 45 ?? ?? ?? ?? ?? 48 89 58 10 48 89 70 18 48 89 78 20 45 8B F9 45 8B E0 44 8B EA 48 8B F9 8B 45 7F 89 44 24 30 8B 75 77 89 74 24 28 44 89 4C 24");
|
||||
}
|
||||
this.ResizeBuffers = scanner.ScanModule("48 8B C4 55 41 54 41 55 41 56 41 57 48 8D 68 B1 48 81 EC ?? ?? ?? ?? 48 C7 45 ?? ?? ?? ?? ?? 48 89 58 10 48 89 70 18 48 89 78 20 45 8B F9 45 8B E0 44 8B EA 48 8B F9 8B 45 7F 89 44 24 30 8B 75 77 89 74 24 28 44 89 4C 24");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,97 +7,96 @@ using Dalamud.Game.Internal.DXGI.Definitions;
|
|||
using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Game.Internal.DXGI
|
||||
namespace Dalamud.Game.Internal.DXGI;
|
||||
|
||||
/// <summary>
|
||||
/// This class attempts to determine the D3D11 SwapChain vtable addresses via instantiating a new form and inspecting it.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the normal signature based method of resolution fails, this is the backup.
|
||||
/// </remarks>
|
||||
public class SwapChainVtableResolver : BaseAddressResolver, ISwapChainAddressResolver
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public IntPtr Present { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IntPtr ResizeBuffers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This class attempts to determine the D3D11 SwapChain vtable addresses via instantiating a new form and inspecting it.
|
||||
/// Gets a value indicating whether or not ReShade is loaded/used.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the normal signature based method of resolution fails, this is the backup.
|
||||
/// </remarks>
|
||||
public class SwapChainVtableResolver : BaseAddressResolver, ISwapChainAddressResolver
|
||||
public bool IsReshade { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override unsafe void Setup64Bit(SigScanner sig)
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public IntPtr Present { get; set; }
|
||||
Device* kernelDev;
|
||||
SwapChain* swapChain;
|
||||
void* dxgiSwapChain;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IntPtr ResizeBuffers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not ReShade is loaded/used.
|
||||
/// </summary>
|
||||
public bool IsReshade { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override unsafe void Setup64Bit(SigScanner sig)
|
||||
while (true)
|
||||
{
|
||||
Device* kernelDev;
|
||||
SwapChain* swapChain;
|
||||
void* dxgiSwapChain;
|
||||
kernelDev = Device.Instance();
|
||||
if (kernelDev == null)
|
||||
continue;
|
||||
|
||||
while (true)
|
||||
swapChain = kernelDev->SwapChain;
|
||||
if (swapChain == null)
|
||||
continue;
|
||||
|
||||
dxgiSwapChain = swapChain->DXGISwapChain;
|
||||
if (dxgiSwapChain == null)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
var scVtbl = GetVTblAddresses(new IntPtr(dxgiSwapChain), Enum.GetValues(typeof(IDXGISwapChainVtbl)).Length);
|
||||
|
||||
this.Present = scVtbl[(int)IDXGISwapChainVtbl.Present];
|
||||
|
||||
var modules = Process.GetCurrentProcess().Modules;
|
||||
foreach (ProcessModule processModule in modules)
|
||||
{
|
||||
if (processModule.FileName != null && processModule.FileName.EndsWith("game\\dxgi.dll"))
|
||||
{
|
||||
kernelDev = Device.Instance();
|
||||
if (kernelDev == null)
|
||||
continue;
|
||||
// reshade master@4232872 RVA
|
||||
// var p = processModule.BaseAddress + 0x82C7E0; // DXGISwapChain::Present
|
||||
// var p = processModule.BaseAddress + 0x82FAC0; // DXGISwapChain::runtime_present
|
||||
|
||||
swapChain = kernelDev->SwapChain;
|
||||
if (swapChain == null)
|
||||
continue;
|
||||
|
||||
dxgiSwapChain = swapChain->DXGISwapChain;
|
||||
if (dxgiSwapChain == null)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
var scVtbl = GetVTblAddresses(new IntPtr(dxgiSwapChain), Enum.GetValues(typeof(IDXGISwapChainVtbl)).Length);
|
||||
|
||||
this.Present = scVtbl[(int)IDXGISwapChainVtbl.Present];
|
||||
|
||||
var modules = Process.GetCurrentProcess().Modules;
|
||||
foreach (ProcessModule processModule in modules)
|
||||
{
|
||||
if (processModule.FileName != null && processModule.FileName.EndsWith("game\\dxgi.dll"))
|
||||
var scanner = new SigScanner(processModule);
|
||||
try
|
||||
{
|
||||
// reshade master@4232872 RVA
|
||||
// var p = processModule.BaseAddress + 0x82C7E0; // DXGISwapChain::Present
|
||||
// var p = processModule.BaseAddress + 0x82FAC0; // DXGISwapChain::runtime_present
|
||||
var p = scanner.ScanText("F6 C2 01 0F 85 ?? ?? ?? ??");
|
||||
Log.Information($"ReShade DLL: {processModule.FileName} with DXGISwapChain::runtime_present at {p:X}");
|
||||
|
||||
var scanner = new SigScanner(processModule);
|
||||
try
|
||||
{
|
||||
var p = scanner.ScanText("F6 C2 01 0F 85 ?? ?? ?? ??");
|
||||
Log.Information($"ReShade DLL: {processModule.FileName} with DXGISwapChain::runtime_present at {p:X}");
|
||||
|
||||
this.Present = p;
|
||||
this.IsReshade = true;
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Could not find reshade DXGISwapChain::runtime_present offset!");
|
||||
}
|
||||
this.Present = p;
|
||||
this.IsReshade = true;
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Could not find reshade DXGISwapChain::runtime_present offset!");
|
||||
}
|
||||
}
|
||||
|
||||
this.ResizeBuffers = scVtbl[(int)IDXGISwapChainVtbl.ResizeBuffers];
|
||||
}
|
||||
|
||||
private static List<IntPtr> GetVTblAddresses(IntPtr pointer, int numberOfMethods)
|
||||
{
|
||||
return GetVTblAddresses(pointer, 0, numberOfMethods);
|
||||
}
|
||||
this.ResizeBuffers = scVtbl[(int)IDXGISwapChainVtbl.ResizeBuffers];
|
||||
}
|
||||
|
||||
private static List<IntPtr> GetVTblAddresses(IntPtr pointer, int startIndex, int numberOfMethods)
|
||||
{
|
||||
var vtblAddresses = new List<IntPtr>();
|
||||
var vTable = Marshal.ReadIntPtr(pointer);
|
||||
for (var i = startIndex; i < startIndex + numberOfMethods; i++)
|
||||
vtblAddresses.Add(Marshal.ReadIntPtr(vTable, i * IntPtr.Size)); // using IntPtr.Size allows us to support both 32 and 64-bit processes
|
||||
private static List<IntPtr> GetVTblAddresses(IntPtr pointer, int numberOfMethods)
|
||||
{
|
||||
return GetVTblAddresses(pointer, 0, numberOfMethods);
|
||||
}
|
||||
|
||||
return vtblAddresses;
|
||||
}
|
||||
private static List<IntPtr> GetVTblAddresses(IntPtr pointer, int startIndex, int numberOfMethods)
|
||||
{
|
||||
var vtblAddresses = new List<IntPtr>();
|
||||
var vTable = Marshal.ReadIntPtr(pointer);
|
||||
for (var i = startIndex; i < startIndex + numberOfMethods; i++)
|
||||
vtblAddresses.Add(Marshal.ReadIntPtr(vTable, i * IntPtr.Size)); // using IntPtr.Size allows us to support both 32 and 64-bit processes
|
||||
|
||||
return vtblAddresses;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,265 +14,264 @@ using Serilog;
|
|||
|
||||
using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType;
|
||||
|
||||
namespace Dalamud.Game.Internal
|
||||
namespace Dalamud.Game.Internal;
|
||||
|
||||
/// <summary>
|
||||
/// This class implements in-game Dalamud options in the in-game System menu.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal sealed unsafe partial class DalamudAtkTweaks : IServiceType
|
||||
{
|
||||
/// <summary>
|
||||
/// This class implements in-game Dalamud options in the in-game System menu.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal sealed unsafe partial class DalamudAtkTweaks : IServiceType
|
||||
private readonly AtkValueChangeType atkValueChangeType;
|
||||
private readonly AtkValueSetString atkValueSetString;
|
||||
private readonly Hook<AgentHudOpenSystemMenuPrototype> hookAgentHudOpenSystemMenu;
|
||||
|
||||
// TODO: Make this into events in Framework.Gui
|
||||
private readonly Hook<UiModuleRequestMainCommand> hookUiModuleRequestMainCommand;
|
||||
|
||||
private readonly Hook<AtkUnitBaseReceiveGlobalEvent> hookAtkUnitBaseReceiveGlobalEvent;
|
||||
|
||||
[ServiceManager.ServiceDependency]
|
||||
private readonly DalamudConfiguration configuration = Service<DalamudConfiguration>.Get();
|
||||
|
||||
// [ServiceManager.ServiceDependency]
|
||||
// private readonly ContextMenu contextMenu = Service<ContextMenu>.Get();
|
||||
|
||||
private readonly string locDalamudPlugins;
|
||||
private readonly string locDalamudSettings;
|
||||
|
||||
[ServiceManager.ServiceConstructor]
|
||||
private DalamudAtkTweaks(SigScanner sigScanner)
|
||||
{
|
||||
private readonly AtkValueChangeType atkValueChangeType;
|
||||
private readonly AtkValueSetString atkValueSetString;
|
||||
private readonly Hook<AgentHudOpenSystemMenuPrototype> hookAgentHudOpenSystemMenu;
|
||||
var openSystemMenuAddress = sigScanner.ScanText("E8 ?? ?? ?? ?? 32 C0 4C 8B AC 24 ?? ?? ?? ?? 48 8B 8D ?? ?? ?? ??");
|
||||
|
||||
// TODO: Make this into events in Framework.Gui
|
||||
private readonly Hook<UiModuleRequestMainCommand> hookUiModuleRequestMainCommand;
|
||||
this.hookAgentHudOpenSystemMenu = Hook<AgentHudOpenSystemMenuPrototype>.FromAddress(openSystemMenuAddress, this.AgentHudOpenSystemMenuDetour);
|
||||
|
||||
private readonly Hook<AtkUnitBaseReceiveGlobalEvent> hookAtkUnitBaseReceiveGlobalEvent;
|
||||
var atkValueChangeTypeAddress = sigScanner.ScanText("E8 ?? ?? ?? ?? 45 84 F6 48 8D 4C 24 ??");
|
||||
this.atkValueChangeType = Marshal.GetDelegateForFunctionPointer<AtkValueChangeType>(atkValueChangeTypeAddress);
|
||||
|
||||
[ServiceManager.ServiceDependency]
|
||||
private readonly DalamudConfiguration configuration = Service<DalamudConfiguration>.Get();
|
||||
var atkValueSetStringAddress = sigScanner.ScanText("E8 ?? ?? ?? ?? 41 03 ED");
|
||||
this.atkValueSetString = Marshal.GetDelegateForFunctionPointer<AtkValueSetString>(atkValueSetStringAddress);
|
||||
|
||||
// [ServiceManager.ServiceDependency]
|
||||
// private readonly ContextMenu contextMenu = Service<ContextMenu>.Get();
|
||||
var uiModuleRequestMainCommandAddress = sigScanner.ScanText("40 53 56 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 48 8B 01 8B DA 48 8B F1 FF 90 ?? ?? ?? ??");
|
||||
this.hookUiModuleRequestMainCommand = Hook<UiModuleRequestMainCommand>.FromAddress(uiModuleRequestMainCommandAddress, this.UiModuleRequestMainCommandDetour);
|
||||
|
||||
private readonly string locDalamudPlugins;
|
||||
private readonly string locDalamudSettings;
|
||||
var atkUnitBaseReceiveGlobalEventAddress = sigScanner.ScanText("48 89 5C 24 ?? 48 89 7C 24 ?? 55 41 56 41 57 48 8B EC 48 83 EC 50 44 0F B7 F2 ");
|
||||
this.hookAtkUnitBaseReceiveGlobalEvent = Hook<AtkUnitBaseReceiveGlobalEvent>.FromAddress(atkUnitBaseReceiveGlobalEventAddress, this.AtkUnitBaseReceiveGlobalEventDetour);
|
||||
|
||||
[ServiceManager.ServiceConstructor]
|
||||
private DalamudAtkTweaks(SigScanner sigScanner)
|
||||
{
|
||||
var openSystemMenuAddress = sigScanner.ScanText("E8 ?? ?? ?? ?? 32 C0 4C 8B AC 24 ?? ?? ?? ?? 48 8B 8D ?? ?? ?? ??");
|
||||
this.locDalamudPlugins = Loc.Localize("SystemMenuPlugins", "Dalamud Plugins");
|
||||
this.locDalamudSettings = Loc.Localize("SystemMenuSettings", "Dalamud Settings");
|
||||
|
||||
this.hookAgentHudOpenSystemMenu = Hook<AgentHudOpenSystemMenuPrototype>.FromAddress(openSystemMenuAddress, this.AgentHudOpenSystemMenuDetour);
|
||||
|
||||
var atkValueChangeTypeAddress = sigScanner.ScanText("E8 ?? ?? ?? ?? 45 84 F6 48 8D 4C 24 ??");
|
||||
this.atkValueChangeType = Marshal.GetDelegateForFunctionPointer<AtkValueChangeType>(atkValueChangeTypeAddress);
|
||||
|
||||
var atkValueSetStringAddress = sigScanner.ScanText("E8 ?? ?? ?? ?? 41 03 ED");
|
||||
this.atkValueSetString = Marshal.GetDelegateForFunctionPointer<AtkValueSetString>(atkValueSetStringAddress);
|
||||
|
||||
var uiModuleRequestMainCommandAddress = sigScanner.ScanText("40 53 56 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 48 8B 01 8B DA 48 8B F1 FF 90 ?? ?? ?? ??");
|
||||
this.hookUiModuleRequestMainCommand = Hook<UiModuleRequestMainCommand>.FromAddress(uiModuleRequestMainCommandAddress, this.UiModuleRequestMainCommandDetour);
|
||||
|
||||
var atkUnitBaseReceiveGlobalEventAddress = sigScanner.ScanText("48 89 5C 24 ?? 48 89 7C 24 ?? 55 41 56 41 57 48 8B EC 48 83 EC 50 44 0F B7 F2 ");
|
||||
this.hookAtkUnitBaseReceiveGlobalEvent = Hook<AtkUnitBaseReceiveGlobalEvent>.FromAddress(atkUnitBaseReceiveGlobalEventAddress, this.AtkUnitBaseReceiveGlobalEventDetour);
|
||||
|
||||
this.locDalamudPlugins = Loc.Localize("SystemMenuPlugins", "Dalamud Plugins");
|
||||
this.locDalamudSettings = Loc.Localize("SystemMenuSettings", "Dalamud Settings");
|
||||
|
||||
// this.contextMenu.ContextMenuOpened += this.ContextMenuOnContextMenuOpened;
|
||||
}
|
||||
|
||||
private delegate void AgentHudOpenSystemMenuPrototype(void* thisPtr, AtkValue* atkValueArgs, uint menuSize);
|
||||
|
||||
private delegate void AtkValueChangeType(AtkValue* thisPtr, ValueType type);
|
||||
|
||||
private delegate void AtkValueSetString(AtkValue* thisPtr, byte* bytes);
|
||||
|
||||
private delegate void UiModuleRequestMainCommand(void* thisPtr, int commandId);
|
||||
|
||||
private delegate IntPtr AtkUnitBaseReceiveGlobalEvent(AtkUnitBase* thisPtr, ushort cmd, uint a3, IntPtr a4, uint* a5);
|
||||
|
||||
[ServiceManager.CallWhenServicesReady]
|
||||
private void ContinueConstruction(DalamudInterface dalamudInterface)
|
||||
{
|
||||
this.hookAgentHudOpenSystemMenu.Enable();
|
||||
this.hookUiModuleRequestMainCommand.Enable();
|
||||
this.hookAtkUnitBaseReceiveGlobalEvent.Enable();
|
||||
}
|
||||
|
||||
/*
|
||||
private void ContextMenuOnContextMenuOpened(ContextMenuOpenedArgs args)
|
||||
{
|
||||
var systemText = Service<DataManager>.GetNullable()?.GetExcelSheet<Addon>()?.GetRow(1059)?.Text?.RawString; // "System"
|
||||
var interfaceManager = Service<InterfaceManager>.GetNullable();
|
||||
|
||||
if (systemText == null || interfaceManager == null)
|
||||
return;
|
||||
|
||||
if (args.Title == systemText && this.configuration.DoButtonsSystemMenu && interfaceManager.IsDispatchingEvents)
|
||||
{
|
||||
var dalamudInterface = Service<DalamudInterface>.Get();
|
||||
|
||||
args.Items.Insert(0, new CustomContextMenuItem(this.locDalamudSettings, selectedArgs =>
|
||||
{
|
||||
dalamudInterface.ToggleSettingsWindow();
|
||||
}));
|
||||
|
||||
args.Items.Insert(0, new CustomContextMenuItem(this.locDalamudPlugins, selectedArgs =>
|
||||
{
|
||||
dalamudInterface.TogglePluginInstallerWindow();
|
||||
}));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
private IntPtr AtkUnitBaseReceiveGlobalEventDetour(AtkUnitBase* thisPtr, ushort cmd, uint a3, IntPtr a4, uint* arg)
|
||||
{
|
||||
// Log.Information("{0}: cmd#{1} a3#{2} - HasAnyFocus:{3}", Marshal.PtrToStringAnsi(new IntPtr(thisPtr->Name)), cmd, a3, WindowSystem.HasAnyWindowSystemFocus);
|
||||
|
||||
// "SendHotkey"
|
||||
// 3 == Close
|
||||
if (cmd == 12 && WindowSystem.HasAnyWindowSystemFocus && *arg == 3 && this.configuration.IsFocusManagementEnabled)
|
||||
{
|
||||
Log.Verbose($"Cancelling global event SendHotkey command due to WindowSystem {WindowSystem.FocusedWindowSystemNamespace}");
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
return this.hookAtkUnitBaseReceiveGlobalEvent.Original(thisPtr, cmd, a3, a4, arg);
|
||||
}
|
||||
|
||||
private void AgentHudOpenSystemMenuDetour(void* thisPtr, AtkValue* atkValueArgs, uint menuSize)
|
||||
{
|
||||
if (WindowSystem.HasAnyWindowSystemFocus && this.configuration.IsFocusManagementEnabled)
|
||||
{
|
||||
Log.Verbose($"Cancelling OpenSystemMenu due to WindowSystem {WindowSystem.FocusedWindowSystemNamespace}");
|
||||
return;
|
||||
}
|
||||
|
||||
var interfaceManager = Service<InterfaceManager>.GetNullable();
|
||||
if (interfaceManager == null)
|
||||
{
|
||||
this.hookAgentHudOpenSystemMenu.Original(thisPtr, atkValueArgs, menuSize);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.configuration.DoButtonsSystemMenu || !interfaceManager.IsDispatchingEvents)
|
||||
{
|
||||
this.hookAgentHudOpenSystemMenu.Original(thisPtr, atkValueArgs, menuSize);
|
||||
return;
|
||||
}
|
||||
|
||||
// the max size (hardcoded) is 0x11/17, but the system menu currently uses 0xC/12
|
||||
// this is a just in case that doesnt really matter
|
||||
// see if we can add 2 entries
|
||||
if (menuSize >= 0x11)
|
||||
{
|
||||
this.hookAgentHudOpenSystemMenu.Original(thisPtr, atkValueArgs, menuSize);
|
||||
return;
|
||||
}
|
||||
|
||||
// atkValueArgs is actually an array of AtkValues used as args. all their UI code works like this.
|
||||
// in this case, menu size is stored in atkValueArgs[4], and the next 17 slots are the MainCommand
|
||||
// the 17 slots after that, if they exist, are the entry names, but they are otherwise pulled from MainCommand EXD
|
||||
// reference the original function for more details :)
|
||||
|
||||
// step 1) move all the current menu items down so we can put Dalamud at the top like it deserves
|
||||
this.atkValueChangeType(&atkValueArgs[menuSize + 5], ValueType.Int); // currently this value has no type, set it to int
|
||||
this.atkValueChangeType(&atkValueArgs[menuSize + 5 + 1], ValueType.Int);
|
||||
|
||||
for (var i = menuSize + 2; i > 1; i--)
|
||||
{
|
||||
var curEntry = &atkValueArgs[i + 5 - 2];
|
||||
var nextEntry = &atkValueArgs[i + 5];
|
||||
|
||||
nextEntry->Int = curEntry->Int;
|
||||
}
|
||||
|
||||
// step 2) set our new entries to dummy commands
|
||||
var firstEntry = &atkValueArgs[5];
|
||||
firstEntry->Int = 69420;
|
||||
var secondEntry = &atkValueArgs[6];
|
||||
secondEntry->Int = 69421;
|
||||
|
||||
// step 3) create strings for them
|
||||
// since the game first checks for strings in the AtkValue argument before pulling them from the exd, if we create strings we dont have to worry
|
||||
// about hooking the exd reader, thank god
|
||||
var firstStringEntry = &atkValueArgs[5 + 17];
|
||||
this.atkValueChangeType(firstStringEntry, ValueType.String);
|
||||
var secondStringEntry = &atkValueArgs[6 + 17];
|
||||
this.atkValueChangeType(secondStringEntry, ValueType.String);
|
||||
|
||||
const int color = 539;
|
||||
var strPlugins = new SeString().Append(new UIForegroundPayload(color))
|
||||
.Append($"{SeIconChar.BoxedLetterD.ToIconString()} ")
|
||||
.Append(new UIForegroundPayload(0))
|
||||
.Append(this.locDalamudPlugins).Encode();
|
||||
var strSettings = new SeString().Append(new UIForegroundPayload(color))
|
||||
.Append($"{SeIconChar.BoxedLetterD.ToIconString()} ")
|
||||
.Append(new UIForegroundPayload(0))
|
||||
.Append(this.locDalamudSettings).Encode();
|
||||
|
||||
// do this the most terrible way possible since im lazy
|
||||
var bytes = stackalloc byte[strPlugins.Length + 1];
|
||||
Marshal.Copy(strPlugins, 0, new IntPtr(bytes), strPlugins.Length);
|
||||
bytes[strPlugins.Length] = 0x0;
|
||||
|
||||
this.atkValueSetString(firstStringEntry, bytes); // this allocs the string properly using the game's allocators and copies it, so we dont have to worry about memory fuckups
|
||||
|
||||
var bytes2 = stackalloc byte[strSettings.Length + 1];
|
||||
Marshal.Copy(strSettings, 0, new IntPtr(bytes2), strSettings.Length);
|
||||
bytes2[strSettings.Length] = 0x0;
|
||||
|
||||
this.atkValueSetString(secondStringEntry, bytes2);
|
||||
|
||||
// open menu with new size
|
||||
var sizeEntry = &atkValueArgs[4];
|
||||
sizeEntry->UInt = menuSize + 2;
|
||||
|
||||
this.hookAgentHudOpenSystemMenu.Original(thisPtr, atkValueArgs, menuSize + 2);
|
||||
}
|
||||
|
||||
private void UiModuleRequestMainCommandDetour(void* thisPtr, int commandId)
|
||||
{
|
||||
var dalamudInterface = Service<DalamudInterface>.GetNullable();
|
||||
|
||||
switch (commandId)
|
||||
{
|
||||
case 69420:
|
||||
dalamudInterface?.TogglePluginInstallerWindow();
|
||||
break;
|
||||
case 69421:
|
||||
dalamudInterface?.ToggleSettingsWindow();
|
||||
break;
|
||||
default:
|
||||
this.hookUiModuleRequestMainCommand.Original(thisPtr, commandId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// this.contextMenu.ContextMenuOpened += this.ContextMenuOnContextMenuOpened;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements IDisposable.
|
||||
/// </summary>
|
||||
internal sealed partial class DalamudAtkTweaks : IDisposable
|
||||
private delegate void AgentHudOpenSystemMenuPrototype(void* thisPtr, AtkValue* atkValueArgs, uint menuSize);
|
||||
|
||||
private delegate void AtkValueChangeType(AtkValue* thisPtr, ValueType type);
|
||||
|
||||
private delegate void AtkValueSetString(AtkValue* thisPtr, byte* bytes);
|
||||
|
||||
private delegate void UiModuleRequestMainCommand(void* thisPtr, int commandId);
|
||||
|
||||
private delegate IntPtr AtkUnitBaseReceiveGlobalEvent(AtkUnitBase* thisPtr, ushort cmd, uint a3, IntPtr a4, uint* a5);
|
||||
|
||||
[ServiceManager.CallWhenServicesReady]
|
||||
private void ContinueConstruction(DalamudInterface dalamudInterface)
|
||||
{
|
||||
private bool disposed = false;
|
||||
this.hookAgentHudOpenSystemMenu.Enable();
|
||||
this.hookUiModuleRequestMainCommand.Enable();
|
||||
this.hookAtkUnitBaseReceiveGlobalEvent.Enable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="DalamudAtkTweaks"/> class.
|
||||
/// </summary>
|
||||
~DalamudAtkTweaks() => this.Dispose(false);
|
||||
/*
|
||||
private void ContextMenuOnContextMenuOpened(ContextMenuOpenedArgs args)
|
||||
{
|
||||
var systemText = Service<DataManager>.GetNullable()?.GetExcelSheet<Addon>()?.GetRow(1059)?.Text?.RawString; // "System"
|
||||
var interfaceManager = Service<InterfaceManager>.GetNullable();
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of managed and unmanaged resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
if (systemText == null || interfaceManager == null)
|
||||
return;
|
||||
|
||||
if (args.Title == systemText && this.configuration.DoButtonsSystemMenu && interfaceManager.IsDispatchingEvents)
|
||||
{
|
||||
this.Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
var dalamudInterface = Service<DalamudInterface>.Get();
|
||||
|
||||
args.Items.Insert(0, new CustomContextMenuItem(this.locDalamudSettings, selectedArgs =>
|
||||
{
|
||||
dalamudInterface.ToggleSettingsWindow();
|
||||
}));
|
||||
|
||||
args.Items.Insert(0, new CustomContextMenuItem(this.locDalamudPlugins, selectedArgs =>
|
||||
{
|
||||
dalamudInterface.TogglePluginInstallerWindow();
|
||||
}));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
private IntPtr AtkUnitBaseReceiveGlobalEventDetour(AtkUnitBase* thisPtr, ushort cmd, uint a3, IntPtr a4, uint* arg)
|
||||
{
|
||||
// Log.Information("{0}: cmd#{1} a3#{2} - HasAnyFocus:{3}", Marshal.PtrToStringAnsi(new IntPtr(thisPtr->Name)), cmd, a3, WindowSystem.HasAnyWindowSystemFocus);
|
||||
|
||||
// "SendHotkey"
|
||||
// 3 == Close
|
||||
if (cmd == 12 && WindowSystem.HasAnyWindowSystemFocus && *arg == 3 && this.configuration.IsFocusManagementEnabled)
|
||||
{
|
||||
Log.Verbose($"Cancelling global event SendHotkey command due to WindowSystem {WindowSystem.FocusedWindowSystemNamespace}");
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of managed and unmanaged resources.
|
||||
/// </summary>
|
||||
private void Dispose(bool disposing)
|
||||
return this.hookAtkUnitBaseReceiveGlobalEvent.Original(thisPtr, cmd, a3, a4, arg);
|
||||
}
|
||||
|
||||
private void AgentHudOpenSystemMenuDetour(void* thisPtr, AtkValue* atkValueArgs, uint menuSize)
|
||||
{
|
||||
if (WindowSystem.HasAnyWindowSystemFocus && this.configuration.IsFocusManagementEnabled)
|
||||
{
|
||||
if (this.disposed)
|
||||
return;
|
||||
Log.Verbose($"Cancelling OpenSystemMenu due to WindowSystem {WindowSystem.FocusedWindowSystemNamespace}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
this.hookAgentHudOpenSystemMenu.Dispose();
|
||||
this.hookUiModuleRequestMainCommand.Dispose();
|
||||
this.hookAtkUnitBaseReceiveGlobalEvent.Dispose();
|
||||
var interfaceManager = Service<InterfaceManager>.GetNullable();
|
||||
if (interfaceManager == null)
|
||||
{
|
||||
this.hookAgentHudOpenSystemMenu.Original(thisPtr, atkValueArgs, menuSize);
|
||||
return;
|
||||
}
|
||||
|
||||
// this.contextMenu.ContextMenuOpened -= this.ContextMenuOnContextMenuOpened;
|
||||
}
|
||||
if (!this.configuration.DoButtonsSystemMenu || !interfaceManager.IsDispatchingEvents)
|
||||
{
|
||||
this.hookAgentHudOpenSystemMenu.Original(thisPtr, atkValueArgs, menuSize);
|
||||
return;
|
||||
}
|
||||
|
||||
this.disposed = true;
|
||||
// the max size (hardcoded) is 0x11/17, but the system menu currently uses 0xC/12
|
||||
// this is a just in case that doesnt really matter
|
||||
// see if we can add 2 entries
|
||||
if (menuSize >= 0x11)
|
||||
{
|
||||
this.hookAgentHudOpenSystemMenu.Original(thisPtr, atkValueArgs, menuSize);
|
||||
return;
|
||||
}
|
||||
|
||||
// atkValueArgs is actually an array of AtkValues used as args. all their UI code works like this.
|
||||
// in this case, menu size is stored in atkValueArgs[4], and the next 17 slots are the MainCommand
|
||||
// the 17 slots after that, if they exist, are the entry names, but they are otherwise pulled from MainCommand EXD
|
||||
// reference the original function for more details :)
|
||||
|
||||
// step 1) move all the current menu items down so we can put Dalamud at the top like it deserves
|
||||
this.atkValueChangeType(&atkValueArgs[menuSize + 5], ValueType.Int); // currently this value has no type, set it to int
|
||||
this.atkValueChangeType(&atkValueArgs[menuSize + 5 + 1], ValueType.Int);
|
||||
|
||||
for (var i = menuSize + 2; i > 1; i--)
|
||||
{
|
||||
var curEntry = &atkValueArgs[i + 5 - 2];
|
||||
var nextEntry = &atkValueArgs[i + 5];
|
||||
|
||||
nextEntry->Int = curEntry->Int;
|
||||
}
|
||||
|
||||
// step 2) set our new entries to dummy commands
|
||||
var firstEntry = &atkValueArgs[5];
|
||||
firstEntry->Int = 69420;
|
||||
var secondEntry = &atkValueArgs[6];
|
||||
secondEntry->Int = 69421;
|
||||
|
||||
// step 3) create strings for them
|
||||
// since the game first checks for strings in the AtkValue argument before pulling them from the exd, if we create strings we dont have to worry
|
||||
// about hooking the exd reader, thank god
|
||||
var firstStringEntry = &atkValueArgs[5 + 17];
|
||||
this.atkValueChangeType(firstStringEntry, ValueType.String);
|
||||
var secondStringEntry = &atkValueArgs[6 + 17];
|
||||
this.atkValueChangeType(secondStringEntry, ValueType.String);
|
||||
|
||||
const int color = 539;
|
||||
var strPlugins = new SeString().Append(new UIForegroundPayload(color))
|
||||
.Append($"{SeIconChar.BoxedLetterD.ToIconString()} ")
|
||||
.Append(new UIForegroundPayload(0))
|
||||
.Append(this.locDalamudPlugins).Encode();
|
||||
var strSettings = new SeString().Append(new UIForegroundPayload(color))
|
||||
.Append($"{SeIconChar.BoxedLetterD.ToIconString()} ")
|
||||
.Append(new UIForegroundPayload(0))
|
||||
.Append(this.locDalamudSettings).Encode();
|
||||
|
||||
// do this the most terrible way possible since im lazy
|
||||
var bytes = stackalloc byte[strPlugins.Length + 1];
|
||||
Marshal.Copy(strPlugins, 0, new IntPtr(bytes), strPlugins.Length);
|
||||
bytes[strPlugins.Length] = 0x0;
|
||||
|
||||
this.atkValueSetString(firstStringEntry, bytes); // this allocs the string properly using the game's allocators and copies it, so we dont have to worry about memory fuckups
|
||||
|
||||
var bytes2 = stackalloc byte[strSettings.Length + 1];
|
||||
Marshal.Copy(strSettings, 0, new IntPtr(bytes2), strSettings.Length);
|
||||
bytes2[strSettings.Length] = 0x0;
|
||||
|
||||
this.atkValueSetString(secondStringEntry, bytes2);
|
||||
|
||||
// open menu with new size
|
||||
var sizeEntry = &atkValueArgs[4];
|
||||
sizeEntry->UInt = menuSize + 2;
|
||||
|
||||
this.hookAgentHudOpenSystemMenu.Original(thisPtr, atkValueArgs, menuSize + 2);
|
||||
}
|
||||
|
||||
private void UiModuleRequestMainCommandDetour(void* thisPtr, int commandId)
|
||||
{
|
||||
var dalamudInterface = Service<DalamudInterface>.GetNullable();
|
||||
|
||||
switch (commandId)
|
||||
{
|
||||
case 69420:
|
||||
dalamudInterface?.TogglePluginInstallerWindow();
|
||||
break;
|
||||
case 69421:
|
||||
dalamudInterface?.ToggleSettingsWindow();
|
||||
break;
|
||||
default:
|
||||
this.hookUiModuleRequestMainCommand.Original(thisPtr, commandId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements IDisposable.
|
||||
/// </summary>
|
||||
internal sealed partial class DalamudAtkTweaks : IDisposable
|
||||
{
|
||||
private bool disposed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="DalamudAtkTweaks"/> class.
|
||||
/// </summary>
|
||||
~DalamudAtkTweaks() => this.Dispose(false);
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of managed and unmanaged resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
this.Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of managed and unmanaged resources.
|
||||
/// </summary>
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (this.disposed)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
this.hookAgentHudOpenSystemMenu.Dispose();
|
||||
this.hookUiModuleRequestMainCommand.Dispose();
|
||||
this.hookAtkUnitBaseReceiveGlobalEvent.Dispose();
|
||||
|
||||
// this.contextMenu.ContextMenuOpened -= this.ContextMenuOnContextMenuOpened;
|
||||
}
|
||||
|
||||
this.disposed = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue