Merge branch 'v9' into ihookprovider

This commit is contained in:
goat 2023-09-23 10:57:09 +02:00 committed by GitHub
commit 7a182b6ef7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 446 additions and 285 deletions

View file

@ -1,10 +1,8 @@
using System;
using System.IO;
using Dalamud.Configuration.Internal;
using Dalamud.Game.Command;
using Dalamud.Interface.Windowing;
using Dalamud.Logging;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using Dalamud.Utility;
@ -52,6 +50,8 @@ namespace Dalamud.CorePlugin
private readonly WindowSystem windowSystem = new("Dalamud.CorePlugin");
private Localization localization;
private IPluginLog pluginLog;
/// <summary>
/// Initializes a new instance of the <see cref="PluginImpl"/> class.
/// </summary>
@ -63,6 +63,7 @@ namespace Dalamud.CorePlugin
{
// this.InitLoc();
this.Interface = pluginInterface;
this.pluginLog = log;
this.windowSystem.AddWindow(new PluginWindow());
@ -76,7 +77,7 @@ namespace Dalamud.CorePlugin
}
catch (Exception ex)
{
PluginLog.Error(ex, "kaboom");
log.Error(ex, "kaboom");
}
}
@ -130,13 +131,13 @@ namespace Dalamud.CorePlugin
}
catch (Exception ex)
{
PluginLog.Error(ex, "Boom");
this.pluginLog.Error(ex, "Boom");
}
}
private void OnCommand(string command, string args)
{
PluginLog.Information("Command called!");
this.pluginLog.Information("Command called!");
// this.window.IsOpen = true;
}

View file

@ -55,18 +55,6 @@ internal sealed partial class BuddyList : IServiceType, IBuddyList
}
}
/// <summary>
/// Gets a value indicating whether the local player's companion is present.
/// </summary>
[Obsolete("Use CompanionBuddy != null", false)]
public bool CompanionBuddyPresent => this.CompanionBuddy != null;
/// <summary>
/// Gets a value indicating whether the local player's pet is present.
/// </summary>
[Obsolete("Use PetBuddy != null", false)]
public bool PetBuddyPresent => this.PetBuddy != null;
/// <inheritdoc/>
public BuddyMember? CompanionBuddy
{

View file

@ -8,24 +8,25 @@ using Dalamud.Game.Network.Internal;
using Dalamud.Hooking;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Logging.Internal;
using Dalamud.Plugin.Services;
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.Game;
using Serilog;
using Lumina.Excel.GeneratedSheets;
using Action = System.Action;
namespace Dalamud.Game.ClientState;
/// <summary>
/// This class represents the state of the game client at the time of access.
/// </summary>
[PluginInterface]
[InterfaceVersion("1.0")]
[ServiceManager.BlockingEarlyLoadedService]
#pragma warning disable SA1015
[ResolveVia<IClientState>]
#pragma warning restore SA1015
internal sealed class ClientState : IDisposable, IServiceType, IClientState
{
private static readonly ModuleLog Log = new("ClientState");
private readonly GameLifecycle lifecycle;
private readonly ClientStateAddressResolver address;
private readonly Hook<SetupTerritoryTypeDelegate> setupTerritoryTypeHook;
@ -37,7 +38,7 @@ internal sealed class ClientState : IDisposable, IServiceType, IClientState
private readonly NetworkHandlers networkHandlers = Service<NetworkHandlers>.Get();
private bool lastConditionNone = true;
private bool lastFramePvP = false;
private bool lastFramePvP;
[ServiceManager.ServiceConstructor]
private ClientState(SigScanner sigScanner, DalamudStartInfo startInfo, GameLifecycle lifecycle)
@ -63,22 +64,22 @@ internal sealed class ClientState : IDisposable, IServiceType, IClientState
private delegate IntPtr SetupTerritoryTypeDelegate(IntPtr manager, ushort terriType);
/// <inheritdoc/>
public event EventHandler<ushort> TerritoryChanged;
public event Action<ushort>? TerritoryChanged;
/// <inheritdoc/>
public event EventHandler Login;
public event Action? Login;
/// <inheritdoc/>
public event EventHandler Logout;
public event Action? Logout;
/// <inheritdoc/>
public event Action EnterPvP;
public event Action? EnterPvP;
/// <inheritdoc/>
public event Action LeavePvP;
public event Action? LeavePvP;
/// <inheritdoc/>
public event EventHandler<Lumina.Excel.GeneratedSheets.ContentFinderCondition> CfPop;
public event Action<ContentFinderCondition>? CfPop;
/// <inheritdoc/>
public ClientLanguage ClientLanguage { get; }
@ -128,16 +129,16 @@ internal sealed class ClientState : IDisposable, IServiceType, IClientState
private IntPtr SetupTerritoryTypeDetour(IntPtr manager, ushort terriType)
{
this.TerritoryType = terriType;
this.TerritoryChanged?.InvokeSafely(this, terriType);
this.TerritoryChanged?.InvokeSafely(terriType);
Log.Debug("TerritoryType changed: {0}", terriType);
return this.setupTerritoryTypeHook.Original(manager, terriType);
}
private void NetworkHandlersOnCfPop(object sender, Lumina.Excel.GeneratedSheets.ContentFinderCondition e)
private void NetworkHandlersOnCfPop(ContentFinderCondition e)
{
this.CfPop?.InvokeSafely(this, e);
this.CfPop?.InvokeSafely(e);
}
private void FrameworkOnOnUpdateEvent(IFramework framework1)
@ -149,12 +150,12 @@ internal sealed class ClientState : IDisposable, IServiceType, IClientState
if (condition == null || gameGui == null || data == null)
return;
if (condition.Any() && this.lastConditionNone == true && this.LocalPlayer != null)
if (condition.Any() && this.lastConditionNone && this.LocalPlayer != null)
{
Log.Debug("Is login");
this.lastConditionNone = false;
this.IsLoggedIn = true;
this.Login?.InvokeSafely(this, null);
this.Login?.InvokeSafely();
gameGui.ResetUiHideState();
this.lifecycle.ResetLogout();
@ -165,7 +166,7 @@ internal sealed class ClientState : IDisposable, IServiceType, IClientState
Log.Debug("Is logout");
this.lastConditionNone = true;
this.IsLoggedIn = false;
this.Logout?.InvokeSafely(this, null);
this.Logout?.InvokeSafely();
gameGui.ResetUiHideState();
this.lifecycle.SetLogout();
@ -189,3 +190,103 @@ internal sealed class ClientState : IDisposable, IServiceType, IClientState
}
}
}
/// <summary>
/// Plugin-scoped version of a GameConfig service.
/// </summary>
[PluginInterface]
[InterfaceVersion("1.0")]
[ServiceManager.ScopedService]
#pragma warning disable SA1015
[ResolveVia<IClientState>]
#pragma warning restore SA1015
internal class ClientStatePluginScoped : IDisposable, IServiceType, IClientState
{
[ServiceManager.ServiceDependency]
private readonly ClientState clientStateService = Service<ClientState>.Get();
/// <summary>
/// Initializes a new instance of the <see cref="ClientStatePluginScoped"/> class.
/// </summary>
internal ClientStatePluginScoped()
{
this.clientStateService.TerritoryChanged += this.TerritoryChangedForward;
this.clientStateService.Login += this.LoginForward;
this.clientStateService.Logout += this.LogoutForward;
this.clientStateService.EnterPvP += this.EnterPvPForward;
this.clientStateService.LeavePvP += this.ExitPvPForward;
this.clientStateService.CfPop += this.ContentFinderPopForward;
}
/// <inheritdoc/>
public event Action<ushort>? TerritoryChanged;
/// <inheritdoc/>
public event Action? Login;
/// <inheritdoc/>
public event Action? Logout;
/// <inheritdoc/>
public event Action? EnterPvP;
/// <inheritdoc/>
public event Action? LeavePvP;
/// <inheritdoc/>
public event Action<ContentFinderCondition>? CfPop;
/// <inheritdoc/>
public ClientLanguage ClientLanguage => this.clientStateService.ClientLanguage;
/// <inheritdoc/>
public ushort TerritoryType => this.clientStateService.TerritoryType;
/// <inheritdoc/>
public PlayerCharacter? LocalPlayer => this.clientStateService.LocalPlayer;
/// <inheritdoc/>
public ulong LocalContentId => this.clientStateService.LocalContentId;
/// <inheritdoc/>
public bool IsLoggedIn => this.clientStateService.IsLoggedIn;
/// <inheritdoc/>
public bool IsPvP => this.clientStateService.IsPvP;
/// <inheritdoc/>
public bool IsPvPExcludingDen => this.clientStateService.IsPvPExcludingDen;
/// <inheritdoc/>
public bool IsGPosing => this.clientStateService.IsGPosing;
/// <inheritdoc/>
public void Dispose()
{
this.clientStateService.TerritoryChanged -= this.TerritoryChangedForward;
this.clientStateService.Login -= this.LoginForward;
this.clientStateService.Logout -= this.LogoutForward;
this.clientStateService.EnterPvP -= this.EnterPvPForward;
this.clientStateService.LeavePvP -= this.ExitPvPForward;
this.clientStateService.CfPop -= this.ContentFinderPopForward;
this.TerritoryChanged = null;
this.Login = null;
this.Logout = null;
this.EnterPvP = null;
this.LeavePvP = null;
this.CfPop = null;
}
private void TerritoryChangedForward(ushort territoryId) => this.TerritoryChanged?.Invoke(territoryId);
private void LoginForward() => this.Login?.Invoke();
private void LogoutForward() => this.Logout?.Invoke();
private void EnterPvPForward() => this.EnterPvP?.Invoke();
private void ExitPvPForward() => this.LeavePvP?.Invoke();
private void ContentFinderPopForward(ContentFinderCondition cfc) => this.CfPop?.Invoke(cfc);
}

View file

@ -55,54 +55,6 @@ internal unsafe class GamepadState : IDisposable, IServiceType, IGamepadState
public Vector2 RightStick =>
new(this.rightStickX, this.rightStickY);
/// <summary>
/// Gets the state of the left analogue stick in the left direction between 0 (not tilted) and 1 (max tilt).
/// </summary>
[Obsolete("Use IGamepadState.LeftStick.X", false)]
public float LeftStickLeft => this.leftStickX < 0 ? -this.leftStickX / 100f : 0;
/// <summary>
/// Gets the state of the left analogue stick in the right direction between 0 (not tilted) and 1 (max tilt).
/// </summary>
[Obsolete("Use IGamepadState.LeftStick.X", false)]
public float LeftStickRight => this.leftStickX > 0 ? this.leftStickX / 100f : 0;
/// <summary>
/// Gets the state of the left analogue stick in the up direction between 0 (not tilted) and 1 (max tilt).
/// </summary>
[Obsolete("Use IGamepadState.LeftStick.Y", false)]
public float LeftStickUp => this.leftStickY > 0 ? this.leftStickY / 100f : 0;
/// <summary>
/// Gets the state of the left analogue stick in the down direction between 0 (not tilted) and 1 (max tilt).
/// </summary>
[Obsolete("Use IGamepadState.LeftStick.Y", false)]
public float LeftStickDown => this.leftStickY < 0 ? -this.leftStickY / 100f : 0;
/// <summary>
/// Gets the state of the right analogue stick in the left direction between 0 (not tilted) and 1 (max tilt).
/// </summary>
[Obsolete("Use IGamepadState.RightStick.X", false)]
public float RightStickLeft => this.rightStickX < 0 ? -this.rightStickX / 100f : 0;
/// <summary>
/// Gets the state of the right analogue stick in the right direction between 0 (not tilted) and 1 (max tilt).
/// </summary>
[Obsolete("Use IGamepadState.RightStick.X", false)]
public float RightStickRight => this.rightStickX > 0 ? this.rightStickX / 100f : 0;
/// <summary>
/// Gets the state of the right analogue stick in the up direction between 0 (not tilted) and 1 (max tilt).
/// </summary>
[Obsolete("Use IGamepadState.RightStick.Y", false)]
public float RightStickUp => this.rightStickY > 0 ? this.rightStickY / 100f : 0;
/// <summary>
/// Gets the state of the right analogue stick in the down direction between 0 (not tilted) and 1 (max tilt).
/// </summary>
[Obsolete("Use IGamepadState.RightStick.Y", false)]
public float RightStickDown => this.rightStickY < 0 ? -this.rightStickY / 100f : 0;
/// <summary>
/// Gets buttons pressed bitmask, set once when the button is pressed. See <see cref="GamepadButtons"/> for the mapping.
///

View file

@ -39,35 +39,35 @@ internal sealed unsafe class TargetManager : IServiceType, ITargetManager
public GameObject? Target
{
get => this.objectTable.CreateObjectReference((IntPtr)Struct->Target);
set => this.SetTarget(value);
set => Struct->Target = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
}
/// <inheritdoc/>
public GameObject? MouseOverTarget
{
get => this.objectTable.CreateObjectReference((IntPtr)Struct->MouseOverTarget);
set => this.SetMouseOverTarget(value);
set => Struct->MouseOverTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
}
/// <inheritdoc/>
public GameObject? FocusTarget
{
get => this.objectTable.CreateObjectReference((IntPtr)Struct->FocusTarget);
set => this.SetFocusTarget(value);
set => Struct->FocusTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
}
/// <inheritdoc/>
public GameObject? PreviousTarget
{
get => this.objectTable.CreateObjectReference((IntPtr)Struct->PreviousTarget);
set => this.SetPreviousTarget(value);
set => Struct->PreviousTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
}
/// <inheritdoc/>
public GameObject? SoftTarget
{
get => this.objectTable.CreateObjectReference((IntPtr)Struct->SoftTarget);
set => this.SetSoftTarget(value);
set => Struct->SoftTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
}
/// <inheritdoc/>
@ -85,104 +85,4 @@ internal sealed unsafe class TargetManager : IServiceType, ITargetManager
}
private FFXIVClientStructs.FFXIV.Client.Game.Control.TargetSystem* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Control.TargetSystem*)this.Address;
/// <summary>
/// Sets the current target.
/// </summary>
/// <param name="actor">Actor to target.</param>
[Obsolete("Use Target Property", false)]
public void SetTarget(GameObject? actor) => this.SetTarget(actor?.Address ?? IntPtr.Zero);
/// <summary>
/// Sets the mouseover target.
/// </summary>
/// <param name="actor">Actor to target.</param>
[Obsolete("Use MouseOverTarget Property", false)]
public void SetMouseOverTarget(GameObject? actor) => this.SetMouseOverTarget(actor?.Address ?? IntPtr.Zero);
/// <summary>
/// Sets the focus target.
/// </summary>
/// <param name="actor">Actor to target.</param>
[Obsolete("Use FocusTarget Property", false)]
public void SetFocusTarget(GameObject? actor) => this.SetFocusTarget(actor?.Address ?? IntPtr.Zero);
/// <summary>
/// Sets the previous target.
/// </summary>
/// <param name="actor">Actor to target.</param>
[Obsolete("Use PreviousTarget Property", false)]
public void SetPreviousTarget(GameObject? actor) => this.SetTarget(actor?.Address ?? IntPtr.Zero);
/// <summary>
/// Sets the soft target.
/// </summary>
/// <param name="actor">Actor to target.</param>
[Obsolete("Use SoftTarget Property", false)]
public void SetSoftTarget(GameObject? actor) => this.SetTarget(actor?.Address ?? IntPtr.Zero);
/// <summary>
/// Sets the current target.
/// </summary>
/// <param name="actorAddress">Actor (address) to target.</param>
[Obsolete("Use Target Property", false)]
public void SetTarget(IntPtr actorAddress) => Struct->Target = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)actorAddress;
/// <summary>
/// Sets the mouseover target.
/// </summary>
/// <param name="actorAddress">Actor (address) to target.</param>
[Obsolete("Use MouseOverTarget Property", false)]
public void SetMouseOverTarget(IntPtr actorAddress) => Struct->MouseOverTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)actorAddress;
/// <summary>
/// Sets the focus target.
/// </summary>
/// <param name="actorAddress">Actor (address) to target.</param>
[Obsolete("Use FocusTarget Property", false)]
public void SetFocusTarget(IntPtr actorAddress) => Struct->FocusTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)actorAddress;
/// <summary>
/// Sets the previous target.
/// </summary>
/// <param name="actorAddress">Actor (address) to target.</param>
[Obsolete("Use PreviousTarget Property", false)]
public void SetPreviousTarget(IntPtr actorAddress) => Struct->PreviousTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)actorAddress;
/// <summary>
/// Sets the soft target.
/// </summary>
/// <param name="actorAddress">Actor (address) to target.</param>
[Obsolete("Use SoftTarget Property", false)]
public void SetSoftTarget(IntPtr actorAddress) => Struct->SoftTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)actorAddress;
/// <summary>
/// Clears the current target.
/// </summary>
[Obsolete("Use Target Property", false)]
public void ClearTarget() => this.SetTarget(IntPtr.Zero);
/// <summary>
/// Clears the mouseover target.
/// </summary>
[Obsolete("Use MouseOverTarget Property", false)]
public void ClearMouseOverTarget() => this.SetMouseOverTarget(IntPtr.Zero);
/// <summary>
/// Clears the focus target.
/// </summary>
[Obsolete("Use FocusTarget Property", false)]
public void ClearFocusTarget() => this.SetFocusTarget(IntPtr.Zero);
/// <summary>
/// Clears the previous target.
/// </summary>
[Obsolete("Use PreviousTarget Property", false)]
public void ClearPreviousTarget() => this.SetPreviousTarget(IntPtr.Zero);
/// <summary>
/// Clears the soft target.
/// </summary>
[Obsolete("Use SoftTarget Property", false)]
public void ClearSoftTarget() => this.SetSoftTarget(IntPtr.Zero);
}

View file

@ -12,11 +12,7 @@ namespace Dalamud.Game.Config;
/// This class represents the game's configuration.
/// </summary>
[InterfaceVersion("1.0")]
[PluginInterface]
[ServiceManager.EarlyLoadedService]
#pragma warning disable SA1015
[ResolveVia<IGameConfig>]
#pragma warning restore SA1015
internal sealed class GameConfig : IServiceType, IGameConfig, IDisposable
{
private readonly GameConfigAddressResolver address = new();
@ -36,15 +32,30 @@ internal sealed class GameConfig : IServiceType, IGameConfig, IDisposable
this.address.Setup(sigScanner);
this.configChangeHook = Hook<ConfigChangeDelegate>.FromAddress(this.address.ConfigChangeAddress, this.OnConfigChanged);
this.configChangeHook?.Enable();
this.configChangeHook.Enable();
});
}
private unsafe delegate nint ConfigChangeDelegate(ConfigBase* configBase, ConfigEntry* configEntry);
/// <inheritdoc/>
public event EventHandler<ConfigChangeEvent> Changed;
public event EventHandler<ConfigChangeEvent>? Changed;
/// <summary>
/// Unused internally, used as a proxy for System.Changed via GameConfigPluginScoped
/// </summary>
public event EventHandler<ConfigChangeEvent>? SystemChanged;
/// <summary>
/// Unused internally, used as a proxy for UiConfig.Changed via GameConfigPluginScoped
/// </summary>
public event EventHandler<ConfigChangeEvent>? UiConfigChanged;
/// <summary>
/// Unused internally, used as a proxy for UiControl.Changed via GameConfigPluginScoped
/// </summary>
public event EventHandler<ConfigChangeEvent>? UiControlChanged;
/// <inheritdoc/>
public GameConfigSection System { get; private set; }
@ -192,3 +203,204 @@ internal sealed class GameConfig : IServiceType, IGameConfig, IDisposable
return returnValue;
}
}
/// <summary>
/// Plugin-scoped version of a GameConfig service.
/// </summary>
[PluginInterface]
[InterfaceVersion("1.0")]
[ServiceManager.ScopedService]
#pragma warning disable SA1015
[ResolveVia<IGameConfig>]
#pragma warning restore SA1015
internal class GameConfigPluginScoped : IDisposable, IServiceType, IGameConfig
{
[ServiceManager.ServiceDependency]
private readonly GameConfig gameConfigService = Service<GameConfig>.Get();
/// <summary>
/// Initializes a new instance of the <see cref="GameConfigPluginScoped"/> class.
/// </summary>
internal GameConfigPluginScoped()
{
this.gameConfigService.Changed += this.ConfigChangedForward;
this.gameConfigService.System.Changed += this.SystemConfigChangedForward;
this.gameConfigService.UiConfig.Changed += this.UiConfigConfigChangedForward;
this.gameConfigService.UiControl.Changed += this.UiControlConfigChangedForward;
}
/// <inheritdoc/>
public event EventHandler<ConfigChangeEvent>? Changed;
/// <inheritdoc/>
public event EventHandler<ConfigChangeEvent>? SystemChanged;
/// <inheritdoc/>
public event EventHandler<ConfigChangeEvent>? UiConfigChanged;
/// <inheritdoc/>
public event EventHandler<ConfigChangeEvent>? UiControlChanged;
/// <inheritdoc/>
public GameConfigSection System => this.gameConfigService.System;
/// <inheritdoc/>
public GameConfigSection UiConfig => this.gameConfigService.UiConfig;
/// <inheritdoc/>
public GameConfigSection UiControl => this.gameConfigService.UiControl;
/// <inheritdoc/>
public void Dispose()
{
this.gameConfigService.Changed -= this.ConfigChangedForward;
this.gameConfigService.System.Changed -= this.SystemConfigChangedForward;
this.gameConfigService.UiConfig.Changed -= this.UiConfigConfigChangedForward;
this.gameConfigService.UiControl.Changed -= this.UiControlConfigChangedForward;
this.Changed = null;
this.SystemChanged = null;
this.UiConfigChanged = null;
this.UiControlChanged = null;
}
/// <inheritdoc/>
public bool TryGet(SystemConfigOption option, out bool value)
=> this.gameConfigService.TryGet(option, out value);
/// <inheritdoc/>
public bool TryGet(SystemConfigOption option, out uint value)
=> this.gameConfigService.TryGet(option, out value);
/// <inheritdoc/>
public bool TryGet(SystemConfigOption option, out float value)
=> this.gameConfigService.TryGet(option, out value);
/// <inheritdoc/>
public bool TryGet(SystemConfigOption option, out string value)
=> this.gameConfigService.TryGet(option, out value);
/// <inheritdoc/>
public bool TryGet(SystemConfigOption option, out UIntConfigProperties? properties)
=> this.gameConfigService.TryGet(option, out properties);
/// <inheritdoc/>
public bool TryGet(SystemConfigOption option, out FloatConfigProperties? properties)
=> this.gameConfigService.TryGet(option, out properties);
/// <inheritdoc/>
public bool TryGet(SystemConfigOption option, out StringConfigProperties? properties)
=> this.gameConfigService.TryGet(option, out properties);
/// <inheritdoc/>
public bool TryGet(UiConfigOption option, out bool value)
=> this.gameConfigService.TryGet(option, out value);
/// <inheritdoc/>
public bool TryGet(UiConfigOption option, out uint value)
=> this.gameConfigService.TryGet(option, out value);
/// <inheritdoc/>
public bool TryGet(UiConfigOption option, out float value)
=> this.gameConfigService.TryGet(option, out value);
/// <inheritdoc/>
public bool TryGet(UiConfigOption option, out string value)
=> this.gameConfigService.TryGet(option, out value);
/// <inheritdoc/>
public bool TryGet(UiConfigOption option, out UIntConfigProperties? properties)
=> this.gameConfigService.TryGet(option, out properties);
/// <inheritdoc/>
public bool TryGet(UiConfigOption option, out FloatConfigProperties? properties)
=> this.gameConfigService.TryGet(option, out properties);
/// <inheritdoc/>
public bool TryGet(UiConfigOption option, out StringConfigProperties? properties)
=> this.gameConfigService.TryGet(option, out properties);
/// <inheritdoc/>
public bool TryGet(UiControlOption option, out bool value)
=> this.gameConfigService.TryGet(option, out value);
/// <inheritdoc/>
public bool TryGet(UiControlOption option, out uint value)
=> this.gameConfigService.TryGet(option, out value);
/// <inheritdoc/>
public bool TryGet(UiControlOption option, out float value)
=> this.gameConfigService.TryGet(option, out value);
/// <inheritdoc/>
public bool TryGet(UiControlOption option, out string value)
=> this.gameConfigService.TryGet(option, out value);
/// <inheritdoc/>
public bool TryGet(UiControlOption option, out UIntConfigProperties? properties)
=> this.gameConfigService.TryGet(option, out properties);
/// <inheritdoc/>
public bool TryGet(UiControlOption option, out FloatConfigProperties? properties)
=> this.gameConfigService.TryGet(option, out properties);
/// <inheritdoc/>
public bool TryGet(UiControlOption option, out StringConfigProperties? properties)
=> this.gameConfigService.TryGet(option, out properties);
/// <inheritdoc/>
public void Set(SystemConfigOption option, bool value)
=> this.gameConfigService.Set(option, value);
/// <inheritdoc/>
public void Set(SystemConfigOption option, uint value)
=> this.gameConfigService.Set(option, value);
/// <inheritdoc/>
public void Set(SystemConfigOption option, float value)
=> this.gameConfigService.Set(option, value);
/// <inheritdoc/>
public void Set(SystemConfigOption option, string value)
=> this.gameConfigService.Set(option, value);
/// <inheritdoc/>
public void Set(UiConfigOption option, bool value)
=> this.gameConfigService.Set(option, value);
/// <inheritdoc/>
public void Set(UiConfigOption option, uint value)
=> this.gameConfigService.Set(option, value);
/// <inheritdoc/>
public void Set(UiConfigOption option, float value)
=> this.gameConfigService.Set(option, value);
/// <inheritdoc/>
public void Set(UiConfigOption option, string value)
=> this.gameConfigService.Set(option, value);
/// <inheritdoc/>
public void Set(UiControlOption option, bool value)
=> this.gameConfigService.Set(option, value);
/// <inheritdoc/>
public void Set(UiControlOption option, uint value)
=> this.gameConfigService.Set(option, value);
/// <inheritdoc/>
public void Set(UiControlOption option, float value)
=> this.gameConfigService.Set(option, value);
/// <inheritdoc/>
public void Set(UiControlOption option, string value)
=> this.gameConfigService.Set(option, value);
private void ConfigChangedForward(object sender, ConfigChangeEvent data) => this.Changed?.Invoke(sender, data);
private void SystemConfigChangedForward(object sender, ConfigChangeEvent data) => this.SystemChanged?.Invoke(sender, data);
private void UiConfigConfigChangedForward(object sender, ConfigChangeEvent data) => this.UiConfigChanged?.Invoke(sender, data);
private void UiControlConfigChangedForward(object sender, ConfigChangeEvent data) => this.UiControlChanged?.Invoke(sender, data);
}

View file

@ -51,7 +51,7 @@ public class GameConfigSection
/// <summary>
/// Event which is fired when a game config option is changed within the section.
/// </summary>
public event EventHandler<ConfigChangeEvent>? Changed;
internal event EventHandler<ConfigChangeEvent>? Changed;
/// <summary>
/// Gets the number of config entries contained within the section.

View file

@ -120,7 +120,7 @@ internal unsafe class DutyState : IDisposable, IServiceType, IDutyState
return this.contentDirectorNetworkMessageHook.Original(a1, a2, a3);
}
private void TerritoryOnChangedEvent(object? sender, ushort e)
private void TerritoryOnChangedEvent(ushort territoryId)
{
if (this.IsDutyStarted)
{

View file

@ -1,34 +0,0 @@
using System.Diagnostics;
using System.Linq;
using Serilog;
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.")]
internal sealed class SwapChainSigResolver : BaseAddressResolver, ISwapChainAddressResolver
{
/// <inheritdoc/>
public IntPtr Present { get; set; }
/// <inheritdoc/>
public IntPtr ResizeBuffers { get; set; }
/// <inheritdoc/>
protected override void Setup64Bit(SigScanner sig)
{
var module = Process.GetCurrentProcess().Modules.Cast<ProcessModule>().First(m => m.ModuleName == "dxgi.dll");
Log.Debug($"Found DXGI: 0x{module.BaseAddress.ToInt64():X}");
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");
}
}

View file

@ -44,7 +44,7 @@ internal class NetworkHandlers : IDisposable, IServiceType
private NetworkHandlers(GameNetwork gameNetwork)
{
this.uploader = new UniversalisMarketBoardUploader();
this.CfPop = (_, _) => { };
this.CfPop = _ => { };
this.messages = Observable.Create<NetworkMessage>(observer =>
{
@ -75,7 +75,7 @@ internal class NetworkHandlers : IDisposable, IServiceType
/// <summary>
/// Event which gets fired when a duty is ready.
/// </summary>
public event EventHandler<ContentFinderCondition> CfPop;
public event Action<ContentFinderCondition> CfPop;
/// <summary>
/// Disposes of managed and unmanaged resources.
@ -430,7 +430,7 @@ internal class NetworkHandlers : IDisposable, IServiceType
Service<ChatGui>.GetNullable()?.Print($"Duty pop: {cfcName}");
}
this.CfPop.InvokeSafely(this, cfCondition);
this.CfPop.InvokeSafely(cfCondition);
}).ContinueWith(
task => Log.Error(task.Exception, "CfPop.Invoke failed"),
TaskContinuationOptions.OnlyOnFaulted);

View file

@ -123,16 +123,6 @@ public partial class FileDialog
return this.isOk;
}
/// <summary>
/// Gets the result of the selection.
/// </summary>
/// <returns>The result of the selection (file or folder path). If multiple entries were selected, they are separated with commas.</returns>
[Obsolete("Use GetResults() instead.", true)]
public string GetResult()
{
return string.Join(',', this.GetResults());
}
/// <summary>
/// Gets the result of the selection.
/// </summary>

View file

@ -59,9 +59,9 @@ internal class EnterTerritoryAgingStep : IAgingStep
this.subscribed = false;
}
private void ClientStateOnTerritoryChanged(object sender, ushort e)
private void ClientStateOnTerritoryChanged(ushort territoryId)
{
if (e == this.territory)
if (territoryId == this.territory)
{
this.hasPassed = true;
}

View file

@ -51,7 +51,7 @@ internal class LoginEventAgingStep : IAgingStep
}
}
private void ClientStateOnOnLogin(object sender, EventArgs e)
private void ClientStateOnOnLogin()
{
this.hasPassed = true;
}

View file

@ -51,7 +51,7 @@ internal class LogoutEventAgingStep : IAgingStep
}
}
private void ClientStateOnOnLogout(object sender, EventArgs e)
private void ClientStateOnOnLogout()
{
this.hasPassed = true;
}

View file

@ -1,10 +1,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Numerics;
using System.Threading.Tasks;
using CheapLoc;
using Dalamud.Configuration;
using Dalamud.Configuration.Internal;
@ -80,25 +78,28 @@ public class ThirdRepoSettingsEntry : SettingsEntry
var disclaimerDismissed = config.ThirdRepoSpeedbumpDismissed.Value;
ImGui.PushFont(InterfaceManager.IconFont);
ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudRed, FontAwesomeIcon.ExclamationTriangle.ToIconString());
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudOrange);
ImGuiHelpers.SafeTextWrapped(FontAwesomeIcon.ExclamationTriangle.ToIconString());
ImGui.PopFont();
ImGui.SameLine();
ImGuiHelpers.ScaledDummy(2);
ImGui.SameLine();
ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudRed, Loc.Localize("DalamudSettingCustomRepoWarningReadThis", "READ THIS FIRST!"));
ImGuiHelpers.SafeTextWrapped(Loc.Localize("DalamudSettingCustomRepoWarningReadThis", "READ THIS FIRST!"));
ImGui.SameLine();
ImGuiHelpers.ScaledDummy(2);
ImGui.SameLine();
ImGui.PushFont(InterfaceManager.IconFont);
ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudRed, FontAwesomeIcon.ExclamationTriangle.ToIconString());
ImGuiHelpers.SafeTextWrapped(FontAwesomeIcon.ExclamationTriangle.ToIconString());
ImGui.PopFont();
ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudRed, Loc.Localize("DalamudSettingCustomRepoWarning", "We cannot take any responsibility for custom plugins and repositories."));
ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudRed, Loc.Localize("DalamudSettingCustomRepoWarning5", "If someone told you to copy/paste something here, it's very possible that you are being scammed or taken advantage of."));
ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudRed, Loc.Localize("DalamudSettingCustomRepoWarning2", "Plugins have full control over your PC, like any other program, and may cause harm or crashes."));
ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudRed, Loc.Localize("DalamudSettingCustomRepoWarning4", "They can delete your character, steal your FC or Discord account, and burn down your house."));
ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudRed, Loc.Localize("DalamudSettingCustomRepoWarning3", "Please make absolutely sure that you only install plugins from developers you trust."));
ImGuiHelpers.SafeTextWrapped(Loc.Localize("DalamudSettingCustomRepoWarning", "We cannot take any responsibility for custom plugins and repositories."));
ImGuiHelpers.SafeTextWrapped(Loc.Localize("DalamudSettingCustomRepoWarning5", "If someone told you to copy/paste something here, it's very possible that you are being scammed or taken advantage of."));
ImGuiHelpers.SafeTextWrapped(Loc.Localize("DalamudSettingCustomRepoWarning2", "Plugins have full control over your PC, like any other program, and may cause harm or crashes."));
ImGuiHelpers.SafeTextWrapped(Loc.Localize("DalamudSettingCustomRepoWarning4", "They can delete your character, steal your FC or Discord account, and burn down your house."));
ImGuiHelpers.SafeTextWrapped(Loc.Localize("DalamudSettingCustomRepoWarning3", "Please make absolutely sure that you only install plugins from developers you trust."));
ImGui.PopStyleColor();
if (!disclaimerDismissed)
{
const int speedbumpTime = 15;

View file

@ -94,14 +94,6 @@ public class WindowSystem
/// </summary>
public void RemoveAllWindows() => this.windows.Clear();
/// <summary>
/// Get a window by name.
/// </summary>
/// <param name="windowName">The name of the <see cref="Window"/>.</param>
/// <returns>The <see cref="Window"/> object with matching name or null.</returns>
[Obsolete("WindowSystem does not own your window - you should store a reference to it and use that instead.")]
public Window? GetWindow(string windowName) => this.windows.FirstOrDefault(w => w.WindowName == windowName);
/// <summary>
/// Draw all registered windows using ImGui.
/// </summary>

View file

@ -1,6 +1,5 @@
using System;
using System.Reflection;
using Dalamud.Plugin.Services;
using Serilog;
using Serilog.Events;
@ -9,6 +8,11 @@ namespace Dalamud.Logging;
/// <summary>
/// Class offering various static methods to allow for logging in plugins.
/// </summary>
/// <remarks>
/// PluginLog has been obsoleted and replaced by the <see cref="IPluginLog"/> service. Developers are encouraged to
/// move over as soon as reasonably possible for performance reasons.
/// </remarks>
[Obsolete("Static PluginLog will be removed in API 10. Developers should use IPluginLog.")]
public static class PluginLog
{
#region "Log" prefixed Serilog style methods

View file

@ -1,6 +1,4 @@
using System;
using Dalamud.IoC;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Internal.Types;
using Dalamud.Plugin.Services;
@ -90,6 +88,14 @@ public class ScopedPluginLogService : IServiceType, IPluginLog, IDisposable
/// <inheritdoc />
public void Information(Exception? exception, string messageTemplate, params object[] values) =>
this.Write(LogEventLevel.Information, exception, messageTemplate, values);
/// <inheritdoc/>
public void Info(string messageTemplate, params object[] values) =>
this.Information(messageTemplate, values);
/// <inheritdoc/>
public void Info(Exception? exception, string messageTemplate, params object[] values) =>
this.Information(exception, messageTemplate, values);
/// <inheritdoc />
public void Debug(string messageTemplate, params object[] values) =>

View file

@ -12,17 +12,17 @@ public interface IClientState
/// <summary>
/// Event that gets fired when the current Territory changes.
/// </summary>
public event EventHandler<ushort> TerritoryChanged;
public event Action<ushort> TerritoryChanged;
/// <summary>
/// Event that fires when a character is logging in, and the local character object is available.
/// </summary>
public event EventHandler Login;
public event Action Login;
/// <summary>
/// Event that fires when a character is logging out.
/// </summary>
public event EventHandler Logout;
public event Action Logout;
/// <summary>
/// Event that fires when a character is entering PvP.
@ -37,7 +37,7 @@ public interface IClientState
/// <summary>
/// Event that gets fired when a duty is ready.
/// </summary>
public event EventHandler<Lumina.Excel.GeneratedSheets.ContentFinderCondition> CfPop;
public event Action<Lumina.Excel.GeneratedSheets.ContentFinderCondition> CfPop;
/// <summary>
/// Gets the language of the client.

View file

@ -12,10 +12,25 @@ namespace Dalamud.Plugin.Services;
public interface IGameConfig
{
/// <summary>
/// Event which is fired when a game config option is changed.
/// Event which is fired when any game config option is changed.
/// </summary>
public event EventHandler<ConfigChangeEvent> Changed;
/// <summary>
/// Event which is fired when a system config option is changed.
/// </summary>
public event EventHandler<ConfigChangeEvent> SystemChanged;
/// <summary>
/// Event which is fired when a UiConfig option is changed.
/// </summary>
public event EventHandler<ConfigChangeEvent> UiConfigChanged;
/// <summary>
/// Event which is fired when a UiControl config option is changed.
/// </summary>
public event EventHandler<ConfigChangeEvent> UiControlChanged;
/// <summary>
/// Gets the collection of config options that persist between characters.
/// </summary>

View file

@ -76,6 +76,12 @@ public interface IPluginLog
/// <inheritdoc cref="Information(string,object[])"/>
/// <param name="exception">An (optional) exception that should be recorded alongside this event.</param>
void Information(Exception? exception, string messageTemplate, params object[] values);
/// <inheritdoc cref="Information(string,object[])"/>
void Info(string messageTemplate, params object[] values);
/// <inheritdoc cref="Information(Exception?,string,object[])"/>
void Info(Exception? exception, string messageTemplate, params object[] values);
/// <summary>
/// Log a <see cref="LogEventLevel.Debug" /> message to the Dalamud log for this plugin. This log level should be

View file

@ -1,12 +1,9 @@
using System;
using System.Linq;
using Dalamud.Game;
using Dalamud.Plugin.Services;
using Serilog;
using static Dalamud.Game.Framework;
namespace Dalamud.Utility;
/// <summary>
@ -21,7 +18,7 @@ internal static class EventHandlerExtensions
/// <param name="eh">The EventHandler in question.</param>
/// <param name="sender">Default sender for Invoke equivalent.</param>
/// <param name="e">Default EventArgs for Invoke equivalent.</param>
public static void InvokeSafely(this EventHandler eh, object sender, EventArgs e)
public static void InvokeSafely(this EventHandler? eh, object sender, EventArgs e)
{
if (eh == null)
return;
@ -40,7 +37,7 @@ internal static class EventHandlerExtensions
/// <param name="sender">Default sender for Invoke equivalent.</param>
/// <param name="e">Default EventArgs for Invoke equivalent.</param>
/// <typeparam name="T">Type of EventArgs.</typeparam>
public static void InvokeSafely<T>(this EventHandler<T> eh, object sender, T e)
public static void InvokeSafely<T>(this EventHandler<T>? eh, object sender, T e)
{
if (eh == null)
return;
@ -56,7 +53,7 @@ internal static class EventHandlerExtensions
/// of a thrown Exception inside of an invocation.
/// </summary>
/// <param name="act">The Action in question.</param>
public static void InvokeSafely(this Action act)
public static void InvokeSafely(this Action? act)
{
if (act == null)
return;
@ -67,13 +64,31 @@ internal static class EventHandlerExtensions
}
}
/// <summary>
/// Replacement for Invoke() on event Actions to catch exceptions that stop event propagation in case
/// of a thrown Exception inside of an invocation.
/// </summary>
/// <param name="act">The Action in question.</param>
/// <param name="argument">Templated argument for Action.</param>
/// <typeparam name="T">Type of Action args.</typeparam>
public static void InvokeSafely<T>(this Action<T>? act, T argument)
{
if (act == null)
return;
foreach (var action in act.GetInvocationList().Cast<Action<T>>())
{
HandleInvoke(action, argument);
}
}
/// <summary>
/// Replacement for Invoke() on OnUpdateDelegate to catch exceptions that stop event propagation in case
/// of a thrown Exception inside of an invocation.
/// </summary>
/// <param name="updateDelegate">The OnUpdateDelegate in question.</param>
/// <param name="framework">Framework to be passed on to OnUpdateDelegate.</param>
public static void InvokeSafely(this IFramework.OnUpdateDelegate updateDelegate, Framework framework)
public static void InvokeSafely(this IFramework.OnUpdateDelegate? updateDelegate, Framework framework)
{
if (updateDelegate == null)
return;
@ -95,4 +110,16 @@ internal static class EventHandlerExtensions
Log.Error(ex, "Exception during raise of {handler}", act.Method);
}
}
private static void HandleInvoke<T>(Action<T> act, T argument)
{
try
{
act(argument);
}
catch (Exception ex)
{
Log.Error(ex, "Exception during raise of {handler}", act.Method);
}
}
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@ -66,7 +66,7 @@ internal static class SignatureHelper
: message;
if (fallible)
{
PluginLog.Warning(errorMsg);
Log.Warning(errorMsg);
}
else
{

@ -1 +1 @@
Subproject commit fd5ba8a27ec911a69eeb93ceb0202091279dfceb
Subproject commit a1ddff0974729a2e984d8cc1dc007eff19bd74ab