mirror of
https://github.com/goatcorp/Dalamud.git
synced 2026-02-18 13:57:43 +01:00
Add IInternal/PublicDisposableService (#1696)
* Add IInternal/PublicDisposableService Plugins are exposed interfaces that are not inherited from `IDisposable`, but services implementing plugin interfaces often implement `IDisposable`. Some plugins may try to call `IDisposable.Dispose` on everything provided, and it also is possible to use `using` clause too eagerly while working on Dalamud itself, such as writing `using var smth = await Service<SomeService>.GetAsync();`. Such behaviors often lead to a difficult-to-debug errors, and making those services either not an `IDisposable` or making `IDisposable.Dispose` do nothing if the object has been loaded would prevent such errors. As `ServiceManager` must be the only class dealing with construction and disposal of services, `IInternalDisposableService` has been added to limit who can dispose the object. `IPublicDisposableService` also has been added to classes that can be constructed and accessed directly by plugins; for those, `Dispose` will be ignored if the instance is a service instance, and only `DisposeService` will respond. In addition, `DalamudPluginInterface` and `UiBuilder` also have been changed so that their `IDisposable.Dispose` no longer respond, and instead, internal functions have been added to only allow disposal from Dalamud. * Cleanup * Postmerge fixes * More explanation on RunOnFrameworkThread(ClearHooks) * Mark ReliableFileStorage public ctor obsolete --------- Co-authored-by: goat <16760685+goaaats@users.noreply.github.com>
This commit is contained in:
parent
dcec076ca7
commit
87b9edb448
62 changed files with 441 additions and 381 deletions
|
|
@ -12,7 +12,7 @@ namespace Dalamud.Game.Internal;
|
|||
/// This class disables anti-debug functionality in the game client.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal sealed partial class AntiDebug : IServiceType
|
||||
internal sealed class AntiDebug : IInternalDisposableService
|
||||
{
|
||||
private readonly byte[] nop = new byte[] { 0x31, 0xC0, 0x90, 0x90, 0x90, 0x90 };
|
||||
private byte[] original;
|
||||
|
|
@ -43,16 +43,25 @@ internal sealed partial class AntiDebug : IServiceType
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Finalizes an instance of the <see cref="AntiDebug"/> class.</summary>
|
||||
~AntiDebug() => this.Disable();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the anti-debugging is enabled.
|
||||
/// </summary>
|
||||
public bool IsEnabled { get; private set; } = false;
|
||||
|
||||
/// <inheritdoc />
|
||||
void IInternalDisposableService.DisposeService() => this.Disable();
|
||||
|
||||
/// <summary>
|
||||
/// Enables the anti-debugging by overwriting code in memory.
|
||||
/// </summary>
|
||||
public void Enable()
|
||||
{
|
||||
if (this.IsEnabled)
|
||||
return;
|
||||
|
||||
this.original = new byte[this.nop.Length];
|
||||
if (this.debugCheckAddress != IntPtr.Zero && !this.IsEnabled)
|
||||
{
|
||||
|
|
@ -73,6 +82,9 @@ internal sealed partial class AntiDebug : IServiceType
|
|||
/// </summary>
|
||||
public void Disable()
|
||||
{
|
||||
if (!this.IsEnabled)
|
||||
return;
|
||||
|
||||
if (this.debugCheckAddress != IntPtr.Zero && this.original != null)
|
||||
{
|
||||
Log.Information($"Reverting debug check at 0x{this.debugCheckAddress.ToInt64():X}");
|
||||
|
|
@ -86,45 +98,3 @@ internal sealed partial class AntiDebug : IServiceType
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace Dalamud.Game.Internal;
|
|||
/// This class implements in-game Dalamud options in the in-game System menu.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal sealed unsafe partial class DalamudAtkTweaks : IServiceType
|
||||
internal sealed unsafe class DalamudAtkTweaks : IInternalDisposableService
|
||||
{
|
||||
private readonly AtkValueChangeType atkValueChangeType;
|
||||
private readonly AtkValueSetString atkValueSetString;
|
||||
|
|
@ -40,6 +40,8 @@ internal sealed unsafe partial class DalamudAtkTweaks : IServiceType
|
|||
private readonly string locDalamudPlugins;
|
||||
private readonly string locDalamudSettings;
|
||||
|
||||
private bool disposed = false;
|
||||
|
||||
[ServiceManager.ServiceConstructor]
|
||||
private DalamudAtkTweaks(TargetSigScanner sigScanner)
|
||||
{
|
||||
|
|
@ -69,6 +71,9 @@ internal sealed unsafe partial class DalamudAtkTweaks : IServiceType
|
|||
this.hookAtkUnitBaseReceiveGlobalEvent.Enable();
|
||||
}
|
||||
|
||||
/// <summary>Finalizes an instance of the <see cref="DalamudAtkTweaks"/> class.</summary>
|
||||
~DalamudAtkTweaks() => this.Dispose(false);
|
||||
|
||||
private delegate void AgentHudOpenSystemMenuPrototype(void* thisPtr, AtkValue* atkValueArgs, uint menuSize);
|
||||
|
||||
private delegate void AtkValueChangeType(AtkValue* thisPtr, ValueType type);
|
||||
|
|
@ -79,6 +84,26 @@ internal sealed unsafe partial class DalamudAtkTweaks : IServiceType
|
|||
|
||||
private delegate IntPtr AtkUnitBaseReceiveGlobalEvent(AtkUnitBase* thisPtr, ushort cmd, uint a3, IntPtr a4, uint* a5);
|
||||
|
||||
/// <inheritdoc/>
|
||||
void IInternalDisposableService.DisposeService() => this.Dispose(true);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
private void ContextMenuOnContextMenuOpened(ContextMenuOpenedArgs args)
|
||||
{
|
||||
|
|
@ -229,45 +254,3 @@ internal sealed unsafe partial class DalamudAtkTweaks : IServiceType
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <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