From 097f85eff6386557d1e6a29de3cec9a3d1b1d6e1 Mon Sep 17 00:00:00 2001 From: KazWolfe Date: Thu, 14 Nov 2024 08:29:28 -0800 Subject: [PATCH] Move more things to ClientStructs (#2080) * GameGui uses CS methods now Co-authored-by: Infi * Shove even more things over to CS * Clean up NetworkHandlers too * bump cs so things build at least --------- Co-authored-by: Infi --- .../AddonEventManagerAddressResolver.cs | 2 +- Dalamud/Game/ClientState/ClientState.cs | 12 ++- .../ClientState/ClientStateAddressResolver.cs | 11 +-- .../Game/Config/GameConfigAddressResolver.cs | 2 +- .../DutyState/DutyStateAddressResolver.cs | 2 +- Dalamud/Game/Gui/FlyText/FlyTextGui.cs | 73 +++---------------- .../Gui/FlyText/FlyTextGuiAddressResolver.cs | 29 -------- Dalamud/Game/Gui/GameGui.cs | 39 ++++------ Dalamud/Game/Gui/GameGuiAddressResolver.cs | 17 +---- .../PartyFinder/PartyFinderAddressResolver.cs | 18 ----- .../Game/Gui/PartyFinder/PartyFinderGui.cs | 21 ++---- Dalamud/Game/Internal/DalamudAtkTweaks.cs | 6 +- Dalamud/Game/Network/GameNetwork.cs | 30 ++++---- .../Network/GameNetworkAddressResolver.cs | 10 +-- .../Game/Network/Internal/NetworkHandlers.cs | 59 +++++++-------- .../NetworkHandlersAddressResolver.cs | 49 +------------ lib/FFXIVClientStructs | 2 +- 17 files changed, 96 insertions(+), 286 deletions(-) delete mode 100644 Dalamud/Game/Gui/FlyText/FlyTextGuiAddressResolver.cs delete mode 100644 Dalamud/Game/Gui/PartyFinder/PartyFinderAddressResolver.cs diff --git a/Dalamud/Game/Addon/Events/AddonEventManagerAddressResolver.cs b/Dalamud/Game/Addon/Events/AddonEventManagerAddressResolver.cs index 927ed87ab..415e1b169 100644 --- a/Dalamud/Game/Addon/Events/AddonEventManagerAddressResolver.cs +++ b/Dalamud/Game/Addon/Events/AddonEventManagerAddressResolver.cs @@ -16,6 +16,6 @@ internal class AddonEventManagerAddressResolver : BaseAddressResolver /// The signature scanner to facilitate setup. protected override void Setup64Bit(ISigScanner scanner) { - this.UpdateCursor = scanner.ScanText("48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 20 4C 8B F1 E8 ?? ?? ?? ?? 49 8B CE"); + this.UpdateCursor = scanner.ScanText("48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 20 4C 8B F1 E8 ?? ?? ?? ?? 49 8B CE"); // unnamed in CS } } diff --git a/Dalamud/Game/ClientState/ClientState.cs b/Dalamud/Game/ClientState/ClientState.cs index 750ba34c5..6ceea4c6b 100644 --- a/Dalamud/Game/ClientState/ClientState.cs +++ b/Dalamud/Game/ClientState/ClientState.cs @@ -37,7 +37,7 @@ internal sealed class ClientState : IInternalDisposableService, IClientState private readonly GameLifecycle lifecycle; private readonly ClientStateAddressResolver address; - private readonly Hook setupTerritoryTypeHook; + private readonly Hook setupTerritoryTypeHook; private readonly Hook uiModuleHandlePacketHook; private readonly Hook processPacketPlayerSetupHook; private readonly Hook onLogoutHook; @@ -56,9 +56,10 @@ internal sealed class ClientState : IInternalDisposableService, IClientState this.ClientLanguage = (ClientLanguage)dalamud.StartInfo.Language; - Log.Verbose($"SetupTerritoryType address {Util.DescribeAddress(this.address.SetupTerritoryType)}"); + var setTerritoryTypeAddr = EventFramework.Addresses.SetTerritoryTypeId.Value; + Log.Verbose($"SetupTerritoryType address {Util.DescribeAddress(setTerritoryTypeAddr)}"); - this.setupTerritoryTypeHook = Hook.FromAddress(this.address.SetupTerritoryType, this.SetupTerritoryTypeDetour); + this.setupTerritoryTypeHook = Hook.FromAddress(setTerritoryTypeAddr, this.SetupTerritoryTypeDetour); this.uiModuleHandlePacketHook = Hook.FromAddress((nint)UIModule.StaticVirtualTablePointer->HandlePacket, this.UIModuleHandlePacketDetour); this.processPacketPlayerSetupHook = Hook.FromAddress(this.address.ProcessPacketPlayerSetup, this.ProcessPacketPlayerSetupDetour); this.onLogoutHook = Hook.FromAddress((nint)LogoutCallbackInterface.StaticVirtualTablePointer->OnLogout, this.OnLogoutDetour); @@ -70,10 +71,7 @@ internal sealed class ClientState : IInternalDisposableService, IClientState this.processPacketPlayerSetupHook.Enable(); this.onLogoutHook.Enable(); } - - [UnmanagedFunctionPointer(CallingConvention.ThisCall)] - private unsafe delegate void SetupTerritoryTypeDelegate(EventFramework* eventFramework, ushort terriType); - + private unsafe delegate void ProcessPacketPlayerSetupDelegate(nint a1, nint packet); /// diff --git a/Dalamud/Game/ClientState/ClientStateAddressResolver.cs b/Dalamud/Game/ClientState/ClientStateAddressResolver.cs index c7d7837a4..d44275ef8 100644 --- a/Dalamud/Game/ClientState/ClientStateAddressResolver.cs +++ b/Dalamud/Game/ClientState/ClientStateAddressResolver.cs @@ -19,11 +19,6 @@ internal sealed class ClientStateAddressResolver : BaseAddressResolver // Functions - /// - /// Gets the address of the method which sets the territory type. - /// - public IntPtr SetupTerritoryType { get; private set; } - /// /// Gets the address of the method which sets up the player. /// @@ -41,9 +36,7 @@ internal sealed class ClientStateAddressResolver : BaseAddressResolver /// The signature scanner to facilitate setup. protected override void Setup64Bit(ISigScanner sig) { - this.SetupTerritoryType = sig.ScanText("48 89 5C 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC ?? 48 8B D9 48 89 6C 24"); - - this.ProcessPacketPlayerSetup = sig.ScanText("40 53 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 48 8B DA E8 ?? ?? ?? ?? 48 8B D3"); + this.ProcessPacketPlayerSetup = sig.ScanText("40 53 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 48 8B DA E8 ?? ?? ?? ?? 48 8B D3"); // not in cs struct // These resolve to fixed offsets only, without the base address added in, so GetStaticAddressFromSig() can't be used. // lea rcx, ds:1DB9F74h[rax*4] KeyboardState @@ -51,6 +44,6 @@ internal sealed class ClientStateAddressResolver : BaseAddressResolver this.KeyboardState = sig.ScanText("48 8D 0C 85 ?? ?? ?? ?? 8B 04 31 85 C2 0F 85") + 0x4; this.KeyboardStateIndexArray = sig.ScanText("0F B6 94 33 ?? ?? ?? ?? 84 D2") + 0x4; - this.GamepadPoll = sig.ScanText("40 55 53 57 41 54 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 44 0F 29 B4 24"); + this.GamepadPoll = sig.ScanText("40 55 53 57 41 54 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 44 0F 29 B4 24"); // unnamed in cs } } diff --git a/Dalamud/Game/Config/GameConfigAddressResolver.cs b/Dalamud/Game/Config/GameConfigAddressResolver.cs index c171932a9..2491c4033 100644 --- a/Dalamud/Game/Config/GameConfigAddressResolver.cs +++ b/Dalamud/Game/Config/GameConfigAddressResolver.cs @@ -13,6 +13,6 @@ internal sealed class GameConfigAddressResolver : BaseAddressResolver /// protected override void Setup64Bit(ISigScanner scanner) { - this.ConfigChangeAddress = scanner.ScanText("E8 ?? ?? ?? ?? 48 8B 3F 49 3B 3E"); + this.ConfigChangeAddress = scanner.ScanText("E8 ?? ?? ?? ?? 48 8B 3F 49 3B 3E"); // unnamed in CS } } diff --git a/Dalamud/Game/DutyState/DutyStateAddressResolver.cs b/Dalamud/Game/DutyState/DutyStateAddressResolver.cs index 01a0d39b7..1bca93efb 100644 --- a/Dalamud/Game/DutyState/DutyStateAddressResolver.cs +++ b/Dalamud/Game/DutyState/DutyStateAddressResolver.cs @@ -16,6 +16,6 @@ internal class DutyStateAddressResolver : BaseAddressResolver /// The signature scanner to facilitate setup. protected override void Setup64Bit(ISigScanner sig) { - this.ContentDirectorNetworkMessage = sig.ScanText("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 56 41 57 48 83 EC ?? 33 FF 48 8B D9 41 0F B7 08"); + this.ContentDirectorNetworkMessage = sig.ScanText("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 56 41 57 48 83 EC ?? 33 FF 48 8B D9 41 0F B7 08"); // unnamed in cs } } diff --git a/Dalamud/Game/Gui/FlyText/FlyTextGui.cs b/Dalamud/Game/Gui/FlyText/FlyTextGui.cs index b01f8c244..cbf166cfc 100644 --- a/Dalamud/Game/Gui/FlyText/FlyTextGui.cs +++ b/Dalamud/Game/Gui/FlyText/FlyTextGui.cs @@ -23,62 +23,21 @@ namespace Dalamud.Game.Gui.FlyText; internal sealed class FlyTextGui : IInternalDisposableService, IFlyTextGui { /// - /// The native function responsible for adding fly text to the UI. See . + /// The hook that fires when the game creates a fly text element. /// - private readonly AddFlyTextDelegate addFlyTextNative; - - /// - /// The hook that fires when the game creates a fly text element. See . - /// - private readonly Hook createFlyTextHook; + private readonly Hook createFlyTextHook; [ServiceManager.ServiceConstructor] private unsafe FlyTextGui(TargetSigScanner sigScanner) { - this.Address = new FlyTextGuiAddressResolver(); - this.Address.Setup(sigScanner); - - this.addFlyTextNative = Marshal.GetDelegateForFunctionPointer(this.Address.AddFlyText); - this.createFlyTextHook = Hook.FromAddress(this.Address.CreateFlyText, this.CreateFlyTextDetour); + this.createFlyTextHook = Hook.FromAddress(AddonFlyText.Addresses.CreateFlyText.Value, this.CreateFlyTextDetour); this.createFlyTextHook.Enable(); } - /// - /// Private delegate for the native CreateFlyText function's hook. - /// - private unsafe delegate nint CreateFlyTextDelegate( - AtkUnitBase* thisPtr, - FlyTextKind kind, - int val1, - int val2, - byte* text2, - uint color, - uint icon, - uint damageTypeIcon, - byte* text1, - float yOffset); - - /// - /// Private delegate for the native AddFlyText function pointer. - /// - private unsafe delegate void AddFlyTextDelegate( - AtkUnitBase* thisPtr, - uint actorIndex, - uint messageMax, - NumberArrayData* numberArrayData, - uint offsetNum, - uint offsetNumMax, - StringArrayData* stringArrayData, - uint offsetStr, - uint offsetStrMax, - int unknown); - /// public event IFlyTextGui.OnFlyTextCreatedDelegate? FlyTextCreated; - private FlyTextGuiAddressResolver Address { get; } - /// /// Disposes of managed and unmanaged resources. /// @@ -94,7 +53,7 @@ internal sealed class FlyTextGui : IInternalDisposableService, IFlyTextGui var numOffset = 161u; var strOffset = 28u; - var flytext = RaptureAtkUnitManager.Instance()->GetAddonByName("_FlyText"); + var flytext = (AddonFlyText*)RaptureAtkUnitManager.Instance()->GetAddonByName("_FlyText"); if (flytext == null) return; @@ -116,23 +75,13 @@ internal sealed class FlyTextGui : IInternalDisposableService, IFlyTextGui strArray->SetValue((int)strOffset + 0, text1.EncodeWithNullTerminator(), false, true, false); strArray->SetValue((int)strOffset + 1, text2.EncodeWithNullTerminator(), false, true, false); - - this.addFlyTextNative( - flytext, - actorIndex, - 1, - numArray, - numOffset, - 10, - strArray, - strOffset, - 2, - 0); + + flytext->AddFlyText(actorIndex, 1, numArray, numOffset, 10, strArray, strOffset, 2, 0); } private unsafe nint CreateFlyTextDetour( - AtkUnitBase* thisPtr, - FlyTextKind kind, + AddonFlyText* thisPtr, + int kind, int val1, int val2, byte* text2, @@ -149,7 +98,7 @@ internal sealed class FlyTextGui : IInternalDisposableService, IFlyTextGui var handled = false; - var tmpKind = kind; + var tmpKind = (FlyTextKind)kind; var tmpVal1 = val1; var tmpVal2 = val2; var tmpText1 = text1 == null ? string.Empty : MemoryHelper.ReadSeStringNullTerminated((nint)text1); @@ -193,7 +142,7 @@ internal sealed class FlyTextGui : IInternalDisposableService, IFlyTextGui var maybeModifiedText2 = tmpText2.EncodeWithNullTerminator(); // Check if any values have changed - var dirty = tmpKind != kind || + var dirty = (int)tmpKind != kind || tmpVal1 != val1 || tmpVal2 != val2 || !maybeModifiedText1.SequenceEqual(originalText1) || @@ -219,7 +168,7 @@ internal sealed class FlyTextGui : IInternalDisposableService, IFlyTextGui retVal = this.createFlyTextHook.Original( thisPtr, - tmpKind, + (int)tmpKind, tmpVal1, tmpVal2, (byte*)pText2, diff --git a/Dalamud/Game/Gui/FlyText/FlyTextGuiAddressResolver.cs b/Dalamud/Game/Gui/FlyText/FlyTextGuiAddressResolver.cs deleted file mode 100644 index aa7c8026f..000000000 --- a/Dalamud/Game/Gui/FlyText/FlyTextGuiAddressResolver.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace Dalamud.Game.Gui.FlyText; - -/// -/// An address resolver for the class. -/// -internal class FlyTextGuiAddressResolver : BaseAddressResolver -{ - /// - /// Gets the address of the native AddFlyText method, which occurs - /// when the game adds fly text elements to the UI. Multiple fly text - /// elements can be added in a single AddFlyText call. - /// - public IntPtr AddFlyText { get; private set; } - - /// - /// Gets the address of the native CreateFlyText method, which occurs - /// when the game creates a new fly text element. This method is called - /// once per fly text element, and can be called multiple times per - /// AddFlyText call. - /// - public IntPtr CreateFlyText { get; private set; } - - /// - protected override void Setup64Bit(ISigScanner sig) - { - this.AddFlyText = sig.ScanText("E8 ?? ?? ?? ?? FF C7 41 D1 C7"); - this.CreateFlyText = sig.ScanText("E8 ?? ?? ?? ?? 48 8B F8 48 85 C0 0F 84 ?? ?? ?? ?? 48 8B 18"); - } -} diff --git a/Dalamud/Game/Gui/GameGui.cs b/Dalamud/Game/Gui/GameGui.cs index 85ac36a66..54f4253cd 100644 --- a/Dalamud/Game/Gui/GameGui.cs +++ b/Dalamud/Game/Gui/GameGui.cs @@ -38,11 +38,11 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui private readonly GameGuiAddressResolver address; private readonly Hook setGlobalBgmHook; - private readonly Hook handleActionHoverHook; - private readonly Hook handleActionOutHook; + private readonly Hook handleActionHoverHook; + private readonly Hook handleActionOutHook; private readonly Hook handleImmHook; private readonly Hook setUiVisibilityHook; - private readonly Hook utf8StringFromSequenceHook; + private readonly Hook utf8StringFromSequenceHook; [ServiceManager.ServiceConstructor] private GameGui(TargetSigScanner sigScanner) @@ -57,14 +57,14 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui this.setGlobalBgmHook = Hook.FromAddress(this.address.SetGlobalBgm, this.HandleSetGlobalBgmDetour); - this.handleActionHoverHook = Hook.FromAddress(AgentActionDetail.Addresses.HandleActionHover.Value, this.HandleActionHoverDetour); - this.handleActionOutHook = Hook.FromAddress(this.address.HandleActionOut, this.HandleActionOutDetour); + this.handleActionHoverHook = Hook.FromAddress(AgentActionDetail.Addresses.HandleActionHover.Value, this.HandleActionHoverDetour); + this.handleActionOutHook = Hook.FromAddress((nint)AgentActionDetail.StaticVirtualTablePointer->ReceiveEvent, this.HandleActionOutDetour); this.handleImmHook = Hook.FromAddress(this.address.HandleImm, this.HandleImmDetour); this.setUiVisibilityHook = Hook.FromAddress((nint)RaptureAtkModule.StaticVirtualTablePointer->SetUiVisibility, this.SetUiVisibilityDetour); - this.utf8StringFromSequenceHook = Hook.FromAddress(this.address.Utf8StringFromSequence, this.Utf8StringFromSequenceDetour); + this.utf8StringFromSequenceHook = Hook.FromAddress(Utf8String.Addresses.Ctor_FromSequence.Value, this.Utf8StringFromSequenceDetour); this.setGlobalBgmHook.Enable(); this.handleImmHook.Enable(); @@ -77,19 +77,10 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui } // Hooked delegates - - [UnmanagedFunctionPointer(CallingConvention.ThisCall)] - private delegate Utf8String* Utf8StringFromSequenceDelegate(Utf8String* thisPtr, byte* sourcePtr, nuint sourceLen); - + [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private delegate IntPtr SetGlobalBgmDelegate(ushort bgmKey, byte a2, uint a3, uint a4, uint a5, byte a6); - [UnmanagedFunctionPointer(CallingConvention.ThisCall)] - private delegate void HandleActionHoverDelegate(IntPtr hoverState, HoverActionKind a2, uint a3, int a4, byte a5); - - [UnmanagedFunctionPointer(CallingConvention.ThisCall)] - private delegate IntPtr HandleActionOutDelegate(IntPtr agentActionDetail, IntPtr a2, IntPtr a3, int a4); - [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private delegate char HandleImmDelegate(IntPtr framework, char a2, byte a3); @@ -309,24 +300,24 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui return retVal; } - private void HandleActionHoverDetour(IntPtr hoverState, HoverActionKind actionKind, uint actionId, int a4, byte a5) + private void HandleActionHoverDetour(AgentActionDetail* hoverState, ActionKind actionKind, uint actionId, int a4, byte a5) { this.handleActionHoverHook.Original(hoverState, actionKind, actionId, a4, a5); - this.HoveredAction.ActionKind = actionKind; + this.HoveredAction.ActionKind = (HoverActionKind)actionKind; this.HoveredAction.BaseActionID = actionId; - this.HoveredAction.ActionID = (uint)Marshal.ReadInt32(hoverState, 0x3C); + this.HoveredAction.ActionID = hoverState->ActionId; this.HoveredActionChanged?.InvokeSafely(this, this.HoveredAction); - Log.Verbose($"HoverActionId: {actionKind}/{actionId} this:{hoverState.ToInt64():X}"); + Log.Verbose($"HoverActionId: {actionKind}/{actionId} this:{(nint)hoverState:X}"); } - private IntPtr HandleActionOutDetour(IntPtr agentActionDetail, IntPtr a2, IntPtr a3, int a4) + private AtkValue* HandleActionOutDetour(AgentActionDetail* agentActionDetail, AtkValue* a2, AtkValue* a3, uint a4, ulong a5) { - var retVal = this.handleActionOutHook.Original(agentActionDetail, a2, a3, a4); + var retVal = this.handleActionOutHook.Original(agentActionDetail, a2, a3, a4, a5); - if (a3 != IntPtr.Zero && a4 == 1) + if (a3 != null && a4 == 1) { - var a3Val = Marshal.ReadByte(a3, 0x8); + var a3Val = a3->Int; if (a3Val == 255) { diff --git a/Dalamud/Game/Gui/GameGuiAddressResolver.cs b/Dalamud/Game/Gui/GameGuiAddressResolver.cs index 5a404fb2a..bdd579c7e 100644 --- a/Dalamud/Game/Gui/GameGuiAddressResolver.cs +++ b/Dalamud/Game/Gui/GameGuiAddressResolver.cs @@ -15,28 +15,15 @@ internal sealed class GameGuiAddressResolver : BaseAddressResolver /// public IntPtr SetGlobalBgm { get; private set; } - /// - /// Gets the address of the native HandleActionOut method. - /// - public IntPtr HandleActionOut { get; private set; } - /// /// Gets the address of the native HandleImm method. /// public IntPtr HandleImm { get; private set; } - /// - /// Gets the address of the native Utf8StringFromSequence method. - /// - public IntPtr Utf8StringFromSequence { get; private set; } - /// protected override void Setup64Bit(ISigScanner sig) { - this.SetGlobalBgm = sig.ScanText("E8 ?? ?? ?? ?? 8B 2F"); - this.HandleActionOut = sig.ScanText("48 89 5C 24 ?? 57 48 83 EC 20 48 8B DA 48 8B F9 4D 85 C0 74 1F"); - this.HandleImm = sig.ScanText("E8 ?? ?? ?? ?? 84 C0 75 10 48 83 FF 09"); - - this.Utf8StringFromSequence = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8D 41 22 66 C7 41 ?? ?? ?? 48 89 01 49 8B D8"); + this.SetGlobalBgm = sig.ScanText("E8 ?? ?? ?? ?? 8B 2F"); // unnamed in CS + this.HandleImm = sig.ScanText("E8 ?? ?? ?? ?? 84 C0 75 10 48 83 FF 09"); // unnamed in CS } } diff --git a/Dalamud/Game/Gui/PartyFinder/PartyFinderAddressResolver.cs b/Dalamud/Game/Gui/PartyFinder/PartyFinderAddressResolver.cs deleted file mode 100644 index 0b267694c..000000000 --- a/Dalamud/Game/Gui/PartyFinder/PartyFinderAddressResolver.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Dalamud.Game.Gui.PartyFinder; - -/// -/// The address resolver for the class. -/// -internal class PartyFinderAddressResolver : BaseAddressResolver -{ - /// - /// Gets the address of the native ReceiveListing method. - /// - public IntPtr ReceiveListing { get; private set; } - - /// - protected override void Setup64Bit(ISigScanner sig) - { - this.ReceiveListing = sig.ScanText("40 53 41 57 48 83 EC ?? 48 8B D9 4C 8B FA"); - } -} diff --git a/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs b/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs index ef4055b29..0b25a87be 100644 --- a/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs +++ b/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs @@ -7,6 +7,8 @@ using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Plugin.Services; +using FFXIVClientStructs.FFXIV.Client.UI.Info; + using Serilog; namespace Dalamud.Game.Gui.PartyFinder; @@ -15,12 +17,11 @@ namespace Dalamud.Game.Gui.PartyFinder; /// This class handles interacting with the native PartyFinder window. /// [ServiceManager.EarlyLoadedService] -internal sealed class PartyFinderGui : IInternalDisposableService, IPartyFinderGui +internal sealed unsafe class PartyFinderGui : IInternalDisposableService, IPartyFinderGui { - private readonly PartyFinderAddressResolver address; private readonly nint memory; - private readonly Hook receiveListingHook; + private readonly Hook receiveListingHook; /// /// Initializes a new instance of the class. @@ -29,18 +30,12 @@ internal sealed class PartyFinderGui : IInternalDisposableService, IPartyFinderG [ServiceManager.ServiceConstructor] private PartyFinderGui(TargetSigScanner sigScanner) { - this.address = new PartyFinderAddressResolver(); - this.address.Setup(sigScanner); - this.memory = Marshal.AllocHGlobal(PartyFinderPacket.PacketSize); - this.receiveListingHook = Hook.FromAddress(this.address.ReceiveListing, this.HandleReceiveListingDetour); + this.receiveListingHook = Hook.FromAddress(InfoProxyCrossRealm.Addresses.ReceiveListing.Value, this.HandleReceiveListingDetour); this.receiveListingHook.Enable(); } - [UnmanagedFunctionPointer(CallingConvention.ThisCall)] - private delegate void ReceiveListingDelegate(nint managerPtr, nint data); - /// public event IPartyFinderGui.PartyFinderListingEventDelegate? ReceiveListing; @@ -61,18 +56,18 @@ internal sealed class PartyFinderGui : IInternalDisposableService, IPartyFinderG } } - private void HandleReceiveListingDetour(nint managerPtr, nint data) + private void HandleReceiveListingDetour(InfoProxyCrossRealm* infoProxy, nint packet) { try { - this.HandleListingEvents(data); + this.HandleListingEvents(packet); } catch (Exception ex) { Log.Error(ex, "Exception on ReceiveListing hook."); } - this.receiveListingHook.Original(managerPtr, data); + this.receiveListingHook.Original(infoProxy, packet); } private void HandleListingEvents(nint data) diff --git a/Dalamud/Game/Internal/DalamudAtkTweaks.cs b/Dalamud/Game/Internal/DalamudAtkTweaks.cs index c147f76e6..7834ab58f 100644 --- a/Dalamud/Game/Internal/DalamudAtkTweaks.cs +++ b/Dalamud/Game/Internal/DalamudAtkTweaks.cs @@ -24,7 +24,7 @@ internal sealed unsafe class DalamudAtkTweaks : IInternalDisposableService { private static readonly ModuleLog Log = new("DalamudAtkTweaks"); - private readonly Hook hookAgentHudOpenSystemMenu; + private readonly Hook hookAgentHudOpenSystemMenu; // TODO: Make this into events in Framework.Gui private readonly Hook hookUiModuleExecuteMainCommand; @@ -45,9 +45,7 @@ internal sealed unsafe class DalamudAtkTweaks : IInternalDisposableService [ServiceManager.ServiceConstructor] private DalamudAtkTweaks(TargetSigScanner sigScanner) { - var openSystemMenuAddress = sigScanner.ScanText("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 48 8B CF 4C 89 B4 24 B8 08 00 00"); - - this.hookAgentHudOpenSystemMenu = Hook.FromAddress(openSystemMenuAddress, this.AgentHudOpenSystemMenuDetour); + this.hookAgentHudOpenSystemMenu = Hook.FromAddress(AgentHUD.Addresses.OpenSystemMenu.Value, this.AgentHudOpenSystemMenuDetour); this.hookUiModuleExecuteMainCommand = Hook.FromAddress((nint)UIModule.StaticVirtualTablePointer->ExecuteMainCommand, this.UiModuleExecuteMainCommandDetour); this.hookAtkUnitBaseReceiveGlobalEvent = Hook.FromAddress((nint)AtkUnitBase.StaticVirtualTablePointer->ReceiveGlobalEvent, this.AtkUnitBaseReceiveGlobalEventDetour); diff --git a/Dalamud/Game/Network/GameNetwork.cs b/Dalamud/Game/Network/GameNetwork.cs index b51232ece..5022eb93d 100644 --- a/Dalamud/Game/Network/GameNetwork.cs +++ b/Dalamud/Game/Network/GameNetwork.cs @@ -6,6 +6,9 @@ using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Plugin.Services; using Dalamud.Utility; + +using FFXIVClientStructs.FFXIV.Client.Network; + using Serilog; namespace Dalamud.Game.Network; @@ -14,10 +17,10 @@ namespace Dalamud.Game.Network; /// This class handles interacting with game network events. /// [ServiceManager.EarlyLoadedService] -internal sealed class GameNetwork : IInternalDisposableService, IGameNetwork +internal sealed unsafe class GameNetwork : IInternalDisposableService, IGameNetwork { private readonly GameNetworkAddressResolver address; - private readonly Hook processZonePacketDownHook; + private readonly Hook processZonePacketDownHook; private readonly Hook processZonePacketUpHook; private readonly HitchDetector hitchDetectorUp; @@ -25,11 +28,9 @@ internal sealed class GameNetwork : IInternalDisposableService, IGameNetwork [ServiceManager.ServiceDependency] private readonly DalamudConfiguration configuration = Service.Get(); - - private IntPtr baseAddress; - + [ServiceManager.ServiceConstructor] - private GameNetwork(TargetSigScanner sigScanner) + private unsafe GameNetwork(TargetSigScanner sigScanner) { this.hitchDetectorUp = new HitchDetector("GameNetworkUp", this.configuration.GameNetworkUpHitch); this.hitchDetectorDown = new HitchDetector("GameNetworkDown", this.configuration.GameNetworkDownHitch); @@ -37,20 +38,19 @@ internal sealed class GameNetwork : IInternalDisposableService, IGameNetwork this.address = new GameNetworkAddressResolver(); this.address.Setup(sigScanner); + var onReceivePacketAddress = (nint)PacketDispatcher.StaticVirtualTablePointer->OnReceivePacket; + Log.Verbose("===== G A M E N E T W O R K ====="); - Log.Verbose($"ProcessZonePacketDown address {Util.DescribeAddress(this.address.ProcessZonePacketDown)}"); + Log.Verbose($"OnReceivePacket address {Util.DescribeAddress(onReceivePacketAddress)}"); Log.Verbose($"ProcessZonePacketUp address {Util.DescribeAddress(this.address.ProcessZonePacketUp)}"); - this.processZonePacketDownHook = Hook.FromAddress(this.address.ProcessZonePacketDown, this.ProcessZonePacketDownDetour); + this.processZonePacketDownHook = Hook.FromAddress(onReceivePacketAddress, this.ProcessZonePacketDownDetour); this.processZonePacketUpHook = Hook.FromAddress(this.address.ProcessZonePacketUp, this.ProcessZonePacketUpDetour); this.processZonePacketDownHook.Enable(); this.processZonePacketUpHook.Enable(); } - [UnmanagedFunctionPointer(CallingConvention.ThisCall)] - private delegate void ProcessZonePacketDownDelegate(IntPtr a, uint targetId, IntPtr dataPtr); - [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private delegate byte ProcessZonePacketUpDelegate(IntPtr a1, IntPtr dataPtr, IntPtr a3, byte a4); @@ -64,10 +64,8 @@ internal sealed class GameNetwork : IInternalDisposableService, IGameNetwork this.processZonePacketUpHook.Dispose(); } - private void ProcessZonePacketDownDetour(IntPtr a, uint targetId, IntPtr dataPtr) + private void ProcessZonePacketDownDetour(PacketDispatcher* dispatcher, uint targetId, IntPtr dataPtr) { - this.baseAddress = a; - this.hitchDetectorDown.Start(); // Go back 0x10 to get back to the start of the packet header @@ -78,7 +76,7 @@ internal sealed class GameNetwork : IInternalDisposableService, IGameNetwork // Call events this.NetworkMessage?.Invoke(dataPtr + 0x20, (ushort)Marshal.ReadInt16(dataPtr, 0x12), 0, targetId, NetworkMessageDirection.ZoneDown); - this.processZonePacketDownHook.Original(a, targetId, dataPtr + 0x10); + this.processZonePacketDownHook.Original(dispatcher, targetId, dataPtr + 0x10); } catch (Exception ex) { @@ -96,7 +94,7 @@ internal sealed class GameNetwork : IInternalDisposableService, IGameNetwork Log.Error(ex, "Exception on ProcessZonePacketDown hook. Header: " + header); - this.processZonePacketDownHook.Original(a, targetId, dataPtr + 0x10); + this.processZonePacketDownHook.Original(dispatcher, targetId, dataPtr + 0x10); } this.hitchDetectorDown.Stop(); diff --git a/Dalamud/Game/Network/GameNetworkAddressResolver.cs b/Dalamud/Game/Network/GameNetworkAddressResolver.cs index 69b97c59d..de92f7c10 100644 --- a/Dalamud/Game/Network/GameNetworkAddressResolver.cs +++ b/Dalamud/Game/Network/GameNetworkAddressResolver.cs @@ -5,11 +5,6 @@ namespace Dalamud.Game.Network; /// internal sealed class GameNetworkAddressResolver : BaseAddressResolver { - /// - /// Gets the address of the ProcessZonePacketDown method. - /// - public IntPtr ProcessZonePacketDown { get; private set; } - /// /// Gets the address of the ProcessZonePacketUp method. /// @@ -18,9 +13,6 @@ internal sealed class GameNetworkAddressResolver : BaseAddressResolver /// protected override void Setup64Bit(ISigScanner sig) { - // ProcessZonePacket = sig.ScanText("48 89 74 24 18 57 48 83 EC 50 8B F2 49 8B F8 41 0F B7 50 02 8B CE E8 ?? ?? 7A FF 0F B7 57 02 8D 42 89 3D 5F 02 00 00 0F 87 60 01 00 00 4C 8D 05"); - // ProcessZonePacket = sig.ScanText("48 89 74 24 18 57 48 83 EC 50 8B F2 49 8B F8 41 0F B7 50 02 8B CE E8 ?? ?? 73 FF 0F B7 57 02 8D 42 ?? 3D ?? ?? 00 00 0F 87 60 01 00 00 4C 8D 05"); - this.ProcessZonePacketDown = sig.ScanText("40 53 56 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 44 24 ?? 8B F2"); - this.ProcessZonePacketUp = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 4C 89 64 24 ?? 55 41 56 41 57 48 8B EC 48 83 EC 70"); + this.ProcessZonePacketUp = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 4C 89 64 24 ?? 55 41 56 41 57 48 8B EC 48 83 EC 70"); // unnamed in cs } } diff --git a/Dalamud/Game/Network/Internal/NetworkHandlers.cs b/Dalamud/Game/Network/Internal/NetworkHandlers.cs index 2017be4bf..a25444f10 100644 --- a/Dalamud/Game/Network/Internal/NetworkHandlers.cs +++ b/Dalamud/Game/Network/Internal/NetworkHandlers.cs @@ -15,6 +15,9 @@ using Dalamud.Game.Text.SeStringHandling; using Dalamud.Hooking; using Dalamud.Networking.Http; using Dalamud.Utility; + +using FFXIVClientStructs.FFXIV.Client.Game.InstanceContent; +using FFXIVClientStructs.FFXIV.Client.Network; using FFXIVClientStructs.FFXIV.Client.UI.Info; using Lumina.Excel.Sheets; using Serilog; @@ -35,13 +38,13 @@ internal unsafe class NetworkHandlers : IInternalDisposableService private readonly NetworkHandlersAddressResolver addressResolver; - private readonly Hook cfPopHook; - private readonly Hook mbPurchaseHook; - private readonly Hook mbHistoryHook; + private readonly Hook cfPopHook; + private readonly Hook mbPurchaseHook; + private readonly Hook mbHistoryHook; private readonly Hook customTalkHook; // used for marketboard taxes - private readonly Hook mbItemRequestStartHook; - private readonly Hook mbOfferingsHook; - private readonly Hook mbSendPurchaseRequestHook; + private readonly Hook mbItemRequestStartHook; + private readonly Hook mbOfferingsHook; + private readonly Hook mbSendPurchaseRequestHook; [ServiceManager.ServiceDependency] private readonly DalamudConfiguration configuration = Service.Get(); @@ -134,14 +137,14 @@ internal unsafe class NetworkHandlers : IInternalDisposableService this.handleMarketBoardPurchaseHandler = this.HandleMarketBoardPurchaseHandler(); this.mbPurchaseHook = - Hook.FromAddress( - this.addressResolver.MarketBoardPurchasePacketHandler, + Hook.FromAddress( + PacketDispatcher.Addresses.HandleMarketBoardPurchasePacket.Value, this.MarketPurchasePacketDetour); this.mbPurchaseHook.Enable(); this.mbHistoryHook = - Hook.FromAddress( - this.addressResolver.MarketBoardHistoryPacketHandler, + Hook.FromAddress( + InfoProxyItemSearch.Addresses.ProcessItemHistory.Value, this.MarketHistoryPacketDetour); this.mbHistoryHook.Enable(); @@ -151,22 +154,22 @@ internal unsafe class NetworkHandlers : IInternalDisposableService this.CustomTalkReceiveResponseDetour); this.customTalkHook.Enable(); - this.mbItemRequestStartHook = Hook.FromAddress( - this.addressResolver.MarketBoardItemRequestStartPacketHandler, + this.mbItemRequestStartHook = Hook.FromAddress( + PacketDispatcher.Addresses.HandleMarketBoardItemRequestStartPacket.Value, this.MarketItemRequestStartDetour); this.mbItemRequestStartHook.Enable(); - this.mbOfferingsHook = Hook.FromAddress( - this.addressResolver.InfoProxyItemSearchAddPage, + this.mbOfferingsHook = Hook.FromAddress( + (nint)InfoProxyItemSearch.StaticVirtualTablePointer->AddPage, this.MarketBoardOfferingsDetour); this.mbOfferingsHook.Enable(); - this.mbSendPurchaseRequestHook = Hook.FromAddress( - this.addressResolver.BuildMarketBoardPurchaseHandlerPacket, + this.mbSendPurchaseRequestHook = Hook.FromAddress( + InfoProxyItemSearch.Addresses.SendPurchaseRequestPacket.Value, this.MarketBoardSendPurchaseRequestDetour); this.mbSendPurchaseRequestHook.Enable(); - this.cfPopHook = Hook.FromAddress(this.addressResolver.CfPopPacketHandler, this.CfPopDetour); + this.cfPopHook = Hook.FromAddress(PublicContentDirector.Addresses.HandleEnterContentInfoPacket.Value, this.CfPopDetour); this.cfPopHook.Enable(); } @@ -183,8 +186,6 @@ internal unsafe class NetworkHandlers : IInternalDisposableService private delegate byte MarketBoardSendPurchaseRequestPacket(InfoProxyItemSearch* infoProxy); - private delegate nint CfPopDelegate(nint packetData); - /// /// Event which gets fired when a duty is ready. /// @@ -263,7 +264,7 @@ internal unsafe class NetworkHandlers : IInternalDisposableService this.cfPopHook.Dispose(); } - private unsafe nint CfPopDetour(nint packetData) + private unsafe nint CfPopDetour(PublicContentDirector.EnterContentInfoPacket* packetData) { var result = this.cfPopHook.OriginalDisposeSafe(packetData); @@ -529,7 +530,7 @@ internal unsafe class NetworkHandlers : IInternalDisposableService return this.configuration.IsMbCollect; } - private nint MarketPurchasePacketDetour(nint a1, nint packetData) + private void MarketPurchasePacketDetour(PacketDispatcher* a1, nint packetData) { try { @@ -540,10 +541,10 @@ internal unsafe class NetworkHandlers : IInternalDisposableService Log.Error(ex, "MarketPurchasePacketHandler threw an exception"); } - return this.mbPurchaseHook.OriginalDisposeSafe(a1, packetData); + this.mbPurchaseHook.OriginalDisposeSafe(a1, packetData); } - private nint MarketHistoryPacketDetour(nint a1, nint packetData, uint a3, char a4) + private void MarketHistoryPacketDetour(InfoProxyItemSearch* a1, nint packetData) { try { @@ -554,7 +555,7 @@ internal unsafe class NetworkHandlers : IInternalDisposableService Log.Error(ex, "MarketHistoryPacketDetour threw an exception"); } - return this.mbHistoryHook.OriginalDisposeSafe(a1, packetData, a3, a4); + this.mbHistoryHook.OriginalDisposeSafe(a1, packetData); } private void CustomTalkReceiveResponseDetour(nuint a1, ushort eventId, byte responseId, uint* args, byte argCount) @@ -573,7 +574,7 @@ internal unsafe class NetworkHandlers : IInternalDisposableService this.customTalkHook.OriginalDisposeSafe(a1, eventId, responseId, args, argCount); } - private nint MarketItemRequestStartDetour(nint a1, nint packetRef) + private void MarketItemRequestStartDetour(PacketDispatcher* a1, nint packetRef) { try { @@ -584,10 +585,10 @@ internal unsafe class NetworkHandlers : IInternalDisposableService Log.Error(ex, "MarketItemRequestStartDetour threw an exception"); } - return this.mbItemRequestStartHook.OriginalDisposeSafe(a1, packetRef); + this.mbItemRequestStartHook.OriginalDisposeSafe(a1, packetRef); } - private byte MarketBoardOfferingsDetour(nint a1, nint packetRef) + private void MarketBoardOfferingsDetour(InfoProxyItemSearch* a1, nint packetRef) { try { @@ -598,10 +599,10 @@ internal unsafe class NetworkHandlers : IInternalDisposableService Log.Error(ex, "MarketBoardOfferingsDetour threw an exception"); } - return this.mbOfferingsHook.OriginalDisposeSafe(a1, packetRef); + this.mbOfferingsHook.OriginalDisposeSafe(a1, packetRef); } - private byte MarketBoardSendPurchaseRequestDetour(InfoProxyItemSearch* infoProxyItemSearch) + private bool MarketBoardSendPurchaseRequestDetour(InfoProxyItemSearch* infoProxyItemSearch) { try { diff --git a/Dalamud/Game/Network/Internal/NetworkHandlersAddressResolver.cs b/Dalamud/Game/Network/Internal/NetworkHandlersAddressResolver.cs index 166b4d67a..18c48b67d 100644 --- a/Dalamud/Game/Network/Internal/NetworkHandlersAddressResolver.cs +++ b/Dalamud/Game/Network/Internal/NetworkHandlersAddressResolver.cs @@ -5,62 +5,17 @@ /// internal class NetworkHandlersAddressResolver : BaseAddressResolver { - /// - /// Gets or sets the pointer to the method responsible for handling CfPop packets. - /// - public nint CfPopPacketHandler { get; set; } - - /// - /// Gets or sets the pointer to the method responsible for handling market board history. In this case, we are - /// sigging the packet handler method directly. - /// - public nint MarketBoardHistoryPacketHandler { get; set; } - - /// - /// Gets or sets the pointer to the method responsible for processing the market board purchase packet. In this - /// case, we are sigging the packet handler method directly. - /// - public nint MarketBoardPurchasePacketHandler { get; set; } - /// /// Gets or sets the pointer to the method responsible for custom talk events. Necessary for marketboard tax data, /// as this isn't really exposed anywhere else. /// public nint CustomTalkEventResponsePacketHandler { get; set; } - - /// - /// Gets or sets the pointer to the method responsible for the marketboard ItemRequestStart packet. - /// - public nint MarketBoardItemRequestStartPacketHandler { get; set; } - - /// - /// Gets or sets the pointer to the InfoProxyItemSearch.AddPage method, used to load market data. - /// - public nint InfoProxyItemSearchAddPage { get; set; } - - /// - /// Gets or sets the pointer to the method inside InfoProxyItemSearch that is responsible for building and sending - /// a purchase request packet. - /// - public nint BuildMarketBoardPurchaseHandlerPacket { get; set; } /// protected override void Setup64Bit(ISigScanner scanner) { - this.CfPopPacketHandler = scanner.ScanText("40 53 57 48 83 EC 78 48 8B D9 48 8D 0D"); - - // TODO: I know this is a CC. I want things working for now. (KW) - this.MarketBoardHistoryPacketHandler = scanner.ScanText( - "40 53 48 83 EC 20 48 8B 0D ?? ?? ?? ?? 48 8B DA E8 ?? ?? ?? ?? 48 85 C0 74 2F 4C 8B 00 48 8B C8 41 FF 90 18 01 00 00 48 8B C8 BA 0B 00 00 00 E8 ?? ?? ?? ?? 48 85 C0 74 10 48 8B D3 48 8B C8 48 83 C4 20 5B E9 ?? ?? ?? ?? 48 83 C4 20 5B C3 CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC 40 53"); - this.MarketBoardPurchasePacketHandler = - scanner.ScanText("40 55 56 41 56 48 8B EC 48 83 EC ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 45 ?? 48 8B 0D ?? ?? ?? ?? 4C 8B F2"); this.CustomTalkEventResponsePacketHandler = - scanner.ScanText("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC ?? 49 8B D9 41 0F B6 F8 0F B7 F2 8B E9 E8 ?? ?? ?? ?? 48 8B C8 44 0F B6 CF 0F B6 44 24 ?? 44 0F B7 C6 88 44 24 ?? 8B D5 48 89 5C 24"); - this.MarketBoardItemRequestStartPacketHandler = - scanner.ScanText("48 89 5C 24 08 57 48 83 EC 20 48 8B 0D ?? ?? ?? ?? 48 8B FA E8 ?? ?? ?? ?? 48 8B D8 48 85 C0 74 4A"); - this.InfoProxyItemSearchAddPage = - scanner.ScanText("48 89 5C 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 0F B6 82 ?? ?? ?? ?? 48 8B FA 48 8B D9 38 41 19 74 54"); - this.BuildMarketBoardPurchaseHandlerPacket = - scanner.ScanText("40 53 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 48 8B D9 48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 4C 8B D0 48 85 C0 0F 84 ?? ?? ?? ?? 8B 8B"); + scanner.ScanText( + "48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC ?? 49 8B D9 41 0F B6 F8 0F B7 F2 8B E9 E8 ?? ?? ?? ?? 48 8B C8 44 0F B6 CF 0F B6 44 24 ?? 44 0F B7 C6 88 44 24 ?? 8B D5 48 89 5C 24"); // unnamed in CS } } diff --git a/lib/FFXIVClientStructs b/lib/FFXIVClientStructs index 78c39ef13..121f2f8d8 160000 --- a/lib/FFXIVClientStructs +++ b/lib/FFXIVClientStructs @@ -1 +1 @@ -Subproject commit 78c39ef1318525d766cdf31fd9a32e6f1c7cb453 +Subproject commit 121f2f8d82bce8632e79790a002d5e1ac17a635c