Merge pull request #80 from pmgr/master

Feature: Added OpenMapWithMapLink; changed visibility of GetVirtualFunction
This commit is contained in:
goaaats 2020-04-20 10:09:55 +02:00 committed by GitHub
commit ad7fe8b3ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 3 deletions

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Runtime.InteropServices;
namespace Dalamud.Game.Internal {
@ -35,7 +35,7 @@ namespace Dalamud.Game.Internal {
// Do nothing
}
protected T GetVirtualFunction<T>(IntPtr address, int vtableOffset, int count) where T : class {
public T GetVirtualFunction<T>(IntPtr address, int vtableOffset, int count) where T : class {
// Get vtable
var vtable = Marshal.ReadIntPtr(address, vtableOffset);

View file

@ -1,6 +1,6 @@
using System;
using System.Runtime.InteropServices;
using Dalamud.Game.Chat;
using Dalamud.Game.Chat.SeStringHandling.Payloads;
using Dalamud.Hooking;
using Serilog;
@ -22,6 +22,18 @@ namespace Dalamud.Game.Internal.Gui {
private delegate IntPtr HandleItemOutDelegate(IntPtr hoverState, IntPtr a2, IntPtr a3, ulong a4);
private readonly Hook<HandleItemOutDelegate> handleItemOutHook;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate IntPtr GetUIObjectDelegate();
private readonly GetUIObjectDelegate getUIObject;
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate IntPtr GetUIMapObjectDelegate(IntPtr UIObject);
private GetUIMapObjectDelegate getUIMapObject;
[UnmanagedFunctionPointer(CallingConvention.ThisCall, CharSet = CharSet.Ansi)]
private delegate bool OpenMapWithFlagDelegate(IntPtr UIMapObject, string flag);
private OpenMapWithFlagDelegate openMapWithFlag;
/// <summary>
/// The item ID that is currently hovered by the player. 0 when no item is hovered.
/// If > 1.000.000, subtract 1.000.000 and treat it as HQ
@ -43,6 +55,7 @@ namespace Dalamud.Game.Internal.Gui {
Log.Verbose("SetGlobalBgm address {Address}", Address.SetGlobalBgm);
Log.Verbose("HandleItemHover address {Address}", Address.HandleItemHover);
Log.Verbose("HandleItemOut address {Address}", Address.HandleItemOut);
Log.Verbose("GetUIObject address {Address}", Address.GetUIObject);
Chat = new ChatGui(Address.ChatManager, scanner, dalamud);
@ -59,6 +72,8 @@ namespace Dalamud.Game.Internal.Gui {
new Hook<HandleItemOutDelegate>(Address.HandleItemOut,
new HandleItemOutDelegate(HandleItemOutDetour),
this);
this.getUIObject = Marshal.GetDelegateForFunctionPointer<GetUIObjectDelegate>(Address.GetUIObject);
}
private IntPtr HandleSetGlobalBgmDetour(UInt16 bgmKey, byte a2, UInt32 a3, UInt32 a4, UInt32 a5, byte a6) {
@ -111,6 +126,39 @@ namespace Dalamud.Game.Internal.Gui {
return retVal;
}
public bool OpenMapWithMapLink(MapLinkPayload mapLink)
{
var uiObjectPtr = getUIObject();
if (uiObjectPtr.Equals(IntPtr.Zero))
{
Log.Error("OpenMapWithMapLink: Null pointer returned from getUIObject()");
return false;
}
getUIMapObject =
Address.GetVirtualFunction<GetUIMapObjectDelegate>(uiObjectPtr, 0, 8);
var uiMapObjectPtr = this.getUIMapObject(uiObjectPtr);
if (uiMapObjectPtr.Equals(IntPtr.Zero))
{
Log.Error("OpenMapWithMapLink: Null pointer returned from GetUIMapObject()");
return false;
}
openMapWithFlag =
Address.GetVirtualFunction<OpenMapWithFlagDelegate>(uiMapObjectPtr, 0, 63);
var mapLinkString =
$"m:{mapLink.TerritoryTypeId},{mapLink.MapId},{unchecked((int)mapLink.RawX)},{unchecked((int)mapLink.RawY)}";
Log.Debug($"OpenMapWithMapLink: Opening Map Link: {mapLinkString}");
return this.openMapWithFlag(uiMapObjectPtr, mapLinkString);
}
public void SetBgm(ushort bgmKey) => this.setGlobalBgmHook.Original(bgmKey, 0, 0, 0, 0, 0);
public void Enable() {

View file

@ -11,6 +11,7 @@ namespace Dalamud.Game.Internal.Gui {
public IntPtr SetGlobalBgm { get; private set; }
public IntPtr HandleItemHover { get; set; }
public IntPtr HandleItemOut { get; set; }
public IntPtr GetUIObject { get; private set; }
public GameGuiAddressResolver(IntPtr baseAddress) {
BaseAddress = baseAddress;
@ -29,6 +30,7 @@ namespace Dalamud.Game.Internal.Gui {
SetGlobalBgm = sig.ScanText("4C 8B 15 ?? ?? ?? ?? 4D 85 D2 74 58");
HandleItemHover = sig.ScanText("E8 ?? ?? ?? ?? 48 8B 5C 24 ?? 48 89 AE ?? ?? ?? ??");
HandleItemOut = sig.ScanText("48 89 5C 24 ?? 57 48 83 EC 20 48 8B FA 48 8B D9 4D");
GetUIObject = sig.ScanText("E8 ?? ?? ?? ?? 48 8B C8 48 8B 10 FF 52 40 80 88 ?? ?? ?? ?? 01 E9");
}
}
}