PeepingTom/Peeping Tom/GameFunctions.cs

65 lines
2.3 KiB
C#
Raw Normal View History

using Dalamud.Game.ClientState.Actors.Types;
using Dalamud.Plugin;
using System;
2020-12-08 08:27:18 +00:00
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace PeepingTom {
public class GameFunctions {
private delegate IntPtr GetListDelegate(IntPtr basePtr);
private delegate long RequestCharInfoDelegate(IntPtr ptr);
2020-12-29 16:08:21 +00:00
private PeepingTomPlugin Plugin { get; }
2020-12-29 16:08:21 +00:00
private readonly RequestCharInfoDelegate? _requestCharInfo;
public GameFunctions(PeepingTomPlugin plugin) {
2020-12-29 16:08:21 +00:00
this.Plugin = plugin ?? throw new ArgumentNullException(nameof(plugin), "PeepingTomPlugin cannot be null");
2020-12-08 08:27:18 +00:00
IntPtr rciPtr;
try {
2020-12-29 16:08:21 +00:00
rciPtr = this.Plugin.Interface.TargetModuleScanner.ScanText("E8 ?? ?? ?? ?? 83 7B 30 00 74 47");
2020-12-08 08:27:18 +00:00
} catch (KeyNotFoundException) {
rciPtr = IntPtr.Zero;
}
if (rciPtr == IntPtr.Zero) {
PluginLog.Log("Could not find the signature for the examine window function - will not be able to open examine window.");
return;
}
this._requestCharInfo = Marshal.GetDelegateForFunctionPointer<RequestCharInfoDelegate>(rciPtr);
}
2020-12-29 16:08:21 +00:00
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;
}
public void OpenExamineWindow(Actor actor) {
if (this._requestCharInfo == null) {
return;
}
2020-12-29 16:08:21 +00:00
var framework = this.Plugin.Interface.Framework.Address.BaseAddress;
2020-12-29 16:08:21 +00:00
var getListPtr = FollowPtrChain(framework, new[] { 0x29f8, 0, 0x110 });
var getList = Marshal.GetDelegateForFunctionPointer<GetListDelegate>(getListPtr);
2020-12-29 16:08:21 +00:00
var list = getList(Marshal.ReadIntPtr(framework + 0x29f8));
var rciData = Marshal.ReadIntPtr(list + 0x188);
Marshal.WriteInt32(rciData + 0x28, actor.ActorId);
Marshal.WriteInt32(rciData + 0x2c, actor.ActorId);
Marshal.WriteInt32(rciData + 0x30, actor.ActorId);
this._requestCharInfo(rciData);
}
}
}