mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +01:00
Merge branch 'net5'
This commit is contained in:
commit
d29400437e
52 changed files with 274 additions and 273 deletions
|
|
@ -84,6 +84,7 @@
|
|||
<!-- This prevents us from having to include Dalamud itself as a dependency -->
|
||||
<!-- If the files move just update the paths here -->
|
||||
<Compile Include="..\Dalamud\ClientLanguage.cs" Link="Included\%(Filename)%(Extension)" />
|
||||
<Compile Include="..\Dalamud\IServiceType.cs" Link="Included\%(Filename)%(Extension)" />
|
||||
<Compile Include="..\Dalamud\DalamudStartInfo.cs" Link="Included\%(Filename)%(Extension)" />
|
||||
<Compile Include="..\Dalamud\Game\GameVersion.cs" Link="Included\Game\%(Filename)%(Extension)" />
|
||||
<Compile Include="..\Dalamud\Game\GameVersionConverter.cs" Link="Included\Game\%(Filename)%(Extension)" />
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace Dalamud.Configuration.Internal
|
|||
/// Class containing Dalamud settings.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
internal sealed class DalamudConfiguration
|
||||
internal sealed class DalamudConfiguration : IServiceType
|
||||
{
|
||||
/// <summary>
|
||||
/// Currently used beta key for Dalamud staging builds.
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace Dalamud
|
|||
/// <summary>
|
||||
/// The main Dalamud class containing all subsystems.
|
||||
/// </summary>
|
||||
internal sealed class Dalamud : IDisposable
|
||||
internal sealed class Dalamud : IDisposable, IServiceType
|
||||
{
|
||||
#region Internals
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Dalamud
|
|||
/// Struct containing information needed to initialize Dalamud.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public record DalamudStartInfo
|
||||
public record DalamudStartInfo : IServiceType
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DalamudStartInfo"/> class.
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace Dalamud.Data
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed class DataManager : IDisposable
|
||||
public sealed class DataManager : IDisposable, IServiceType
|
||||
{
|
||||
private const string IconFileFormat = "ui/icon/{0:D3}000/{1}{2:D6}.tex";
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ namespace Dalamud.Game
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public class ChatHandlers
|
||||
public class ChatHandlers : IServiceType
|
||||
{
|
||||
// private static readonly Dictionary<string, string> UnicodeToDiscordEmojiDict = new()
|
||||
// {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace Dalamud.Game.ClientState.Aetherytes
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed partial class AetheryteList
|
||||
public sealed partial class AetheryteList : IServiceType
|
||||
{
|
||||
[ServiceManager.ServiceDependency]
|
||||
private readonly ClientState clientState = Service<ClientState>.Get();
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace Dalamud.Game.ClientState.Buddy
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed partial class BuddyList
|
||||
public sealed partial class BuddyList : IServiceType
|
||||
{
|
||||
private const uint InvalidObjectID = 0xE0000000;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ namespace Dalamud.Game.ClientState
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed class ClientState : IDisposable
|
||||
public sealed class ClientState : IDisposable, IServiceType
|
||||
{
|
||||
private readonly ClientStateAddressResolver address;
|
||||
private readonly Hook<SetupTerritoryTypeDelegate> setupTerritoryTypeHook;
|
||||
|
|
@ -128,16 +128,6 @@ namespace Dalamud.Game.ClientState
|
|||
/// </summary>
|
||||
public bool IsPvPExcludingDen { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enable this module.
|
||||
/// </summary>
|
||||
public void Enable()
|
||||
{
|
||||
Service<Conditions.Condition>.Get().Enable();
|
||||
Service<GamepadState>.Get().Enable();
|
||||
this.setupTerritoryTypeHook.Enable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of managed and unmanaged resources.
|
||||
/// </summary>
|
||||
|
|
@ -150,6 +140,12 @@ namespace Dalamud.Game.ClientState
|
|||
Service<NetworkHandlers>.Get().CfPop -= this.NetworkHandlersOnCfPop;
|
||||
}
|
||||
|
||||
[ServiceManager.CallWhenServicesReady]
|
||||
private void ContinueConstruction()
|
||||
{
|
||||
this.setupTerritoryTypeHook.Enable();
|
||||
}
|
||||
|
||||
private IntPtr SetupTerritoryTypeDetour(IntPtr manager, ushort terriType)
|
||||
{
|
||||
this.TerritoryType = terriType;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace Dalamud.Game.ClientState.Conditions
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed partial class Condition
|
||||
public sealed partial class Condition : IServiceType
|
||||
{
|
||||
/// <summary>
|
||||
/// The current max number of conditions. You can get this just by looking at the condition sheet and how many rows it has.
|
||||
|
|
@ -82,16 +82,14 @@ namespace Dalamud.Game.ClientState.Conditions
|
|||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables the hooks of the Condition class function.
|
||||
/// </summary>
|
||||
public void Enable()
|
||||
[ServiceManager.CallWhenServicesReady]
|
||||
private void ContinueConstruction(Framework framework)
|
||||
{
|
||||
// Initialization
|
||||
for (var i = 0; i < MaxConditionEntries; i++)
|
||||
this.cache[i] = this[i];
|
||||
|
||||
Service<Framework>.Get().Update += this.FrameworkUpdate;
|
||||
framework.Update += this.FrameworkUpdate;
|
||||
}
|
||||
|
||||
private void FrameworkUpdate(Framework framework)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ namespace Dalamud.Game.ClientState.Fates
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed partial class FateTable
|
||||
public sealed partial class FateTable : IServiceType
|
||||
{
|
||||
private readonly ClientStateAddressResolver address;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace Dalamud.Game.ClientState.GamePad
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public unsafe class GamepadState : IDisposable
|
||||
public unsafe class GamepadState : IDisposable, IServiceType
|
||||
{
|
||||
private readonly Hook<ControllerPoll> gamepadPoll;
|
||||
|
||||
|
|
@ -168,10 +168,8 @@ namespace Dalamud.Game.ClientState.GamePad
|
|||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables the hook of the GamepadPoll function.
|
||||
/// </summary>
|
||||
internal void Enable()
|
||||
[ServiceManager.CallWhenServicesReady]
|
||||
private void ContinueConstruction()
|
||||
{
|
||||
this.gamepadPoll.Enable();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace Dalamud.Game.ClientState.JobGauge
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public class JobGauges
|
||||
public class JobGauges : IServiceType
|
||||
{
|
||||
private Dictionary<Type, JobGaugeBase> cache = new();
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace Dalamud.Game.ClientState.Keys
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public class KeyState
|
||||
public class KeyState : IServiceType
|
||||
{
|
||||
// The array is accessed in a way that this limit doesn't appear to exist
|
||||
// but there is other state data past this point, and keys beyond here aren't
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace Dalamud.Game.ClientState.Objects
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed partial class ObjectTable
|
||||
public sealed partial class ObjectTable : IServiceType
|
||||
{
|
||||
private const int ObjectTableLength = 424;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace Dalamud.Game.ClientState.Objects
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed unsafe class TargetManager
|
||||
public sealed unsafe class TargetManager : IServiceType
|
||||
{
|
||||
private readonly ClientStateAddressResolver address;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace Dalamud.Game.ClientState.Party
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed unsafe partial class PartyList
|
||||
public sealed unsafe partial class PartyList : IServiceType
|
||||
{
|
||||
private const int GroupLength = 8;
|
||||
private const int AllianceLength = 20;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ namespace Dalamud.Game.Command
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed class CommandManager
|
||||
public sealed class CommandManager : IServiceType
|
||||
{
|
||||
private readonly Dictionary<string, CommandInfo> commandMap = new();
|
||||
private readonly Regex commandRegexEn = new(@"^The command (?<command>.+) does not exist\.$", RegexOptions.Compiled);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ namespace Dalamud.Game
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed class Framework : IDisposable
|
||||
public sealed class Framework : IDisposable, IServiceType
|
||||
{
|
||||
private static Stopwatch statsStopwatch = new();
|
||||
|
||||
|
|
@ -47,13 +47,6 @@ namespace Dalamud.Game
|
|||
this.updateHook = new Hook<OnUpdateDetour>(this.Address.TickAddress, this.HandleFrameworkUpdate);
|
||||
this.freeHook = new Hook<OnDestroyDetour>(this.Address.FreeAddress, this.HandleFrameworkFree);
|
||||
this.destroyHook = new Hook<OnRealDestroyDelegate>(this.Address.DestroyAddress, this.HandleFrameworkDestroy);
|
||||
|
||||
gameGui.Enable();
|
||||
gameNetwork.Enable();
|
||||
|
||||
this.updateHook.Enable();
|
||||
this.freeHook.Enable();
|
||||
this.destroyHook.Enable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -224,6 +217,14 @@ namespace Dalamud.Game
|
|||
statsStopwatch.Reset();
|
||||
}
|
||||
|
||||
[ServiceManager.CallWhenServicesReady]
|
||||
private void ContinueConstruction()
|
||||
{
|
||||
this.updateHook.Enable();
|
||||
this.freeHook.Enable();
|
||||
this.destroyHook.Enable();
|
||||
}
|
||||
|
||||
private bool HandleFrameworkUpdate(IntPtr framework)
|
||||
{
|
||||
this.frameworkUpdateThread ??= Thread.CurrentThread;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace Dalamud.Game.Gui
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed class ChatGui : IDisposable
|
||||
public sealed class ChatGui : IDisposable, IServiceType
|
||||
{
|
||||
private readonly ChatGuiAddressResolver address;
|
||||
|
||||
|
|
@ -123,16 +123,6 @@ namespace Dalamud.Game.Gui
|
|||
/// </summary>
|
||||
public byte LastLinkedItemFlags { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enables this module.
|
||||
/// </summary>
|
||||
public void Enable()
|
||||
{
|
||||
this.printMessageHook.Enable();
|
||||
this.populateItemLinkHook.Enable();
|
||||
this.interactableLinkClickedHook.Enable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of managed and unmanaged resources.
|
||||
/// </summary>
|
||||
|
|
@ -280,6 +270,14 @@ namespace Dalamud.Game.Gui
|
|||
}
|
||||
}
|
||||
|
||||
[ServiceManager.CallWhenServicesReady]
|
||||
private void ContinueConstruction(GameGui gameGui, LibcFunction libcFunction)
|
||||
{
|
||||
this.printMessageHook.Enable();
|
||||
this.populateItemLinkHook.Enable();
|
||||
this.interactableLinkClickedHook.Enable();
|
||||
}
|
||||
|
||||
private void HandlePopulateItemLinkDetour(IntPtr linkObjectPtr, IntPtr itemInfoPtr)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Game.Gui.ContextMenus.OldStructs;
|
||||
using Dalamud.Hooking;
|
||||
using Dalamud.IoC;
|
||||
|
|
@ -25,7 +25,7 @@ namespace Dalamud.Game.Gui.ContextMenus
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed class ContextMenu : IDisposable
|
||||
public sealed class ContextMenu : IDisposable, IServiceType
|
||||
{
|
||||
private const int MaxContextMenuItemsPerContextMenu = 32;
|
||||
|
||||
|
|
@ -97,18 +97,6 @@ namespace Dalamud.Game.Gui.ContextMenus
|
|||
this.contextMenuOpeningHook.Disable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable this subsystem.
|
||||
/// </summary>
|
||||
internal void Enable()
|
||||
{
|
||||
this.contextMenuOpeningHook.Enable();
|
||||
this.contextMenuOpenedHook.Enable();
|
||||
this.contextMenuItemSelectedHook.Enable();
|
||||
this.subContextMenuOpeningHook.Enable();
|
||||
this.subContextMenuOpenedHook.Enable();
|
||||
}
|
||||
|
||||
private static unsafe bool IsInventoryContext(OldAgentContextInterface* agentContextInterface)
|
||||
{
|
||||
return agentContextInterface == AgentInventoryContext.Instance();
|
||||
|
|
@ -122,6 +110,19 @@ namespace Dalamud.Game.Gui.ContextMenus
|
|||
}
|
||||
}
|
||||
|
||||
[ServiceManager.CallWhenServicesReady]
|
||||
private void ContinueConstruction(GameGui gameGui)
|
||||
{
|
||||
if (!EnvironmentConfiguration.DalamudDoContextMenu)
|
||||
return;
|
||||
|
||||
this.contextMenuOpeningHook.Enable();
|
||||
this.contextMenuOpenedHook.Enable();
|
||||
this.contextMenuItemSelectedHook.Enable();
|
||||
this.subContextMenuOpeningHook.Enable();
|
||||
this.subContextMenuOpenedHook.Enable();
|
||||
}
|
||||
|
||||
private unsafe IntPtr ContextMenuOpeningDetour(IntPtr a1, IntPtr a2, IntPtr a3, uint a4, IntPtr a5, OldAgentContextInterface* agentContextInterface, IntPtr a7, ushort a8)
|
||||
{
|
||||
this.currentAgentContextInterface = agentContextInterface;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ namespace Dalamud.Game.Gui.Dtr
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed unsafe class DtrBar : IDisposable
|
||||
public sealed unsafe class DtrBar : IDisposable, IServiceType
|
||||
{
|
||||
private const uint BaseNodeId = 1000;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed class FlyTextGui : IDisposable
|
||||
public sealed class FlyTextGui : IDisposable, IServiceType
|
||||
{
|
||||
/// <summary>
|
||||
/// The native function responsible for adding fly text to the UI. See <see cref="FlyTextGuiAddressResolver.AddFlyText"/>.
|
||||
|
|
@ -129,7 +129,10 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
var strOffset = 28u;
|
||||
|
||||
// Get the UI module and flytext addon pointers
|
||||
var gameGui = Service<GameGui>.Get();
|
||||
var gameGui = Service<GameGui>.GetNullable();
|
||||
if (gameGui == null)
|
||||
return;
|
||||
|
||||
var ui = (FFXIVClientStructs.FFXIV.Client.UI.UIModule*)gameGui.GetUIModule();
|
||||
var flytext = gameGui.GetAddonByName("_FlyText", 1);
|
||||
|
||||
|
|
@ -174,10 +177,8 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables this module.
|
||||
/// </summary>
|
||||
internal void Enable()
|
||||
[ServiceManager.CallWhenServicesReady]
|
||||
private void ContinueConstruction(GameGui gameGui)
|
||||
{
|
||||
this.createFlyTextHook.Enable();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ namespace Dalamud.Game.Gui
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed unsafe class GameGui : IDisposable
|
||||
public sealed unsafe class GameGui : IDisposable, IServiceType
|
||||
{
|
||||
private readonly GameGuiAddressResolver address;
|
||||
|
||||
|
|
@ -418,19 +418,9 @@ namespace Dalamud.Game.Gui
|
|||
/// <param name="bgmKey">The background music key.</param>
|
||||
public void SetBgm(ushort bgmKey) => this.setGlobalBgmHook.Original(bgmKey, 0, 0, 0, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Enables the hooks and submodules of this module.
|
||||
/// </summary>
|
||||
public void Enable()
|
||||
[ServiceManager.CallWhenServicesReady]
|
||||
private void ContinueConstruction()
|
||||
{
|
||||
Service<ChatGui>.GetAsync().ContinueWith(x => x.Result.Enable());
|
||||
Service<ToastGui>.GetAsync().ContinueWith(x => x.Result.Enable());
|
||||
Service<FlyTextGui>.GetAsync().ContinueWith(x => x.Result.Enable());
|
||||
Service<PartyFinderGui>.GetAsync().ContinueWith(x => x.Result.Enable());
|
||||
|
||||
if (EnvironmentConfiguration.DalamudDoContextMenu)
|
||||
Service<ContextMenu>.GetAsync().ContinueWith(x => x.Result.Enable());
|
||||
|
||||
this.setGlobalBgmHook.Enable();
|
||||
this.handleItemHoverHook.Enable();
|
||||
this.handleItemOutHook.Enable();
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Dalamud.Game.Gui.Internal
|
|||
/// This class handles IME for non-English users.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal unsafe class DalamudIME : IDisposable
|
||||
internal unsafe class DalamudIME : IDisposable, IServiceType
|
||||
{
|
||||
private static readonly ModuleLog Log = new("IME");
|
||||
|
||||
|
|
@ -83,15 +83,13 @@ namespace Dalamud.Game.Gui.Internal
|
|||
return new Vector2(this.cursorPos->X, this.cursorPos->Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables the IME module.
|
||||
/// </summary>
|
||||
internal void Enable()
|
||||
[ServiceManager.CallWhenServicesReady]
|
||||
private void ContinueConstruction(InterfaceManager.InterfaceManagerWithScene interfaceManagerWithScene)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.wndProcDelegate = this.WndProcDetour;
|
||||
this.interfaceHandle = Service<InterfaceManager>.Get().WindowHandlePtr;
|
||||
this.interfaceHandle = interfaceManagerWithScene.Manager.WindowHandlePtr;
|
||||
this.wndProcPtr = Marshal.GetFunctionPointerForDelegate(this.wndProcDelegate);
|
||||
this.oldWndProcPtr = SetWindowLongPtrW(this.interfaceHandle, WindowLongType.WndProc, this.wndProcPtr);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace Dalamud.Game.Gui.PartyFinder
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed class PartyFinderGui : IDisposable
|
||||
public sealed class PartyFinderGui : IDisposable, IServiceType
|
||||
{
|
||||
private readonly PartyFinderAddressResolver address;
|
||||
private readonly IntPtr memory;
|
||||
|
|
@ -55,14 +55,6 @@ namespace Dalamud.Game.Gui.PartyFinder
|
|||
/// </summary>
|
||||
public event PartyFinderListingEventDelegate ReceiveListing;
|
||||
|
||||
/// <summary>
|
||||
/// Enables this module.
|
||||
/// </summary>
|
||||
public void Enable()
|
||||
{
|
||||
this.receiveListingHook.Enable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of managed and unmanaged resources.
|
||||
/// </summary>
|
||||
|
|
@ -80,6 +72,12 @@ namespace Dalamud.Game.Gui.PartyFinder
|
|||
}
|
||||
}
|
||||
|
||||
[ServiceManager.CallWhenServicesReady]
|
||||
private void ContinueConstruction(GameGui gameGui)
|
||||
{
|
||||
this.receiveListingHook.Enable();
|
||||
}
|
||||
|
||||
private void HandleReceiveListingDetour(IntPtr managerPtr, IntPtr data)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace Dalamud.Game.Gui.Toast
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed partial class ToastGui : IDisposable
|
||||
public sealed partial class ToastGui : IDisposable, IServiceType
|
||||
{
|
||||
private const uint QuestToastCheckmarkMagic = 60081;
|
||||
|
||||
|
|
@ -100,16 +100,6 @@ namespace Dalamud.Game.Gui.Toast
|
|||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Enables this module.
|
||||
/// </summary>
|
||||
public void Enable()
|
||||
{
|
||||
this.showNormalToastHook.Enable();
|
||||
this.showQuestToastHook.Enable();
|
||||
this.showErrorToastHook.Enable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes of managed and unmanaged resources.
|
||||
/// </summary>
|
||||
|
|
@ -153,6 +143,14 @@ namespace Dalamud.Game.Gui.Toast
|
|||
return terminated;
|
||||
}
|
||||
|
||||
[ServiceManager.CallWhenServicesReady]
|
||||
private void ContinueConstruction(GameGui gameGui)
|
||||
{
|
||||
this.showNormalToastHook.Enable();
|
||||
this.showQuestToastHook.Enable();
|
||||
this.showErrorToastHook.Enable();
|
||||
}
|
||||
|
||||
private SeString ParseString(IntPtr text)
|
||||
{
|
||||
var bytes = new List<byte>();
|
||||
|
|
@ -202,7 +200,9 @@ namespace Dalamud.Game.Gui.Toast
|
|||
{
|
||||
options ??= new ToastOptions();
|
||||
|
||||
var manager = Service<GameGui>.Get().GetUIModule();
|
||||
var manager = Service<GameGui>.GetNullable()?.GetUIModule();
|
||||
if (manager == null)
|
||||
return;
|
||||
|
||||
// terminate the string
|
||||
var terminated = Terminate(bytes);
|
||||
|
|
@ -211,7 +211,7 @@ namespace Dalamud.Game.Gui.Toast
|
|||
{
|
||||
fixed (byte* ptr = terminated)
|
||||
{
|
||||
this.HandleNormalToastDetour(manager, (IntPtr)ptr, 5, (byte)options.Position, (byte)options.Speed, 0);
|
||||
this.HandleNormalToastDetour(manager!.Value, (IntPtr)ptr, 5, (byte)options.Position, (byte)options.Speed, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -283,7 +283,9 @@ namespace Dalamud.Game.Gui.Toast
|
|||
{
|
||||
options ??= new QuestToastOptions();
|
||||
|
||||
var manager = Service<GameGui>.Get().GetUIModule();
|
||||
var manager = Service<GameGui>.GetNullable()?.GetUIModule();
|
||||
if (manager == null)
|
||||
return;
|
||||
|
||||
// terminate the string
|
||||
var terminated = Terminate(bytes);
|
||||
|
|
@ -295,7 +297,7 @@ namespace Dalamud.Game.Gui.Toast
|
|||
fixed (byte* ptr = terminated)
|
||||
{
|
||||
this.HandleQuestToastDetour(
|
||||
manager,
|
||||
manager!.Value,
|
||||
(int)options.Position,
|
||||
(IntPtr)ptr,
|
||||
ioc1,
|
||||
|
|
@ -385,7 +387,9 @@ namespace Dalamud.Game.Gui.Toast
|
|||
|
||||
private void ShowError(byte[] bytes)
|
||||
{
|
||||
var manager = Service<GameGui>.Get().GetUIModule();
|
||||
var manager = Service<GameGui>.GetNullable()?.GetUIModule();
|
||||
if (manager == null)
|
||||
return;
|
||||
|
||||
// terminate the string
|
||||
var terminated = Terminate(bytes);
|
||||
|
|
@ -394,7 +398,7 @@ namespace Dalamud.Game.Gui.Toast
|
|||
{
|
||||
fixed (byte* ptr = terminated)
|
||||
{
|
||||
this.HandleErrorToastDetour(manager, (IntPtr)ptr, 0);
|
||||
this.HandleErrorToastDetour(manager!.Value, (IntPtr)ptr, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace Dalamud.Game.Internal
|
|||
/// This class disables anti-debug functionality in the game client.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal sealed partial class AntiDebug
|
||||
internal sealed partial class AntiDebug : IServiceType
|
||||
{
|
||||
private readonly byte[] nop = new byte[] { 0x31, 0xC0, 0x90, 0x90, 0x90, 0x90 };
|
||||
private byte[] original;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,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
|
||||
internal sealed unsafe partial class DalamudAtkTweaks : IServiceType
|
||||
{
|
||||
private readonly AtkValueChangeType atkValueChangeType;
|
||||
private readonly AtkValueSetString atkValueSetString;
|
||||
|
|
@ -39,7 +39,7 @@ namespace Dalamud.Game.Internal
|
|||
private readonly string locDalamudSettings;
|
||||
|
||||
[ServiceManager.ServiceConstructor]
|
||||
private DalamudAtkTweaks(SigScanner sigScanner)
|
||||
private DalamudAtkTweaks(SigScanner sigScanner, ContextMenu contextMenu)
|
||||
{
|
||||
var openSystemMenuAddress = sigScanner.ScanText("E8 ?? ?? ?? ?? 32 C0 4C 8B AC 24 ?? ?? ?? ?? 48 8B 8D ?? ?? ?? ??");
|
||||
|
||||
|
|
@ -60,10 +60,7 @@ namespace Dalamud.Game.Internal
|
|||
this.locDalamudPlugins = Loc.Localize("SystemMenuPlugins", "Dalamud Plugins");
|
||||
this.locDalamudSettings = Loc.Localize("SystemMenuSettings", "Dalamud Settings");
|
||||
|
||||
var contextMenu = Service<ContextMenu>.Get();
|
||||
contextMenu.ContextMenuOpened += this.ContextMenuOnContextMenuOpened;
|
||||
|
||||
this.Enable();
|
||||
}
|
||||
|
||||
private delegate void AgentHudOpenSystemMenuPrototype(void* thisPtr, AtkValue* atkValueArgs, uint menuSize);
|
||||
|
|
@ -76,10 +73,8 @@ namespace Dalamud.Game.Internal
|
|||
|
||||
private delegate IntPtr AtkUnitBaseReceiveGlobalEvent(AtkUnitBase* thisPtr, ushort cmd, uint a3, IntPtr a4, uint* a5);
|
||||
|
||||
/// <summary>
|
||||
/// Enables the <see cref="DalamudAtkTweaks"/>.
|
||||
/// </summary>
|
||||
public void Enable()
|
||||
[ServiceManager.CallWhenServicesReady]
|
||||
private void ContinueConstruction(DalamudInterface dalamudInterface)
|
||||
{
|
||||
this.hookAgentHudOpenSystemMenu.Enable();
|
||||
this.hookUiModuleRequestMainCommand.Enable();
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace Dalamud.Game.Libc
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed class LibcFunction
|
||||
public sealed class LibcFunction : IServiceType
|
||||
{
|
||||
private readonly LibcFunctionAddressResolver address;
|
||||
private readonly StdStringFromCStringDelegate stdStringCtorCString;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace Dalamud.Game.Network
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed class GameNetwork : IDisposable
|
||||
public sealed class GameNetwork : IDisposable, IServiceType
|
||||
{
|
||||
private readonly GameNetworkAddressResolver address;
|
||||
private readonly Hook<ProcessZonePacketDownDelegate> processZonePacketDownHook;
|
||||
|
|
@ -59,15 +59,6 @@ namespace Dalamud.Game.Network
|
|||
/// </summary>
|
||||
public event OnNetworkMessageDelegate NetworkMessage;
|
||||
|
||||
/// <summary>
|
||||
/// Enable this module.
|
||||
/// </summary>
|
||||
public void Enable()
|
||||
{
|
||||
this.processZonePacketDownHook.Enable();
|
||||
this.processZonePacketUpHook.Enable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of managed and unmanaged resources.
|
||||
/// </summary>
|
||||
|
|
@ -98,6 +89,13 @@ namespace Dalamud.Game.Network
|
|||
}
|
||||
}
|
||||
|
||||
[ServiceManager.CallWhenServicesReady]
|
||||
private void ContinueConstruction()
|
||||
{
|
||||
this.processZonePacketDownHook.Enable();
|
||||
this.processZonePacketUpHook.Enable();
|
||||
}
|
||||
|
||||
private void ProcessZonePacketDownDetour(IntPtr a, uint targetId, IntPtr dataPtr)
|
||||
{
|
||||
this.baseAddress = a;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace Dalamud.Game.Network.Internal
|
|||
/// This class handles network notifications and uploading market board data.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal class NetworkHandlers
|
||||
internal class NetworkHandlers : IServiceType
|
||||
{
|
||||
private readonly List<MarketBoardItemRequest> marketBoardRequests = new();
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Dalamud.Game.Network.Internal
|
|||
/// This class enables TCP optimizations in the game socket for better performance.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal sealed class WinSockHandlers : IDisposable
|
||||
internal sealed class WinSockHandlers : IDisposable, IServiceType
|
||||
{
|
||||
private Hook<SocketDelegate> ws2SocketHook;
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Dalamud.Game
|
|||
/// </summary>
|
||||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
public class SigScanner : IDisposable
|
||||
public class SigScanner : IDisposable, IServiceType
|
||||
{
|
||||
private readonly FileInfo? cacheFile;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ namespace Dalamud.Game.Text.SeStringHandling
|
|||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
[Obsolete("This class is obsolete. Please use the static methods on SeString instead.")]
|
||||
public sealed class SeStringManager
|
||||
public sealed class SeStringManager : IServiceType
|
||||
{
|
||||
[ServiceManager.ServiceConstructor]
|
||||
private SeStringManager()
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ namespace Dalamud.Hooking.Internal
|
|||
/// This class manages the final disposition of hooks, cleaning up any that have not reverted their changes.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal class HookManager : IDisposable
|
||||
internal class HookManager : IDisposable, IServiceType
|
||||
{
|
||||
private static readonly ModuleLog Log = new("HM");
|
||||
|
||||
|
|
|
|||
8
Dalamud/IServiceType.cs
Normal file
8
Dalamud/IServiceType.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
namespace Dalamud;
|
||||
|
||||
/// <summary>
|
||||
/// Marker class for service types.
|
||||
/// </summary>
|
||||
public interface IServiceType
|
||||
{
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ namespace Dalamud.Interface.GameFonts
|
|||
/// Loads game font for use in ImGui.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal class GameFontManager : IDisposable
|
||||
internal class GameFontManager : IDisposable, IServiceType
|
||||
{
|
||||
private static readonly string?[] FontNames =
|
||||
{
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Dalamud.Interface.Internal
|
|||
/// Class handling Dalamud core commands.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal class DalamudCommands
|
||||
internal class DalamudCommands : IServiceType
|
||||
{
|
||||
[ServiceManager.ServiceConstructor]
|
||||
private DalamudCommands(CommandManager commandManager)
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ namespace Dalamud.Interface.Internal
|
|||
/// <summary>
|
||||
/// This plugin implements all of the Dalamud interface separately, to allow for reloading of the interface and rapid prototyping.
|
||||
/// </summary>
|
||||
[ServiceManager.AfterDrawingEarlyLoadedService]
|
||||
internal class DalamudInterface : IDisposable
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal class DalamudInterface : IDisposable, IServiceType
|
||||
{
|
||||
private static readonly ModuleLog Log = new("DUI");
|
||||
|
||||
|
|
@ -77,8 +77,12 @@ namespace Dalamud.Interface.Internal
|
|||
private bool isImGuiDrawMetricsWindow = false;
|
||||
|
||||
[ServiceManager.ServiceConstructor]
|
||||
private DalamudInterface(Dalamud dalamud, DalamudConfiguration configuration, InterfaceManager interfaceManager)
|
||||
private DalamudInterface(
|
||||
Dalamud dalamud,
|
||||
DalamudConfiguration configuration,
|
||||
InterfaceManager.InterfaceManagerWithScene interfaceManagerWithScene)
|
||||
{
|
||||
var interfaceManager = interfaceManagerWithScene.Manager;
|
||||
this.WindowSystem = new WindowSystem("DalamudCore");
|
||||
|
||||
this.changelogWindow = new ChangelogWindow() { IsOpen = false };
|
||||
|
|
|
|||
|
|
@ -7,12 +7,10 @@ using System.Runtime.CompilerServices;
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Game;
|
||||
using Dalamud.Game.ClientState.GamePad;
|
||||
using Dalamud.Game.ClientState.Keys;
|
||||
using Dalamud.Game.Gui.Internal;
|
||||
using Dalamud.Game.Internal.DXGI;
|
||||
using Dalamud.Hooking;
|
||||
using Dalamud.Interface.GameFonts;
|
||||
|
|
@ -45,7 +43,7 @@ namespace Dalamud.Interface.Internal
|
|||
/// This class manages interaction with the ImGui interface.
|
||||
/// </summary>
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
internal class InterfaceManager : IDisposable
|
||||
internal class InterfaceManager : IDisposable, IServiceType
|
||||
{
|
||||
private const float MinimumFallbackFontSizePt = 9.6f; // Game's minimum AXIS font size
|
||||
private const float MinimumFallbackFontSizePx = MinimumFallbackFontSizePt * 4.0f / 3.0f;
|
||||
|
|
@ -61,7 +59,6 @@ namespace Dalamud.Interface.Internal
|
|||
|
||||
private readonly ManualResetEvent fontBuildSignal;
|
||||
private readonly SwapChainVtableResolver address;
|
||||
private readonly TaskCompletionSource sceneInitializeTaskCompletionSource = new();
|
||||
private RawDX11Scene? scene;
|
||||
|
||||
private Hook<PresentDelegate>? presentHook;
|
||||
|
|
@ -71,7 +68,7 @@ namespace Dalamud.Interface.Internal
|
|||
// can't access imgui IO before first present call
|
||||
private bool lastWantCapture = false;
|
||||
private bool isRebuildingFonts = false;
|
||||
|
||||
private bool isOverrideGameCursor = false;
|
||||
private bool isFallbackFontMode = false;
|
||||
|
||||
[ServiceManager.ServiceConstructor]
|
||||
|
|
@ -100,13 +97,6 @@ namespace Dalamud.Interface.Internal
|
|||
{
|
||||
Log.Error(e, "RTSS Free failed");
|
||||
}
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var framework = await Service<Framework>.GetAsync();
|
||||
var sigScanner = await Service<SigScanner>.GetAsync();
|
||||
await framework.RunOnFrameworkThread(() => this.Enable(sigScanner));
|
||||
});
|
||||
}
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
|
||||
|
|
@ -160,11 +150,6 @@ namespace Dalamud.Interface.Internal
|
|||
/// </summary>
|
||||
public static ImFontPtr MonoFont { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a task that gets completed when scene gets initialized.
|
||||
/// </summary>
|
||||
public Task SceneInitializeTask => this.sceneInitializeTaskCompletionSource.Task;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the pointer to ImGui.IO(), when it was last used.
|
||||
/// </summary>
|
||||
|
|
@ -178,15 +163,20 @@ namespace Dalamud.Interface.Internal
|
|||
/// <summary>
|
||||
/// Gets the address handle to the main process window.
|
||||
/// </summary>
|
||||
public IntPtr WindowHandlePtr => this.scene.WindowHandlePtr;
|
||||
public IntPtr WindowHandlePtr => this.scene?.WindowHandlePtr ?? IntPtr.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether or not the game's cursor should be overridden with the ImGui cursor.
|
||||
/// </summary>
|
||||
public bool OverrideGameCursor
|
||||
{
|
||||
get => this.scene.UpdateCursor;
|
||||
set => this.scene.UpdateCursor = value;
|
||||
get => this.scene?.UpdateCursor ?? this.isOverrideGameCursor;
|
||||
set
|
||||
{
|
||||
this.isOverrideGameCursor = value;
|
||||
if (this.scene != null)
|
||||
this.scene.UpdateCursor = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -353,6 +343,12 @@ namespace Dalamud.Interface.Internal
|
|||
/// </summary>
|
||||
public void RebuildFonts()
|
||||
{
|
||||
if (this.scene == null)
|
||||
{
|
||||
Log.Verbose("[FONT] RebuildFonts(): scene not ready, doing nothing");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Verbose("[FONT] RebuildFonts() called");
|
||||
|
||||
// don't invoke this multiple times per frame, in case multiple plugins call it
|
||||
|
|
@ -448,7 +444,7 @@ namespace Dalamud.Interface.Internal
|
|||
private IntPtr PresentDetour(IntPtr swapChain, uint syncInterval, uint presentFlags)
|
||||
{
|
||||
if (this.scene != null && swapChain != this.scene.SwapChain.NativePointer)
|
||||
return this.presentHook.Original(swapChain, syncInterval, presentFlags);
|
||||
return this.presentHook!.Original(swapChain, syncInterval, presentFlags);
|
||||
|
||||
if (this.scene == null)
|
||||
{
|
||||
|
|
@ -460,7 +456,7 @@ namespace Dalamud.Interface.Internal
|
|||
}
|
||||
catch (DllNotFoundException ex)
|
||||
{
|
||||
this.sceneInitializeTaskCompletionSource.SetException(ex);
|
||||
Service<InterfaceManagerWithScene>.ProvideException(ex);
|
||||
Log.Error(ex, "Could not load ImGui dependencies.");
|
||||
|
||||
var res = PInvoke.User32.MessageBox(
|
||||
|
|
@ -501,6 +497,7 @@ namespace Dalamud.Interface.Internal
|
|||
Log.Error(ex, "Could not delete dalamudUI.ini");
|
||||
}
|
||||
|
||||
this.scene.UpdateCursor = this.isOverrideGameCursor;
|
||||
this.scene.ImGuiIniPath = iniFileInfo.FullName;
|
||||
this.scene.OnBuildUI += this.Display;
|
||||
this.scene.OnNewInputFrame += this.OnNewInputFrame;
|
||||
|
|
@ -566,7 +563,7 @@ namespace Dalamud.Interface.Internal
|
|||
|
||||
Log.Information("[IM] Scene & ImGui setup OK!");
|
||||
|
||||
Service<DalamudIME>.Get().Enable();
|
||||
Service<Framework>.Get().RunOnFrameworkThread(() => Service<InterfaceManagerWithScene>.Provide(new(this)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -576,17 +573,11 @@ namespace Dalamud.Interface.Internal
|
|||
|
||||
this.RenderImGui();
|
||||
|
||||
if (!this.SceneInitializeTask.IsCompleted)
|
||||
this.sceneInitializeTaskCompletionSource.SetResult();
|
||||
|
||||
return pRes;
|
||||
}
|
||||
|
||||
this.RenderImGui();
|
||||
|
||||
if (!this.SceneInitializeTask.IsCompleted)
|
||||
this.sceneInitializeTaskCompletionSource.SetResult();
|
||||
|
||||
return this.presentHook.Original(swapChain, syncInterval, presentFlags);
|
||||
}
|
||||
|
||||
|
|
@ -987,21 +978,20 @@ namespace Dalamud.Interface.Internal
|
|||
}
|
||||
}
|
||||
|
||||
private void Enable(SigScanner sigScanner)
|
||||
[ServiceManager.CallWhenServicesReady]
|
||||
private void ContinueConstruction(SigScanner sigScanner)
|
||||
{
|
||||
this.address.Setup(sigScanner);
|
||||
this.setCursorHook = Hook<SetCursorDelegate>.FromSymbol("user32.dll", "SetCursor", this.SetCursorDetour, true);
|
||||
this.setCursorHook = Hook<SetCursorDelegate>.FromSymbol("user32.dll", "SetCursor", this.SetCursorDetour, true)!;
|
||||
this.presentHook = new Hook<PresentDelegate>(this.address.Present, this.PresentDetour);
|
||||
this.resizeBuffersHook = new Hook<ResizeBuffersDelegate>(this.address.ResizeBuffers, this.ResizeBuffersDetour);
|
||||
|
||||
var setCursorAddress = this.setCursorHook?.Address ?? IntPtr.Zero;
|
||||
|
||||
Log.Verbose("===== S W A P C H A I N =====");
|
||||
Log.Verbose($"SetCursor address 0x{setCursorAddress.ToInt64():X}");
|
||||
Log.Verbose($"Present address 0x{this.presentHook.Address.ToInt64():X}");
|
||||
Log.Verbose($"ResizeBuffers address 0x{this.resizeBuffersHook.Address.ToInt64():X}");
|
||||
Log.Verbose($"SetCursor address 0x{this.setCursorHook!.Address.ToInt64():X}");
|
||||
Log.Verbose($"Present address 0x{this.presentHook!.Address.ToInt64():X}");
|
||||
Log.Verbose($"ResizeBuffers address 0x{this.resizeBuffersHook!.Address.ToInt64():X}");
|
||||
|
||||
this.setCursorHook?.Enable();
|
||||
this.setCursorHook.Enable();
|
||||
this.presentHook.Enable();
|
||||
this.resizeBuffersHook.Enable();
|
||||
|
||||
|
|
@ -1027,8 +1017,8 @@ namespace Dalamud.Interface.Internal
|
|||
private void Disable()
|
||||
{
|
||||
this.setCursorHook?.Disable();
|
||||
this.presentHook.Disable();
|
||||
this.resizeBuffersHook.Disable();
|
||||
this.presentHook?.Disable();
|
||||
this.resizeBuffersHook?.Disable();
|
||||
}
|
||||
|
||||
// This is intended to only be called as a handler attached to scene.OnNewRenderFrame
|
||||
|
|
@ -1038,7 +1028,7 @@ namespace Dalamud.Interface.Internal
|
|||
this.SetupFonts();
|
||||
|
||||
Log.Verbose("[FONT] RebuildFontsInternal() detaching");
|
||||
this.scene.OnNewRenderFrame -= this.RebuildFontsInternal;
|
||||
this.scene!.OnNewRenderFrame -= this.RebuildFontsInternal;
|
||||
|
||||
Log.Verbose("[FONT] Calling InvalidateFonts");
|
||||
try
|
||||
|
|
@ -1086,11 +1076,11 @@ namespace Dalamud.Interface.Internal
|
|||
// We have to ensure we're working with the main swapchain,
|
||||
// as viewports might be resizing as well
|
||||
if (this.scene == null || swapChain != this.scene.SwapChain.NativePointer)
|
||||
return this.resizeBuffersHook.Original(swapChain, bufferCount, width, height, newFormat, swapChainFlags);
|
||||
return this.resizeBuffersHook!.Original(swapChain, bufferCount, width, height, newFormat, swapChainFlags);
|
||||
|
||||
this.scene?.OnPreResize();
|
||||
|
||||
var ret = this.resizeBuffersHook.Original(swapChain, bufferCount, width, height, newFormat, swapChainFlags);
|
||||
var ret = this.resizeBuffersHook!.Original(swapChain, bufferCount, width, height, newFormat, swapChainFlags);
|
||||
if (ret.ToInt64() == 0x887A0001)
|
||||
{
|
||||
Log.Error("invalid call to resizeBuffers");
|
||||
|
|
@ -1106,7 +1096,7 @@ namespace Dalamud.Interface.Internal
|
|||
if (this.lastWantCapture == true && (!this.scene?.IsImGuiCursor(hCursor) ?? false) && this.OverrideGameCursor)
|
||||
return IntPtr.Zero;
|
||||
|
||||
return this.setCursorHook.Original(hCursor);
|
||||
return this.setCursorHook!.Original(hCursor);
|
||||
}
|
||||
|
||||
private void OnNewInputFrame()
|
||||
|
|
@ -1194,6 +1184,26 @@ namespace Dalamud.Interface.Internal
|
|||
Service<NotificationManager>.Get().Draw();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents an instance of InstanceManager with scene ready for use.
|
||||
/// </summary>
|
||||
public class InterfaceManagerWithScene : IServiceType
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="InterfaceManagerWithScene"/> class.
|
||||
/// </summary>
|
||||
/// <param name="interfaceManager">An instance of <see cref="InterfaceManager"/>.</param>
|
||||
internal InterfaceManagerWithScene(InterfaceManager interfaceManager)
|
||||
{
|
||||
this.Manager = interfaceManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Associated InterfaceManager.
|
||||
/// </summary>
|
||||
public InterfaceManager Manager { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a glyph request.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ namespace Dalamud.Interface.Internal.Notifications
|
|||
/// Ported from https://github.com/patrickcjk/imgui-notify.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal class NotificationManager
|
||||
internal class NotificationManager : IServiceType
|
||||
{
|
||||
/// <summary>
|
||||
/// Value indicating the bottom-left X padding.
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace Dalamud.Interface
|
|||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public class TitleScreenMenu
|
||||
public class TitleScreenMenu : IServiceType
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the texture size needed for title screen menu logos.
|
||||
|
|
|
|||
|
|
@ -109,12 +109,12 @@ namespace Dalamud.Interface
|
|||
/// <summary>
|
||||
/// Gets the game's active Direct3D device.
|
||||
/// </summary>
|
||||
public Device Device => Service<InterfaceManager>.Get().Device;
|
||||
public Device Device => Service<InterfaceManager.InterfaceManagerWithScene>.Get().Manager.Device!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the game's main window handle.
|
||||
/// </summary>
|
||||
public IntPtr WindowHandlePtr => Service<InterfaceManager>.Get().WindowHandlePtr;
|
||||
public IntPtr WindowHandlePtr => Service<InterfaceManager.InterfaceManagerWithScene>.Get().Manager.WindowHandlePtr;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this plugin should hide its UI automatically when the game's UI is hidden.
|
||||
|
|
@ -215,7 +215,7 @@ namespace Dalamud.Interface
|
|||
/// <param name="filePath">The full filepath to the image.</param>
|
||||
/// <returns>A <see cref="TextureWrap"/> object wrapping the created image. Use <see cref="TextureWrap.ImGuiHandle"/> inside ImGui.Image().</returns>
|
||||
public TextureWrap LoadImage(string filePath)
|
||||
=> Service<InterfaceManager>.Get().LoadImage(filePath);
|
||||
=> Service<InterfaceManager.InterfaceManagerWithScene>.Get().Manager.LoadImage(filePath);
|
||||
|
||||
/// <summary>
|
||||
/// Loads an image from a byte stream, such as a png downloaded into memory.
|
||||
|
|
@ -223,7 +223,7 @@ namespace Dalamud.Interface
|
|||
/// <param name="imageData">A byte array containing the raw image data.</param>
|
||||
/// <returns>A <see cref="TextureWrap"/> object wrapping the created image. Use <see cref="TextureWrap.ImGuiHandle"/> inside ImGui.Image().</returns>
|
||||
public TextureWrap LoadImage(byte[] imageData)
|
||||
=> Service<InterfaceManager>.Get().LoadImage(imageData);
|
||||
=> Service<InterfaceManager.InterfaceManagerWithScene>.Get().Manager.LoadImage(imageData);
|
||||
|
||||
/// <summary>
|
||||
/// Loads an image from raw unformatted pixel data, with no type or header information. To load formatted data, use <see cref="LoadImage(byte[])"/>.
|
||||
|
|
@ -234,7 +234,7 @@ namespace Dalamud.Interface
|
|||
/// <param name="numChannels">The number of channels (bytes per pixel) of the image contained in <paramref name="imageData"/>. This should usually be 4.</param>
|
||||
/// <returns>A <see cref="TextureWrap"/> object wrapping the created image. Use <see cref="TextureWrap.ImGuiHandle"/> inside ImGui.Image().</returns>
|
||||
public TextureWrap LoadImageRaw(byte[] imageData, int width, int height, int numChannels)
|
||||
=> Service<InterfaceManager>.Get().LoadImageRaw(imageData, width, height, numChannels);
|
||||
=> Service<InterfaceManager.InterfaceManagerWithScene>.Get().Manager.LoadImageRaw(imageData, width, height, numChannels);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a game font.
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace Dalamud.IoC.Internal
|
|||
/// <summary>
|
||||
/// A simple singleton-only IOC container that provides (optional) version-based dependency resolution.
|
||||
/// </summary>
|
||||
internal class ServiceContainer : IServiceProvider
|
||||
internal class ServiceContainer : IServiceProvider, IServiceType
|
||||
{
|
||||
private static readonly ModuleLog Log = new("SERVICECONTAINER");
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ namespace Dalamud
|
|||
/// Class handling localization.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
public class Localization
|
||||
public class Localization : IServiceType
|
||||
{
|
||||
/// <summary>
|
||||
/// Array of language codes which have a valid translation in Dalamud.
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace Dalamud.Logging.Internal
|
|||
/// Class responsible for tracking asynchronous tasks.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal class TaskTracker : IDisposable
|
||||
internal class TaskTracker : IDisposable, IServiceType
|
||||
{
|
||||
private static readonly ModuleLog Log = new("TT");
|
||||
private static readonly List<TaskInfo> TrackedTasksInternal = new();
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace Dalamud.Plugin.Internal;
|
|||
/// Class responsible for loading and unloading plugins.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal partial class PluginManager : IDisposable
|
||||
internal partial class PluginManager : IDisposable, IServiceType
|
||||
{
|
||||
/// <summary>
|
||||
/// The current Dalamud API level, used to handle breaking changes. Only plugins with this level will be loaded.
|
||||
|
|
@ -386,12 +386,8 @@ internal partial class PluginManager : IDisposable
|
|||
|
||||
// Load plugins that want to be loaded during Framework.Tick, when drawing facilities are available
|
||||
loadTasks.Add(
|
||||
Service<InterfaceManager>
|
||||
Service<InterfaceManager.InterfaceManagerWithScene>
|
||||
.GetAsync()
|
||||
.ContinueWith(
|
||||
x => x.Result.SceneInitializeTask,
|
||||
TaskContinuationOptions.RunContinuationsAsynchronously)
|
||||
.Unwrap()
|
||||
.ContinueWith(
|
||||
_ => Service<Framework>.Get().RunOnTick(
|
||||
() => LoadPluginsSync(
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Dalamud.Plugin.Internal;
|
|||
/// Class responsible for loading plugins on startup.
|
||||
/// </summary>
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public class StartupPluginLoader
|
||||
public class StartupPluginLoader : IServiceType
|
||||
{
|
||||
private static readonly ModuleLog Log = new("SPL");
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ namespace Dalamud.Plugin.Ipc.Internal
|
|||
/// This class facilitates inter-plugin communication.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal class CallGate
|
||||
internal class CallGate : IServiceType
|
||||
{
|
||||
private readonly Dictionary<string, CallGateChannel> gates = new();
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ using System.Reflection;
|
|||
using System.Threading.Tasks;
|
||||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Game;
|
||||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.IoC.Internal;
|
||||
using Dalamud.Logging.Internal;
|
||||
using Dalamud.Utility.Timing;
|
||||
|
|
@ -67,7 +66,6 @@ namespace Dalamud
|
|||
|
||||
var earlyLoadingServices = new HashSet<Type>();
|
||||
var blockingEarlyLoadingServices = new HashSet<Type>();
|
||||
var afterDrawingEarlyLoadedServices = new HashSet<Type>();
|
||||
|
||||
var dependencyServicesMap = new Dictionary<Type, List<Type>>();
|
||||
var getAsyncTaskMap = new Dictionary<Type, Task>();
|
||||
|
|
@ -90,10 +88,6 @@ namespace Dalamud
|
|||
getAsyncTaskMap[serviceType] = getTask;
|
||||
blockingEarlyLoadingServices.Add(serviceType);
|
||||
}
|
||||
else if (attr.IsAssignableTo(typeof(AfterDrawingEarlyLoadedService)))
|
||||
{
|
||||
afterDrawingEarlyLoadedServices.Add(serviceType);
|
||||
}
|
||||
else
|
||||
{
|
||||
earlyLoadingServices.Add(serviceType);
|
||||
|
|
@ -125,21 +119,11 @@ namespace Dalamud
|
|||
}).ConfigureAwait(false);
|
||||
|
||||
try
|
||||
{
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
var tasks = new List<Task>();
|
||||
var servicesToLoad = new HashSet<Type>();
|
||||
if (i == 0)
|
||||
{
|
||||
servicesToLoad.UnionWith(earlyLoadingServices);
|
||||
servicesToLoad.UnionWith(blockingEarlyLoadingServices);
|
||||
}
|
||||
else
|
||||
{
|
||||
servicesToLoad.UnionWith(afterDrawingEarlyLoadedServices);
|
||||
await (await Service<InterfaceManager>.GetAsync()).SceneInitializeTask;
|
||||
}
|
||||
|
||||
while (servicesToLoad.Any())
|
||||
{
|
||||
|
|
@ -176,7 +160,6 @@ namespace Dalamud
|
|||
tasks.RemoveAll(x => x.IsCompleted);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e, "Failed resolving services");
|
||||
|
|
@ -236,11 +219,11 @@ namespace Dalamud
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the class is a service, and will be instantiated automatically on startup,
|
||||
/// when drawing becomes available.
|
||||
/// Indicates that the method should be called when the services given in the constructor are ready.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class AfterDrawingEarlyLoadedService : EarlyLoadedService
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
[MeansImplicitUse]
|
||||
public class CallWhenServicesReady : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Dalamud.IoC;
|
||||
using Dalamud.IoC.Internal;
|
||||
|
|
@ -18,7 +17,7 @@ namespace Dalamud
|
|||
/// Only used internally within Dalamud, if plugins need access to things it should be _only_ via DI.
|
||||
/// </remarks>
|
||||
/// <typeparam name="T">The class you want to store in the service locator.</typeparam>
|
||||
internal static class Service<T>
|
||||
internal static class Service<T> where T : IServiceType
|
||||
{
|
||||
// ReSharper disable once StaticMemberInGenericType
|
||||
private static readonly TaskCompletionSource<T> InstanceTcs = new();
|
||||
|
|
@ -51,10 +50,23 @@ namespace Dalamud
|
|||
ServiceManager.Log.Debug("Service<{0}>: Begin construction", typeof(T).Name);
|
||||
try
|
||||
{
|
||||
var x = await ConstructObject();
|
||||
var instance = await ConstructObject();
|
||||
InstanceTcs.SetResult(instance);
|
||||
|
||||
foreach (var method in typeof(T).GetMethods(
|
||||
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
|
||||
{
|
||||
if (method.GetCustomAttribute<ServiceManager.CallWhenServicesReady>(true) == null)
|
||||
continue;
|
||||
|
||||
ServiceManager.Log.Debug("Service<{0}>: Calling {1}", typeof(T).Name, method.Name);
|
||||
var args = await Task.WhenAll(method.GetParameters().Select(
|
||||
x => ResolveServiceFromTypeAsync(x.ParameterType)));
|
||||
method.Invoke(instance, args);
|
||||
}
|
||||
|
||||
ServiceManager.Log.Debug("Service<{0}>: Construction complete", typeof(T).Name);
|
||||
InstanceTcs.SetResult(x);
|
||||
return x;
|
||||
return instance;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
@ -71,10 +83,20 @@ namespace Dalamud
|
|||
/// <param name="obj">Object to set.</param>
|
||||
public static void Provide(T obj)
|
||||
{
|
||||
InstanceTcs!.SetResult(obj);
|
||||
InstanceTcs.SetResult(obj);
|
||||
ServiceManager.Log.Debug("Service<{0}>: Provided", typeof(T).Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the service load state to failure.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception.</param>
|
||||
public static void ProvideException(Exception exception)
|
||||
{
|
||||
ServiceManager.Log.Error(exception, "Service<{0}>: Error", typeof(T).Name);
|
||||
InstanceTcs.SetException(exception);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pull the instance out of the service locator, waiting if necessary.
|
||||
/// </summary>
|
||||
|
|
@ -103,6 +125,7 @@ namespace Dalamud
|
|||
/// Gets an enumerable containing Service<T>s that are required for this Service to initialize without blocking.
|
||||
/// </summary>
|
||||
/// <returns>List of dependency services.</returns>
|
||||
[UsedImplicitly]
|
||||
public static List<Type> GetDependencyServices()
|
||||
{
|
||||
var res = new List<Type>();
|
||||
|
|
@ -119,7 +142,7 @@ namespace Dalamud
|
|||
.ToList();
|
||||
}
|
||||
|
||||
private static async Task<object?> GetServiceObjectConstructArgument(Type type)
|
||||
private static async Task<object?> ResolveServiceFromTypeAsync(Type type)
|
||||
{
|
||||
var task = (Task)typeof(Service<>)
|
||||
.MakeGenericType(type)
|
||||
|
|
@ -151,7 +174,7 @@ namespace Dalamud
|
|||
{
|
||||
var ctor = GetServiceConstructor();
|
||||
var args = await Task.WhenAll(
|
||||
ctor.GetParameters().Select(x => GetServiceObjectConstructArgument(x.ParameterType)));
|
||||
ctor.GetParameters().Select(x => ResolveServiceFromTypeAsync(x.ParameterType)));
|
||||
using (Timings.Start($"{typeof(T).Name} Construct"))
|
||||
{
|
||||
return (T)ctor.Invoke(args)!;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue