Merge pull request #173 from Caraxi/get-ui

Add "GetUiObjectByName"
This commit is contained in:
goaaats 2020-09-20 13:52:03 +02:00 committed by GitHub
commit 84d25da9af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 85 additions and 0 deletions

View file

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
namespace Dalamud.Game.Internal.Gui.Addon {
public class Addon {
public IntPtr Address;
protected Structs.Addon addonStruct;
public Addon(IntPtr address, Structs.Addon addonStruct) {
this.Address = address;
this.addonStruct = addonStruct;
}
public string Name => this.addonStruct.Name;
public short X => this.addonStruct.X;
public short Y => this.addonStruct.Y;
public float Scale => this.addonStruct.Scale;
public bool Visible => (this.addonStruct.Flags & 0x20) == 1;
}
}

View file

@ -48,6 +48,14 @@ namespace Dalamud.Game.Internal.Gui {
private delegate IntPtr ToggleUiHideDelegate(IntPtr thisPtr, byte unknownByte);
private readonly Hook<ToggleUiHideDelegate> toggleUiHideHook;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate IntPtr GetBaseUIObjectDelegate();
private readonly GetBaseUIObjectDelegate getBaseUIObject;
[UnmanagedFunctionPointer(CallingConvention.ThisCall, CharSet = CharSet.Ansi)]
private delegate IntPtr GetUIObjectByNameDelegate(IntPtr thisPtr, string uiName, int index);
private readonly GetUIObjectByNameDelegate getUIObjectByName;
public bool GameUiHidden { get; private set; }
/// <summary>
@ -103,6 +111,9 @@ namespace Dalamud.Game.Internal.Gui {
Marshal.GetDelegateForFunctionPointer<ScreenToWorldNativeDelegate>(Address.ScreenToWorld);
this.toggleUiHideHook = new Hook<ToggleUiHideDelegate>(Address.ToggleUiHide, new ToggleUiHideDelegate(ToggleUiHideDetour), this);
this.getBaseUIObject = Marshal.GetDelegateForFunctionPointer<GetBaseUIObjectDelegate>(Address.GetBaseUIObject);
this.getUIObjectByName = Marshal.GetDelegateForFunctionPointer<GetUIObjectByNameDelegate>(Address.GetUIObjectByName);
}
private IntPtr HandleSetGlobalBgmDetour(UInt16 bgmKey, byte a2, UInt32 a3, UInt32 a4, UInt32 a5, byte a6) {
@ -306,6 +317,27 @@ namespace Dalamud.Game.Internal.Gui {
return this.toggleUiHideHook.Original(thisPtr, unknownByte);
}
/// <summary>
/// Gets the pointer to the UI Object with the given name and index.
/// </summary>
/// <param name="name">Name of UI to find</param>
/// <param name="index">Index of UI to find (1-indexed)</param>
/// <returns>IntPtr.Zero if unable to find UI, otherwise IntPtr pointing to the start of the UI Object</returns>
public IntPtr GetUiObjectByName(string name, int index) {
var baseUi = this.getBaseUIObject();
if (baseUi == IntPtr.Zero) return IntPtr.Zero;
var baseUiProperties = Marshal.ReadIntPtr(baseUi, 0x20);
if (baseUiProperties == IntPtr.Zero) return IntPtr.Zero;
return this.getUIObjectByName(baseUiProperties, name, index);
}
public Addon.Addon GetAddonByName(string name, int index) {
var addonMem = GetUiObjectByName(name, index);
if (addonMem == IntPtr.Zero) return null;
var addonStruct = Marshal.PtrToStructure<Structs.Addon>(addonMem);
return new Addon.Addon(addonMem, addonStruct);
}
public void SetBgm(ushort bgmKey) => this.setGlobalBgmHook.Original(bgmKey, 0, 0, 0, 0, 0);
public void Enable() {

View file

@ -15,6 +15,8 @@ namespace Dalamud.Game.Internal.Gui {
public IntPtr GetMatrixSingleton { get; private set; }
public IntPtr ScreenToWorld { get; private set; }
public IntPtr ToggleUiHide { get; set; }
public IntPtr GetBaseUIObject { get; private set; }
public IntPtr GetUIObjectByName { get; private set; }
public GameGuiAddressResolver(IntPtr baseAddress) {
BaseAddress = baseAddress;
@ -37,6 +39,8 @@ namespace Dalamud.Game.Internal.Gui {
GetMatrixSingleton = sig.ScanText("E8 ?? ?? ?? ?? 48 8D 4C 24 ?? 48 89 4c 24 ?? 4C 8D 4D ?? 4C 8D 44 24 ??");
ScreenToWorld = sig.ScanText("48 83 EC 48 48 8B 05 ?? ?? ?? ?? 4D 8B D1");
ToggleUiHide = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 0F B6 B9 ?? ?? ?? ?? B8 ?? ?? ?? ??");
GetBaseUIObject = sig.ScanText("E8 ?? ?? ?? ?? 41 B8 01 00 00 00 48 8D 15 ?? ?? ?? ?? 48 8B 48 20 E8 ?? ?? ?? ?? 48 8B CF");
GetUIObjectByName = sig.ScanText("E8 ?? ?? ?? ?? 48 8B CF 48 89 87 ?? ?? 00 00 E8 ?? ?? ?? ?? 41 B8 01 00 00 00");
}
}
}

View file

@ -0,0 +1,24 @@
using System.Runtime.InteropServices;
namespace Dalamud.Game.Internal.Gui.Structs {
public class AddonOffsets {
public const int Name = 0x8;
public const int Flags = 0x182;
public const int X = 0x1BC;
public const int Y = 0x1BE;
public const int Scale = 0x1AC;
}
[StructLayout(LayoutKind.Explicit)]
public struct Addon {
[FieldOffset(AddonOffsets.Name), MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string Name;
[FieldOffset(AddonOffsets.Flags)] public byte Flags;
[FieldOffset(AddonOffsets.X)] public short X;
[FieldOffset(AddonOffsets.Y)] public short Y;
[FieldOffset(AddonOffsets.Scale)] public float Scale;
}
}