78 lines
2.9 KiB
C#
Executable File
78 lines
2.9 KiB
C#
Executable File
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.InteropServices;
|
|
using Dalamud.Game;
|
|
using Dalamud.Game.ClientState.Actors.Types;
|
|
|
|
namespace XivCommon.Functions {
|
|
/// <summary>
|
|
/// Class containing examine functions
|
|
/// </summary>
|
|
public class Examine {
|
|
private GameFunctions Functions { get; }
|
|
|
|
private delegate IntPtr GetAgentModuleDelegate(IntPtr basePtr);
|
|
|
|
private delegate long RequestCharInfoDelegate(IntPtr ptr);
|
|
|
|
private RequestCharInfoDelegate RequestCharacterInfo { get; }
|
|
|
|
internal Examine(GameFunctions functions, SigScanner scanner) {
|
|
this.Functions = functions;
|
|
|
|
// got this by checking what accesses rciData below
|
|
var rciPtr = scanner.ScanText("48 89 5C 24 ?? 57 48 83 EC 40 BA ?? ?? ?? ?? 48 8B D9 E8 ?? ?? ?? ?? 48 8B F8 48 85 C0 74 16");
|
|
this.RequestCharacterInfo = Marshal.GetDelegateForFunctionPointer<RequestCharInfoDelegate>(rciPtr);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Opens the Examine window for the specified actor.
|
|
/// </summary>
|
|
/// <param name="actor">Actor to open window for</param>
|
|
public void OpenExamineWindow(Actor actor) {
|
|
this.OpenExamineWindow(actor.ActorId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Opens the Examine window for the actor with the specified ID.
|
|
/// </summary>
|
|
/// <param name="actorId">Actor ID to open window for</param>
|
|
public void OpenExamineWindow(int actorId) {
|
|
// NOTES LAST UPDATED: 5.45
|
|
|
|
// 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 uiModule = this.Functions.GetUiModule();
|
|
var getAgentModulePtr = FollowPtrChain(uiModule, new[] {0, 0x110});
|
|
var getAgentModule = Marshal.GetDelegateForFunctionPointer<GetAgentModuleDelegate>(getAgentModulePtr);
|
|
var agentModule = getAgentModule(uiModule);
|
|
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 = (int*) rciData;
|
|
*(raw + 10) = actorId;
|
|
*(raw + 11) = actorId;
|
|
*(raw + 12) = actorId;
|
|
*(raw + 13) = -536870912;
|
|
*(raw + 311) = 0;
|
|
}
|
|
|
|
this.RequestCharacterInfo(rciData);
|
|
}
|
|
}
|
|
}
|