Implement service locator

This commit is contained in:
Raymond 2021-08-20 11:59:35 -04:00
parent 06b1163a52
commit ff1d7f2829
101 changed files with 1614 additions and 1436 deletions

View file

@ -3,11 +3,14 @@ using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using Dalamud.Configuration.Internal;
using Dalamud.Game.Libc;
using Dalamud.Game.Text;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.Hooking;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Serilog;
namespace Dalamud.Game.Gui
@ -15,9 +18,10 @@ namespace Dalamud.Game.Gui
/// <summary>
/// This class handles interacting with the native chat UI.
/// </summary>
[PluginInterface]
[InterfaceVersion("1.0")]
public sealed class ChatGui : IDisposable
{
private readonly Dalamud dalamud;
private readonly ChatGuiAddressResolver address;
private readonly Queue<XivChatEntry> chatQueue = new();
@ -33,14 +37,10 @@ namespace Dalamud.Game.Gui
/// Initializes a new instance of the <see cref="ChatGui"/> class.
/// </summary>
/// <param name="baseAddress">The base address of the ChatManager.</param>
/// <param name="scanner">The SigScanner instance.</param>
/// <param name="dalamud">The Dalamud instance.</param>
internal ChatGui(IntPtr baseAddress, SigScanner scanner, Dalamud dalamud)
internal ChatGui(IntPtr baseAddress)
{
this.dalamud = dalamud;
this.address = new ChatGuiAddressResolver(baseAddress);
this.address.Setup(scanner);
this.address.Setup();
Log.Verbose($"Chat manager address 0x{this.address.BaseAddress.ToInt64():X}");
@ -163,11 +163,13 @@ namespace Dalamud.Game.Gui
/// <param name="message">A message to send.</param>
public void Print(string message)
{
var configuration = Service<DalamudConfiguration>.Get();
Log.Verbose("[CHATGUI PRINT REGULAR]{0}", message);
this.PrintChat(new XivChatEntry
{
Message = message,
Type = this.dalamud.Configuration.GeneralChatType,
Type = configuration.GeneralChatType,
});
}
@ -178,11 +180,13 @@ namespace Dalamud.Game.Gui
/// <param name="message">A message to send.</param>
public void Print(SeString message)
{
var configuration = Service<DalamudConfiguration>.Get();
Log.Verbose("[CHATGUI PRINT SESTRING]{0}", message.TextValue);
this.PrintChat(new XivChatEntry
{
Message = message,
Type = this.dalamud.Configuration.GeneralChatType,
Type = configuration.GeneralChatType,
});
}
@ -219,8 +223,7 @@ namespace Dalamud.Game.Gui
/// <summary>
/// Process a chat queue.
/// </summary>
/// <param name="framework">The Framework instance.</param>
public void UpdateQueue(Framework framework)
public void UpdateQueue()
{
while (this.chatQueue.Count > 0)
{
@ -232,10 +235,10 @@ namespace Dalamud.Game.Gui
}
var senderRaw = (chat.Name ?? string.Empty).Encode();
using var senderOwned = framework.Libc.NewString(senderRaw);
using var senderOwned = Service<LibcFunction>.Get().NewString(senderRaw);
var messageRaw = (chat.Message ?? string.Empty).Encode();
using var messageOwned = framework.Libc.NewString(messageRaw);
using var messageOwned = Service<LibcFunction>.Get().NewString(messageRaw);
this.HandlePrintMessageDetour(this.baseAddress, chat.Type, senderOwned.Address, messageOwned.Address, chat.SenderId, chat.Parameters);
}
@ -353,8 +356,8 @@ namespace Dalamud.Game.Gui
var sender = StdString.ReadFromPointer(pSenderName);
var message = StdString.ReadFromPointer(pMessage);
var parsedSender = this.dalamud.SeStringManager.Parse(sender.RawData);
var parsedMessage = this.dalamud.SeStringManager.Parse(message.RawData);
var parsedSender = Service<SeStringManager>.Get().Parse(sender.RawData);
var parsedMessage = Service<SeStringManager>.Get().Parse(message.RawData);
Log.Verbose("[CHATGUI][{0}][{1}]", parsedSender.TextValue, parsedMessage.TextValue);
@ -386,7 +389,7 @@ namespace Dalamud.Game.Gui
if (!FastByteArrayCompare(originalMessageData, message.RawData))
{
allocatedString = this.dalamud.Framework.Libc.NewString(message.RawData);
allocatedString = Service<LibcFunction>.Get().NewString(message.RawData);
Log.Debug(
$"HandlePrintMessageDetour String modified: {originalMessageData}({messagePtr}) -> {message}({allocatedString.Address})");
messagePtr = allocatedString.Address;
@ -436,7 +439,7 @@ namespace Dalamud.Game.Gui
while (Marshal.ReadByte(payloadPtr, messageSize) != 0) messageSize++;
var payloadBytes = new byte[messageSize];
Marshal.Copy(payloadPtr, payloadBytes, 0, messageSize);
var seStr = this.dalamud.SeStringManager.Parse(payloadBytes);
var seStr = Service<SeStringManager>.Get().Parse(payloadBytes);
var terminatorIndex = seStr.Payloads.IndexOf(RawPayload.LinkTerminator);
var payloads = terminatorIndex >= 0 ? seStr.Payloads.Take(terminatorIndex + 1).ToList() : seStr.Payloads;
if (payloads.Count == 0) return;

View file

@ -4,8 +4,9 @@ using System.Threading.Tasks;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Hooking;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Memory;
using FFXIVClientStructs.FFXIV.Client.UI;
using Serilog;
namespace Dalamud.Game.Gui.FlyText
@ -13,6 +14,8 @@ namespace Dalamud.Game.Gui.FlyText
/// <summary>
/// This class facilitates interacting with and creating native in-game "fly text".
/// </summary>
[PluginInterface]
[InterfaceVersion("1.0")]
public sealed class FlyTextGui : IDisposable
{
/// <summary>
@ -28,14 +31,10 @@ namespace Dalamud.Game.Gui.FlyText
/// <summary>
/// Initializes a new instance of the <see cref="FlyTextGui"/> class.
/// </summary>
/// <param name="scanner">The SigScanner instance.</param>
/// <param name="dalamud">The Dalamud instance.</param>
internal FlyTextGui(SigScanner scanner, Dalamud dalamud)
internal FlyTextGui()
{
this.Dalamud = dalamud;
this.Address = new FlyTextGuiAddressResolver();
this.Address.Setup(scanner);
this.Address.Setup();
this.addFlyTextNative = Marshal.GetDelegateForFunctionPointer<AddFlyTextDelegate>(this.Address.AddFlyText);
this.createFlyTextHook = new Hook<CreateFlyTextDelegate>(this.Address.CreateFlyText, this.CreateFlyTextDetour);
@ -132,8 +131,9 @@ namespace Dalamud.Game.Gui.FlyText
var strOffset = 28u;
// Get the UI module and flytext addon pointers
var ui = (UIModule*)this.Dalamud.Framework.Gui.GetUIModule();
var flytext = this.Dalamud.Framework.Gui.GetAddonByName("_FlyText", 1);
var gameGui = Service<GameGui>.Get();
var ui = (FFXIVClientStructs.FFXIV.Client.UI.UIModule*)gameGui.GetUIModule();
var flytext = gameGui.GetAddonByName("_FlyText", 1);
if (ui == null || flytext == IntPtr.Zero)
return;

View file

@ -8,6 +8,8 @@ using Dalamud.Game.Gui.Toast;
using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.Hooking;
using Dalamud.Interface;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Utility;
using ImGuiNET;
using Serilog;
@ -17,9 +19,10 @@ namespace Dalamud.Game.Gui
/// <summary>
/// A class handling many aspects of the in-game UI.
/// </summary>
[PluginInterface]
[InterfaceVersion("1.0")]
public sealed class GameGui : IDisposable
{
private readonly Dalamud dalamud;
private readonly GameGuiAddressResolver address;
private readonly GetMatrixSingletonDelegate getMatrixSingleton;
@ -41,15 +44,10 @@ namespace Dalamud.Game.Gui
/// Initializes a new instance of the <see cref="GameGui"/> class.
/// This class is responsible for many aspects of interacting with the native game UI.
/// </summary>
/// <param name="baseAddress">The base address of the native GuiManager class.</param>
/// <param name="scanner">The SigScanner instance.</param>
/// <param name="dalamud">The Dalamud instance.</param>
internal GameGui(IntPtr baseAddress, SigScanner scanner, Dalamud dalamud)
internal GameGui()
{
this.dalamud = dalamud;
this.address = new GameGuiAddressResolver(baseAddress);
this.address.Setup(scanner);
this.address = new GameGuiAddressResolver(this.address.BaseAddress);
this.address.Setup();
Log.Verbose("===== G A M E G U I =====");
@ -60,10 +58,10 @@ namespace Dalamud.Game.Gui
Log.Verbose($"HandleImm address 0x{this.address.HandleImm.ToInt64():X}");
Log.Verbose($"GetAgentModule address 0x{this.address.GetAgentModule.ToInt64():X}");
this.Chat = new ChatGui(this.address.ChatManager, scanner, dalamud);
this.PartyFinder = new PartyFinderGui(scanner, dalamud);
this.Toast = new ToastGui(scanner, dalamud);
this.FlyText = new FlyTextGui(scanner, dalamud);
Service<ChatGui>.Set(new ChatGui(this.address.ChatManager));
Service<PartyFinderGui>.Set();
Service<ToastGui>.Set();
Service<FlyTextGui>.Set();
this.setGlobalBgmHook = new Hook<SetGlobalBgmDelegate>(this.address.SetGlobalBgm, this.HandleSetGlobalBgmDetour);
@ -128,26 +126,6 @@ namespace Dalamud.Game.Gui
/// </summary>
public event EventHandler<bool> OnUiHideToggled;
/// <summary>
/// Gets the <see cref="Chat"/> instance.
/// </summary>
public ChatGui Chat { get; private set; }
/// <summary>
/// Gets the <see cref="PartyFinder"/> instance.
/// </summary>
public PartyFinderGui PartyFinder { get; private set; }
/// <summary>
/// Gets the <see cref="Toast"/> instance.
/// </summary>
public ToastGui Toast { get; private set; }
/// <summary>
/// Gets the <see cref="FlyText"/> instance.
/// </summary>
public FlyTextGui FlyText { get; private set; }
/// <summary>
/// Gets a value indicating whether the game UI is hidden.
/// </summary>
@ -440,7 +418,7 @@ namespace Dalamud.Game.Gui
if (addon == IntPtr.Zero)
return IntPtr.Zero;
var uiModule = this.dalamud.Framework.Gui.GetUIModule();
var uiModule = Service<GameGui>.Get().GetUIModule();
if (uiModule == IntPtr.Zero)
{
return IntPtr.Zero;
@ -483,10 +461,10 @@ namespace Dalamud.Game.Gui
/// </summary>
public void Enable()
{
this.Chat.Enable();
this.Toast.Enable();
this.FlyText.Enable();
this.PartyFinder.Enable();
Service<ChatGui>.Get().Enable();
Service<ToastGui>.Get().Enable();
Service<FlyTextGui>.Get().Enable();
Service<PartyFinderGui>.Get().Enable();
this.setGlobalBgmHook.Enable();
this.handleItemHoverHook.Enable();
this.handleItemOutHook.Enable();
@ -501,10 +479,10 @@ namespace Dalamud.Game.Gui
/// </summary>
public void Dispose()
{
this.Chat.Dispose();
this.Toast.Dispose();
this.FlyText.Dispose();
this.PartyFinder.Dispose();
Service<ChatGui>.Get().Dispose();
Service<ToastGui>.Get().Dispose();
Service<FlyTextGui>.Get().Dispose();
Service<PartyFinderGui>.Get().Dispose();
this.setGlobalBgmHook.Dispose();
this.handleItemHoverHook.Dispose();
this.handleItemOutHook.Dispose();

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using Dalamud.Interface.Internal;
using Dalamud.Logging.Internal;
using ImGuiNET;
@ -17,8 +18,6 @@ namespace Dalamud.Game.Gui.Internal
{
private static readonly ModuleLog Log = new("IME");
private readonly Dalamud dalamud;
private IntPtr interfaceHandle;
private IntPtr wndProcPtr;
private IntPtr oldWndProcPtr;
@ -27,10 +26,8 @@ namespace Dalamud.Game.Gui.Internal
/// <summary>
/// Initializes a new instance of the <see cref="DalamudIME"/> class.
/// </summary>
/// <param name="dalamud">The Dalamud instance.</param>
internal DalamudIME(Dalamud dalamud)
internal DalamudIME()
{
this.dalamud = dalamud;
}
private delegate long WndProcDelegate(IntPtr hWnd, uint msg, ulong wParam, long lParam);
@ -68,7 +65,7 @@ namespace Dalamud.Game.Gui.Internal
try
{
this.wndProcDelegate = this.WndProcDetour;
this.interfaceHandle = this.dalamud.InterfaceManager.WindowHandlePtr;
this.interfaceHandle = Service<InterfaceManager>.Get().WindowHandlePtr;
this.wndProcPtr = Marshal.GetFunctionPointerForDelegate(this.wndProcDelegate);
this.oldWndProcPtr = SetWindowLongPtrW(this.interfaceHandle, WindowLongType.WndProc, this.wndProcPtr);
this.IsEnabled = true;
@ -83,9 +80,9 @@ namespace Dalamud.Game.Gui.Internal
private void ToggleWindow(bool visible)
{
if (visible)
this.dalamud.DalamudUi.OpenIMEWindow();
Service<DalamudInterface>.Get().OpenIMEWindow();
else
this.dalamud.DalamudUi.CloseIMEWindow();
Service<DalamudInterface>.Get().CloseIMEWindow();
}
private long WndProcDetour(IntPtr hWnd, uint msg, ulong wParam, long lParam)

View file

@ -4,6 +4,8 @@ using System.Runtime.InteropServices;
using Dalamud.Game.Gui.PartyFinder.Internal;
using Dalamud.Game.Gui.PartyFinder.Types;
using Dalamud.Hooking;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Serilog;
namespace Dalamud.Game.Gui.PartyFinder
@ -11,9 +13,10 @@ namespace Dalamud.Game.Gui.PartyFinder
/// <summary>
/// This class handles interacting with the native PartyFinder window.
/// </summary>
[PluginInterface]
[InterfaceVersion("1.0")]
public sealed class PartyFinderGui : IDisposable
{
private readonly Dalamud dalamud;
private readonly PartyFinderAddressResolver address;
private readonly IntPtr memory;
@ -22,14 +25,10 @@ namespace Dalamud.Game.Gui.PartyFinder
/// <summary>
/// Initializes a new instance of the <see cref="PartyFinderGui"/> class.
/// </summary>
/// <param name="scanner">The SigScanner instance.</param>
/// <param name="dalamud">The Dalamud instance.</param>
internal PartyFinderGui(SigScanner scanner, Dalamud dalamud)
internal PartyFinderGui()
{
this.dalamud = dalamud;
this.address = new PartyFinderAddressResolver();
this.address.Setup(scanner);
this.address.Setup();
this.memory = Marshal.AllocHGlobal(PartyFinderPacket.PacketSize);
@ -101,7 +100,7 @@ namespace Dalamud.Game.Gui.PartyFinder
continue;
}
var listing = new PartyFinderListing(packet.Listings[i], this.dalamud.Data, this.dalamud.SeStringManager);
var listing = new PartyFinderListing(packet.Listings[i]);
var args = new PartyFinderListingEventArgs(packet.BatchNumber);
this.ReceiveListing?.Invoke(listing, args);

View file

@ -14,8 +14,6 @@ namespace Dalamud.Game.Gui.PartyFinder.Types
/// </summary>
public class PartyFinderListing
{
#region Backing fields
private readonly byte objective;
private readonly byte conditions;
private readonly byte dutyFinderSettings;
@ -24,16 +22,15 @@ namespace Dalamud.Game.Gui.PartyFinder.Types
private readonly PartyFinderSlot[] slots;
private readonly byte[] jobsPresent;
#endregion
/// <summary>
/// Initializes a new instance of the <see cref="PartyFinderListing"/> class.
/// </summary>
/// <param name="listing">The interop listing data.</param>
/// <param name="dataManager">The DataManager instance.</param>
/// <param name="seStringManager">The SeStringManager instance.</param>
internal PartyFinderListing(PartyFinderPacketListing listing, DataManager dataManager, SeStringManager seStringManager)
internal PartyFinderListing(PartyFinderPacketListing listing)
{
var dataManager = Service<DataManager>.Get();
var seStringManager = Service<SeStringManager>.Get();
this.objective = listing.Objective;
this.conditions = listing.Conditions;
this.dutyFinderSettings = listing.DutyFinderSettings;

View file

@ -4,17 +4,20 @@ using System.Text;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Hooking;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
namespace Dalamud.Game.Gui.Toast
{
/// <summary>
/// This class facilitates interacting with and creating native toast windows.
/// </summary>
[PluginInterface]
[InterfaceVersion("1.0")]
public sealed partial class ToastGui : IDisposable
{
private const uint QuestToastCheckmarkMagic = 60081;
private readonly Dalamud dalamud;
private readonly ToastGuiAddressResolver address;
private readonly Queue<(byte[] Message, ToastOptions Options)> normalQueue = new();
@ -28,14 +31,10 @@ namespace Dalamud.Game.Gui.Toast
/// <summary>
/// Initializes a new instance of the <see cref="ToastGui"/> class.
/// </summary>
/// <param name="scanner">The SigScanner instance.</param>
/// <param name="dalamud">The Dalamud instance.</param>
internal ToastGui(SigScanner scanner, Dalamud dalamud)
internal ToastGui()
{
this.dalamud = dalamud;
this.address = new ToastGuiAddressResolver();
this.address.Setup(scanner);
this.address.Setup();
this.showNormalToastHook = new Hook<ShowNormalToastDelegate>(this.address.ShowNormalToast, new ShowNormalToastDelegate(this.HandleNormalToastDetour));
this.showQuestToastHook = new Hook<ShowQuestToastDelegate>(this.address.ShowQuestToast, new ShowQuestToastDelegate(this.HandleQuestToastDetour));
@ -165,7 +164,7 @@ namespace Dalamud.Game.Gui.Toast
}
// call events
return this.dalamud.SeStringManager.Parse(bytes.ToArray());
return Service<SeStringManager>.Get().Parse(bytes.ToArray());
}
}
@ -200,7 +199,7 @@ namespace Dalamud.Game.Gui.Toast
{
options ??= new ToastOptions();
var manager = this.dalamud.Framework.Gui.GetUIModule();
var manager = Service<GameGui>.Get().GetUIModule();
// terminate the string
var terminated = Terminate(bytes);
@ -281,7 +280,7 @@ namespace Dalamud.Game.Gui.Toast
{
options ??= new QuestToastOptions();
var manager = this.dalamud.Framework.Gui.GetUIModule();
var manager = Service<GameGui>.Get().GetUIModule();
// terminate the string
var terminated = Terminate(bytes);
@ -383,7 +382,7 @@ namespace Dalamud.Game.Gui.Toast
private void ShowError(byte[] bytes)
{
var manager = this.dalamud.Framework.Gui.GetUIModule();
var manager = Service<GameGui>.Get().GetUIModule();
// terminate the string
var terminated = Terminate(bytes);