feat: add journal functions

This commit is contained in:
Anna 2021-07-21 15:40:59 -04:00
parent f92856e1fa
commit 03face6f31
3 changed files with 95 additions and 0 deletions

View File

@ -39,6 +39,7 @@ namespace XivCommon.Functions {
/// Opens the Duty Finder to the given duty.
/// </summary>
/// <param name="condition">duty to show</param>
/// <exception cref="InvalidOperationException">if the open duty function could not be found in memory</exception>
public void OpenDuty(ContentFinderCondition condition) {
this.OpenDuty(condition.RowId);
}
@ -47,6 +48,7 @@ namespace XivCommon.Functions {
/// Opens the Duty Finder to the given duty ID.
/// </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) {
if (this._openDuty == null) {
throw new InvalidOperationException("Could not find signature for open duty function");

87
XivCommon/Functions/Journal.cs Executable file
View File

@ -0,0 +1,87 @@
using System;
using System.Runtime.InteropServices;
using Dalamud.Game;
using Lumina.Excel.GeneratedSheets;
namespace XivCommon.Functions {
/// <summary>
/// Journal functions
/// </summary>
public class Journal {
private static class Signatures {
internal const string OpenQuest = "E8 ?? ?? ?? ?? 48 8B 74 24 ?? 48 8B 7C 24 ?? 48 83 C4 30 5B C3 48 8B CB";
internal const string IsQuestCompleted = "E8 ?? ?? ?? ?? 41 88 84 2C ?? ?? ?? ??";
}
private const int JournalAgentId = 31;
private delegate IntPtr OpenQuestDelegate(IntPtr agent, int questId, int a3, ushort a4, byte a5);
private delegate byte IsQuestCompletedDelegate(ushort questId);
private GameFunctions Functions { get; }
private readonly OpenQuestDelegate? _openQuest;
private readonly IsQuestCompletedDelegate? _isQuestCompleted;
internal Journal(GameFunctions functions, SigScanner scanner) {
this.Functions = functions;
if (scanner.TryScanText(Signatures.OpenQuest, out var openQuestPtr, "Journal (open quest)")) {
this._openQuest = Marshal.GetDelegateForFunctionPointer<OpenQuestDelegate>(openQuestPtr);
}
if (scanner.TryScanText(Signatures.IsQuestCompleted, out var questCompletedPtr, "Journal (quest completed)")) {
this._isQuestCompleted = Marshal.GetDelegateForFunctionPointer<IsQuestCompletedDelegate>(questCompletedPtr);
}
}
/// <summary>
/// Opens the quest journal to the given quest.
/// </summary>
/// <param name="quest">quest to show</param>
/// <exception cref="InvalidOperationException">if the open quest function could not be found in memory</exception>
public void OpenQuest(Quest quest) {
this.OpenQuest(quest.RowId);
}
/// <summary>
/// Opens the quest journal to the given quest ID.
/// </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) {
if (this._openQuest == null) {
throw new InvalidOperationException("Could not find signature for open quest function");
}
var agent = this.Functions.GetAgentByInternalId(JournalAgentId);
this._openQuest(agent, (int) (questId & 0xFFFF), 1, 0, 1);
}
/// <summary>
/// Checks if the given quest is completed.
/// </summary>
/// <param name="quest">quest to check</param>
/// <returns>true if the quest is completed</returns>
/// <exception cref="InvalidOperationException">if the function for checking quest completion could not be found in memory</exception>
public bool IsQuestCompleted(Quest quest) {
return this.IsQuestCompleted(quest.RowId);
}
/// <summary>
/// Checks if the given quest ID is completed.
/// </summary>
/// <param name="questId">ID of quest to check</param>
/// <returns>true if the quest is completed</returns>
/// <exception cref="InvalidOperationException">if the function for checking quest completion could not be found in memory</exception>
public bool IsQuestCompleted(uint questId) {
if (this._isQuestCompleted == null) {
throw new InvalidOperationException("Could not find signature for quest completed function");
}
return this._isQuestCompleted((ushort) (questId & 0xFFFF)) != 0;
}
}
}

View File

@ -84,6 +84,11 @@ namespace XivCommon {
/// </summary>
public DutyFinder DutyFinder { get; }
/// <summary>
/// Journal functions
/// </summary>
public Journal Journal { get; }
internal GameFunctions(Hooks hooks, DalamudPluginInterface @interface) {
this.Interface = @interface;
@ -104,6 +109,7 @@ namespace XivCommon {
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);
this.Journal = new Journal(this, scanner);
if (scanner.TryScanText(Signatures.GetAgentByInternalId, out var byInternalIdPtr, "GetAgentByInternalId")) {
this.GetAgentByInternalIdInternal = Marshal.GetDelegateForFunctionPointer<GetAgentByInternalIdDelegate>(byInternalIdPtr);