refactor: use ClientStructs more thoroughly
Obsolete old functions
This commit is contained in:
parent
35364d5bdb
commit
5e9321cc86
|
@ -113,7 +113,7 @@ namespace XivCommon.Functions {
|
|||
this.Show(sender.Encode(), message.Encode(), options);
|
||||
}
|
||||
|
||||
private void Show(byte[] sender, byte[] message, BattleTalkOptions? options) {
|
||||
private unsafe void Show(byte[] sender, byte[] message, BattleTalkOptions? options) {
|
||||
if (sender.Length == 0) {
|
||||
throw new ArgumentException("sender cannot be empty", nameof(sender));
|
||||
}
|
||||
|
@ -128,15 +128,13 @@ namespace XivCommon.Functions {
|
|||
|
||||
options ??= new BattleTalkOptions();
|
||||
|
||||
var uiModule = this.Functions.GetUiModule();
|
||||
var uiModule = (IntPtr) this.Functions.GetFramework()->GetUiModule();
|
||||
|
||||
unsafe {
|
||||
fixed (byte* senderPtr = sender.Terminate(), messagePtr = message.Terminate()) {
|
||||
if (this.HookEnabled) {
|
||||
this.AddBattleTalkDetour(uiModule, (IntPtr) senderPtr, (IntPtr) messagePtr, options.Duration, (byte) options.Style);
|
||||
} else {
|
||||
this.AddBattleTalk(uiModule, (IntPtr) senderPtr, (IntPtr) messagePtr, options.Duration, (byte) options.Style);
|
||||
}
|
||||
fixed (byte* senderPtr = sender.Terminate(), messagePtr = message.Terminate()) {
|
||||
if (this.HookEnabled) {
|
||||
this.AddBattleTalkDetour(uiModule, (IntPtr) senderPtr, (IntPtr) messagePtr, options.Duration, (byte) options.Style);
|
||||
} else {
|
||||
this.AddBattleTalk(uiModule, (IntPtr) senderPtr, (IntPtr) messagePtr, options.Duration, (byte) options.Style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,12 +32,12 @@ namespace XivCommon.Functions {
|
|||
/// </summary>
|
||||
/// <param name="message">Message to send</param>
|
||||
/// <exception cref="InvalidOperationException">If the signature for this function could not be found</exception>
|
||||
public void SendMessage(string message) {
|
||||
public unsafe void SendMessage(string message) {
|
||||
if (this.ProcessChatBox == null) {
|
||||
throw new InvalidOperationException("Could not find signature for chat sending");
|
||||
}
|
||||
|
||||
var uiModule = this.Functions.GetUiModule();
|
||||
var uiModule = (IntPtr) this.Functions.GetFramework()->GetUiModule();
|
||||
|
||||
using var payload = new ChatPayload(message);
|
||||
var mem1 = Marshal.AllocHGlobal(400);
|
||||
|
|
|
@ -8,6 +8,7 @@ using Dalamud;
|
|||
using Dalamud.Game;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Hooking;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||
using XivCommon.Functions.ContextMenu.Inventory;
|
||||
using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType;
|
||||
|
@ -281,13 +282,17 @@ namespace XivCommon.Functions.ContextMenu {
|
|||
Unknown,
|
||||
}
|
||||
|
||||
private (AgentType agentType, IntPtr agent) GetContextMenuAgent(IntPtr? agent = null) {
|
||||
private unsafe (AgentType agentType, IntPtr agent) GetContextMenuAgent(IntPtr? agent = null) {
|
||||
agent ??= this.Agent;
|
||||
|
||||
IntPtr GetAgent(AgentId id) {
|
||||
return (IntPtr) this.Functions.GetFramework()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(id);
|
||||
}
|
||||
|
||||
var agentType = AgentType.Unknown;
|
||||
if (agent == this.Functions.GetAgentByInternalId(9u)) {
|
||||
if (agent == GetAgent(AgentId.Context)) {
|
||||
agentType = AgentType.Normal;
|
||||
} else if (agent == this.Functions.GetAgentByInternalId(10u)) {
|
||||
} else if (agent == GetAgent(AgentId.InventoryContext)) {
|
||||
agentType = AgentType.Inventory;
|
||||
}
|
||||
|
||||
|
@ -300,7 +305,7 @@ namespace XivCommon.Functions.ContextMenu {
|
|||
return null;
|
||||
}
|
||||
|
||||
var stage = (AtkStage*) this.Functions.GetAtkStageSingleton();
|
||||
var stage = AtkStage.GetSingleton();
|
||||
var parentAddon = this._getAddonByInternalId((IntPtr) stage->RaptureAtkUnitManager, parentAddonId);
|
||||
return Encoding.UTF8.GetString(Util.ReadTerminated(parentAddon + 8));
|
||||
}
|
||||
|
@ -311,7 +316,7 @@ namespace XivCommon.Functions.ContextMenu {
|
|||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
var stage = (AtkStage*) this.Functions.GetAtkStageSingleton();
|
||||
var stage = AtkStage.GetSingleton();
|
||||
return this._getAddonByInternalId((IntPtr) stage->RaptureAtkUnitManager, addonId);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Game;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
|
||||
namespace XivCommon.Functions {
|
||||
|
@ -49,12 +50,12 @@ namespace XivCommon.Functions {
|
|||
/// </summary>
|
||||
/// <param name="contentFinderCondition">ID of duty to show</param>
|
||||
/// <exception cref="InvalidOperationException">if the open duty function could not be found in memory</exception>
|
||||
public void OpenDuty(uint contentFinderCondition) {
|
||||
public unsafe void OpenDuty(uint contentFinderCondition) {
|
||||
if (this._openDuty == null) {
|
||||
throw new InvalidOperationException("Could not find signature for open duty function");
|
||||
}
|
||||
|
||||
var agent = this.Functions.GetAgentByInternalId(ContentsFinderAgentId);
|
||||
var agent = (IntPtr) this.Functions.GetFramework()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.ContentsFinder);
|
||||
|
||||
this._openDuty(agent, contentFinderCondition, 0);
|
||||
}
|
||||
|
@ -71,12 +72,12 @@ namespace XivCommon.Functions {
|
|||
/// Opens the Duty Finder to the given roulette ID.
|
||||
/// </summary>
|
||||
/// <param name="roulette">ID of roulette to show</param>
|
||||
public void OpenRoulette(byte roulette) {
|
||||
public unsafe void OpenRoulette(byte roulette) {
|
||||
if (this._openRoulette == null) {
|
||||
throw new InvalidOperationException("Could not find signature for open roulette function");
|
||||
}
|
||||
|
||||
var agent = this.Functions.GetAgentByInternalId(ContentsFinderAgentId);
|
||||
var agent = (IntPtr) this.Functions.GetFramework()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.ContentsFinder);
|
||||
|
||||
this._openRoulette(agent, roulette, 0);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace XivCommon.Functions {
|
|||
/// </summary>
|
||||
/// <param name="objectId">Object ID to open window for</param>
|
||||
/// <exception cref="InvalidOperationException">If the signature for this function could not be found</exception>
|
||||
public void OpenExamineWindow(uint objectId) {
|
||||
public unsafe void OpenExamineWindow(uint objectId) {
|
||||
if (this.RequestCharacterInfo == null) {
|
||||
throw new InvalidOperationException("Could not find signature for Examine function");
|
||||
}
|
||||
|
@ -51,19 +51,17 @@ namespace XivCommon.Functions {
|
|||
// offsets and stuff come from the beginning of case 0x2c (around line 621 in IDA)
|
||||
// if 29f8 ever changes, I'd just scan for it in old binary and find what it is in the new binary at the same spot
|
||||
// 40 55 53 57 41 54 41 55 41 56 48 8D 6C 24 ??
|
||||
var agentModule = this.Functions.GetAgentModule();
|
||||
var agentModule = (IntPtr) this.Functions.GetFramework()->GetUiModule()->GetAgentModule();
|
||||
var rciData = Marshal.ReadIntPtr(agentModule + 0x1A0);
|
||||
|
||||
unsafe {
|
||||
// offsets at sig E8 ?? ?? ?? ?? 33 C0 EB 4C
|
||||
// this is called at the end of the 2c case
|
||||
var raw = (uint*) rciData;
|
||||
*(raw + 10) = objectId;
|
||||
*(raw + 11) = objectId;
|
||||
*(raw + 12) = objectId;
|
||||
*(raw + 13) = 0xE0000000;
|
||||
*(raw + 311) = 0;
|
||||
}
|
||||
// offsets at sig E8 ?? ?? ?? ?? 33 C0 EB 4C
|
||||
// this is called at the end of the 2c case
|
||||
var raw = (uint*) rciData;
|
||||
*(raw + 10) = objectId;
|
||||
*(raw + 11) = objectId;
|
||||
*(raw + 12) = objectId;
|
||||
*(raw + 13) = 0xE0000000;
|
||||
*(raw + 311) = 0;
|
||||
|
||||
this.RequestCharacterInfo(rciData);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
|
||||
namespace XivCommon.Functions.FriendList {
|
||||
/// <summary>
|
||||
|
@ -22,37 +23,39 @@ namespace XivCommon.Functions.FriendList {
|
|||
/// The list is empty if not logged in.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public IList<FriendListEntry> List {
|
||||
public unsafe IList<FriendListEntry> List {
|
||||
get {
|
||||
var friendListAgent = this.Functions.GetAgentByInternalId(FriendListAgentId);
|
||||
var friendListAgent = (IntPtr) this.Functions
|
||||
.GetFramework()
|
||||
->GetUiModule()
|
||||
->GetAgentModule()
|
||||
->GetAgentByInternalId(AgentId.FriendList);
|
||||
if (friendListAgent == IntPtr.Zero) {
|
||||
return Array.Empty<FriendListEntry>();
|
||||
}
|
||||
|
||||
unsafe {
|
||||
var info = *(IntPtr*) (friendListAgent + InfoOffset);
|
||||
if (info == IntPtr.Zero) {
|
||||
return Array.Empty<FriendListEntry>();
|
||||
}
|
||||
|
||||
var length = *(ushort*) (info + LengthOffset);
|
||||
if (length == 0) {
|
||||
return Array.Empty<FriendListEntry>();
|
||||
}
|
||||
|
||||
var list = *(IntPtr*) (info + ListOffset);
|
||||
if (list == IntPtr.Zero) {
|
||||
return Array.Empty<FriendListEntry>();
|
||||
}
|
||||
|
||||
var entries = new List<FriendListEntry>(length);
|
||||
for (var i = 0; i < length; i++) {
|
||||
var entry = *(FriendListEntry*) (list + i * FriendListEntry.Size);
|
||||
entries.Add(entry);
|
||||
}
|
||||
|
||||
return entries;
|
||||
var info = *(IntPtr*) (friendListAgent + InfoOffset);
|
||||
if (info == IntPtr.Zero) {
|
||||
return Array.Empty<FriendListEntry>();
|
||||
}
|
||||
|
||||
var length = *(ushort*) (info + LengthOffset);
|
||||
if (length == 0) {
|
||||
return Array.Empty<FriendListEntry>();
|
||||
}
|
||||
|
||||
var list = *(IntPtr*) (info + ListOffset);
|
||||
if (list == IntPtr.Zero) {
|
||||
return Array.Empty<FriendListEntry>();
|
||||
}
|
||||
|
||||
var entries = new List<FriendListEntry>(length);
|
||||
for (var i = 0; i < length; i++) {
|
||||
var entry = *(FriendListEntry*) (list + i * FriendListEntry.Size);
|
||||
entries.Add(entry);
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Game;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
|
||||
namespace XivCommon.Functions {
|
||||
|
@ -50,12 +51,12 @@ namespace XivCommon.Functions {
|
|||
/// </summary>
|
||||
/// <param name="questId">ID of quest to show</param>
|
||||
/// <exception cref="InvalidOperationException">if the open quest function could not be found in memory</exception>
|
||||
public void OpenQuest(uint questId) {
|
||||
public unsafe void OpenQuest(uint questId) {
|
||||
if (this._openQuest == null) {
|
||||
throw new InvalidOperationException("Could not find signature for open quest function");
|
||||
}
|
||||
|
||||
var agent = this.Functions.GetAgentByInternalId(JournalAgentId);
|
||||
var agent = (IntPtr) this.Functions.GetFramework()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.Journal);
|
||||
|
||||
this._openQuest(agent, (int) (questId & 0xFFFF), 1, 0, 1);
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ namespace XivCommon.Functions.NamePlates {
|
|||
return;
|
||||
}
|
||||
|
||||
var atkModule = (RaptureAtkModule*) this.Functions.GetAtkModule();
|
||||
var atkModule = this.Functions.GetFramework()->GetUiModule()->GetRaptureAtkModule();
|
||||
|
||||
var active = numbers->IntArray[0];
|
||||
|
||||
|
|
|
@ -1,40 +1,26 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Game;
|
||||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Game.Gui;
|
||||
using Dalamud.Game.Gui.PartyFinder;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||
using XivCommon.Functions;
|
||||
using XivCommon.Functions.ContextMenu;
|
||||
using XivCommon.Functions.FriendList;
|
||||
using XivCommon.Functions.NamePlates;
|
||||
using XivCommon.Functions.Tooltips;
|
||||
using Framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework;
|
||||
|
||||
namespace XivCommon {
|
||||
/// <summary>
|
||||
/// A class containing game functions
|
||||
/// </summary>
|
||||
public class GameFunctions : IDisposable {
|
||||
private static class Signatures {
|
||||
internal const string GetAgentByInternalId = "E8 ?? ?? ?? ?? 83 FF 0D";
|
||||
internal const string GetAtkStageSingleton = "E8 ?? ?? ?? ?? 41 B8 01 00 00 00 48 8D 15 ?? ?? ?? ?? 48 8B 48 20 E8 ?? ?? ?? ?? 48 8B CF";
|
||||
}
|
||||
|
||||
private delegate IntPtr GetAtkStageSingletonDelegate();
|
||||
|
||||
private delegate IntPtr GetAgentModuleDelegate(IntPtr basePtr);
|
||||
|
||||
private delegate IntPtr GetAtkModuleDelegate(IntPtr uiModule);
|
||||
|
||||
private delegate IntPtr GetAgentByInternalIdDelegate(IntPtr agentModule, uint id);
|
||||
|
||||
private GameGui GameGui { get; }
|
||||
|
||||
private GetAgentByInternalIdDelegate? GetAgentByInternalIdInternal { get; }
|
||||
|
||||
private GetAtkStageSingletonDelegate? GetAtkStageSingletonInternal { get; }
|
||||
private Dalamud.Game.Framework Framework { get; }
|
||||
|
||||
internal UiAlloc UiAlloc { get; }
|
||||
|
||||
|
@ -99,6 +85,7 @@ namespace XivCommon {
|
|||
public Journal Journal { get; }
|
||||
|
||||
internal GameFunctions(Hooks hooks) {
|
||||
this.Framework = Util.GetService<Dalamud.Game.Framework>();
|
||||
this.GameGui = Util.GetService<GameGui>();
|
||||
|
||||
var clientState = Util.GetService<ClientState>();
|
||||
|
@ -119,14 +106,6 @@ namespace XivCommon {
|
|||
this.DutyFinder = new DutyFinder(this, scanner);
|
||||
this.Journal = new Journal(this, scanner);
|
||||
this.FriendList = new FriendList(this);
|
||||
|
||||
if (scanner.TryScanText(Signatures.GetAgentByInternalId, out var byInternalIdPtr, "GetAgentByInternalId")) {
|
||||
this.GetAgentByInternalIdInternal = Marshal.GetDelegateForFunctionPointer<GetAgentByInternalIdDelegate>(byInternalIdPtr);
|
||||
}
|
||||
|
||||
if (scanner.TryScanText(Signatures.GetAtkStageSingleton, out var getSingletonPtr, "GetAtkStageSingleton")) {
|
||||
this.GetAtkStageSingletonInternal = Marshal.GetDelegateForFunctionPointer<GetAtkStageSingletonDelegate>(getSingletonPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -140,53 +119,39 @@ namespace XivCommon {
|
|||
this.PartyFinder.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convenience method to get a pointer to <see cref="Framework"/>.
|
||||
/// </summary>
|
||||
/// <returns>pointer to struct</returns>
|
||||
public unsafe Framework* GetFramework() {
|
||||
return (Framework*) this.Framework.Address.BaseAddress;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pointer to the UI module
|
||||
/// </summary>
|
||||
/// <returns>Pointer</returns>
|
||||
public IntPtr GetUiModule() {
|
||||
return this.GameGui.GetUIModule();
|
||||
[Obsolete("Use GetFramework()->GetUiModule()")]
|
||||
public unsafe IntPtr GetUiModule() {
|
||||
return (IntPtr) this.GetFramework()->GetUiModule();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pointer to the RaptureAtkModule
|
||||
/// </summary>
|
||||
/// <returns>Pointer</returns>
|
||||
public IntPtr GetAtkModule() {
|
||||
var uiModule = this.GetUiModule();
|
||||
if (uiModule == IntPtr.Zero) {
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
var getAtkModulePtr = FollowPtrChain(uiModule, new[] { 0, 0x38 });
|
||||
if (getAtkModulePtr == IntPtr.Zero) {
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
var getAtkModule = Marshal.GetDelegateForFunctionPointer<GetAtkModuleDelegate>(getAtkModulePtr);
|
||||
return getAtkModule(uiModule);
|
||||
[Obsolete("Use GetFramework()->GetUiModule()->GetRaptureAtkModule()")]
|
||||
public unsafe IntPtr GetAtkModule() {
|
||||
return (IntPtr) this.GetFramework()->GetUiModule()->GetRaptureAtkModule();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pointer to the agent module
|
||||
/// </summary>
|
||||
/// <returns>Pointer</returns>
|
||||
public IntPtr GetAgentModule() {
|
||||
var uiModule = this.GetUiModule();
|
||||
var getAgentModulePtr = FollowPtrChain(uiModule, new[] { 0, 0x110 });
|
||||
var getAgentModule = Marshal.GetDelegateForFunctionPointer<GetAgentModuleDelegate>(getAgentModulePtr);
|
||||
return getAgentModule(uiModule);
|
||||
}
|
||||
|
||||
private static IntPtr FollowPtrChain(IntPtr start, IEnumerable<int> offsets) {
|
||||
foreach (var offset in offsets) {
|
||||
start = Marshal.ReadIntPtr(start, offset);
|
||||
if (start == IntPtr.Zero) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return start;
|
||||
[Obsolete("Use GetFramework()->GetUiModule()->GetAgentModule()")]
|
||||
public unsafe IntPtr GetAgentModule() {
|
||||
return (IntPtr) this.GetFramework()->GetUiModule()->GetAgentModule();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -195,13 +160,9 @@ namespace XivCommon {
|
|||
/// <param name="id">internal id of agent</param>
|
||||
/// <returns>Pointer</returns>
|
||||
/// <exception cref="InvalidOperationException">if the signature for the function could not be found</exception>
|
||||
public IntPtr GetAgentByInternalId(uint id) {
|
||||
if (this.GetAgentByInternalIdInternal == null) {
|
||||
throw new InvalidOperationException("Could not find signature for GetAgentByInternalId");
|
||||
}
|
||||
|
||||
var agent = this.GetAgentModule();
|
||||
return this.GetAgentByInternalIdInternal(agent, id);
|
||||
[Obsolete("Use GetFramework()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId)")]
|
||||
public unsafe IntPtr GetAgentByInternalId(uint id) {
|
||||
return (IntPtr) this.GetFramework()->GetUiModule()->GetAgentModule()->GetAgentByInternalId((AgentId) id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -209,12 +170,9 @@ namespace XivCommon {
|
|||
/// </summary>
|
||||
/// <returns>Pointer</returns>
|
||||
/// <exception cref="InvalidOperationException">if the signature for the function could not be found</exception>
|
||||
public IntPtr GetAtkStageSingleton() {
|
||||
if (this.GetAtkStageSingletonInternal == null) {
|
||||
throw new InvalidOperationException("Could not find signature for GetAtkStageSingleton");
|
||||
}
|
||||
|
||||
return this.GetAtkStageSingletonInternal();
|
||||
[Obsolete("Use AtkStage.GetSingleton()")]
|
||||
public unsafe IntPtr GetAtkStageSingleton() {
|
||||
return (IntPtr) AtkStage.GetSingleton();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue