From 08c969208c0978a90bd5fc6acf993740b8b11612 Mon Sep 17 00:00:00 2001 From: Anna Date: Sun, 11 Jul 2021 21:41:48 -0400 Subject: [PATCH] feat(df): add Duty Finder functions --- XivCommon/Functions/DutyFinder.cs | 82 +++++++++++++++++++++++++++++++ XivCommon/GameFunctions.cs | 6 +++ XivCommon/XivCommon.csproj | 10 +++- 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100755 XivCommon/Functions/DutyFinder.cs diff --git a/XivCommon/Functions/DutyFinder.cs b/XivCommon/Functions/DutyFinder.cs new file mode 100755 index 0000000..2d51285 --- /dev/null +++ b/XivCommon/Functions/DutyFinder.cs @@ -0,0 +1,82 @@ +using System; +using System.Runtime.InteropServices; +using Dalamud.Game; +using Lumina.Excel.GeneratedSheets; + +namespace XivCommon.Functions { + /// + /// Duty Finder functions + /// + public class DutyFinder { + private static class Signatures { + internal const string OpenRegularDuty = "48 89 6C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B F9 41 0F B6 E8"; + internal const string OpenRoulette = "E9 ?? ?? ?? ?? 8B 93 ?? ?? ?? ?? 48 83 C4 20"; + } + + private const uint ContentsFinderAgentId = 50; + + private delegate IntPtr OpenDutyDelegate(IntPtr agent, uint contentFinderCondition, byte a3); + + private delegate IntPtr OpenRouletteDelegate(IntPtr agent, byte roulette, byte a3); + + private GameFunctions Functions { get; } + private readonly OpenDutyDelegate? _openDuty; + private readonly OpenRouletteDelegate? _openRoulette; + + internal DutyFinder(GameFunctions functions, SigScanner scanner) { + this.Functions = functions; + + if (scanner.TryScanText(Signatures.OpenRegularDuty, out var openDutyPtr, "Duty Finder (open duty)")) { + this._openDuty = Marshal.GetDelegateForFunctionPointer(openDutyPtr); + } + + if (scanner.TryScanText(Signatures.OpenRoulette, out var openRoulettePtr, "Duty Finder (open roulette)")) { + this._openRoulette = Marshal.GetDelegateForFunctionPointer(openRoulettePtr); + } + } + + /// + /// Opens the Duty Finder to the given duty. + /// + /// duty to show + public void OpenDuty(ContentFinderCondition condition) { + this.OpenDuty(condition.RowId); + } + + /// + /// Opens the Duty Finder to the given duty ID. + /// + /// ID of duty to show + public 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); + + this._openDuty(agent, contentFinderCondition, 0); + } + + /// + /// Opens the Duty Finder to the given roulette. + /// + /// roulette to show + public void OpenRoulette(ContentRoulette roulette) { + this.OpenRoulette((byte) roulette.RowId); + } + + /// + /// Opens the Duty Finder to the given roulette ID. + /// + /// ID of roulette to show + public 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); + + this._openRoulette(agent, roulette, 0); + } + } +} diff --git a/XivCommon/GameFunctions.cs b/XivCommon/GameFunctions.cs index 863e266..6c065eb 100755 --- a/XivCommon/GameFunctions.cs +++ b/XivCommon/GameFunctions.cs @@ -79,6 +79,11 @@ namespace XivCommon { /// public NamePlates NamePlates { get; } + /// + /// Duty Finder functions + /// + public DutyFinder DutyFinder { get; } + internal GameFunctions(Hooks hooks, DalamudPluginInterface @interface) { this.Interface = @interface; @@ -98,6 +103,7 @@ namespace XivCommon { this.ContextMenu = new ContextMenu(this, scanner, seStringManager, @interface.ClientState.ClientLanguage, hooks); this.Tooltips = new Tooltips(scanner, @interface.Framework, @interface.Framework.Gui, seStringManager, hooks.HasFlag(Hooks.Tooltips)); this.NamePlates = new NamePlates(this, scanner, seStringManager, hooks.HasFlag(Hooks.NamePlates)); + this.DutyFinder = new DutyFinder(this, scanner); if (scanner.TryScanText(Signatures.GetAgentByInternalId, out var byInternalIdPtr, "GetAgentByInternalId")) { this.GetAgentByInternalIdInternal = Marshal.GetDelegateForFunctionPointer(byInternalIdPtr); diff --git a/XivCommon/XivCommon.csproj b/XivCommon/XivCommon.csproj index 4aa7b4d..b1251e2 100755 --- a/XivCommon/XivCommon.csproj +++ b/XivCommon/XivCommon.csproj @@ -5,7 +5,7 @@ latest true enable - 2.1.1 + 2.2.0-alpha.1 full @@ -28,6 +28,14 @@ $(AppData)\XIVLauncher\addon\Hooks\dev\FFXIVClientStructs.dll False + + $(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.dll + False + + + $(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.Excel.dll + False +