From 65d0acaf64a584bd85427bd8440845cdc9f3d7d7 Mon Sep 17 00:00:00 2001
From: goat <16760685+goaaats@users.noreply.github.com>
Date: Tue, 7 Dec 2021 21:54:05 +0100
Subject: [PATCH] feat: move UIDebug PrintOutObject into Util, add
ImGuiHelpers.ClickToCopyText
---
Dalamud/Interface/ImGuiHelpers.cs | 18 +++
Dalamud/Interface/Internal/UiDebug.cs | 179 ++++----------------------
Dalamud/Utility/Util.cs | 128 ++++++++++++++++++
3 files changed, 169 insertions(+), 156 deletions(-)
diff --git a/Dalamud/Interface/ImGuiHelpers.cs b/Dalamud/Interface/ImGuiHelpers.cs
index f138cdf40..395d3340b 100644
--- a/Dalamud/Interface/ImGuiHelpers.cs
+++ b/Dalamud/Interface/ImGuiHelpers.cs
@@ -119,5 +119,23 @@ namespace Dalamud.Interface
{
GlobalScale = ImGui.GetIO().FontGlobalScale;
}
+
+ ///
+ /// Print out text that can be copied when clicked.
+ ///
+ /// The text to show.
+ /// The text to copy when clicked.
+ public static void ClickToCopyText(string text, string? textCopy = null)
+ {
+ textCopy ??= text;
+ ImGui.Text($"{text}");
+ if (ImGui.IsItemHovered())
+ {
+ ImGui.SetMouseCursor(ImGuiMouseCursor.Hand);
+ if (textCopy != text) ImGui.SetTooltip(textCopy);
+ }
+
+ if (ImGui.IsItemClicked()) ImGui.SetClipboardText($"{textCopy}");
+ }
}
}
diff --git a/Dalamud/Interface/Internal/UiDebug.cs b/Dalamud/Interface/Internal/UiDebug.cs
index e64ec6bc2..0a5c27004 100644
--- a/Dalamud/Interface/Internal/UiDebug.cs
+++ b/Dalamud/Interface/Internal/UiDebug.cs
@@ -8,6 +8,7 @@ using System.Runtime.InteropServices;
using Dalamud.Game;
using Dalamud.Game.Gui;
+using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Component.GUI;
using ImGuiNET;
@@ -49,8 +50,6 @@ namespace Dalamud.Interface.Internal
private bool doingSearch;
private string searchInput = string.Empty;
private AtkUnitBase* selectedUnitBase = null;
- private ulong beginModule;
- private ulong endModule;
///
/// Initializes a new instance of the class.
@@ -88,19 +87,6 @@ namespace Dalamud.Interface.Internal
ImGui.PopStyleVar();
}
- private static void ClickToCopyText(string text, string textCopy = null)
- {
- textCopy ??= text;
- ImGui.Text($"{text}");
- if (ImGui.IsItemHovered())
- {
- ImGui.SetMouseCursor(ImGuiMouseCursor.Hand);
- if (textCopy != text) ImGui.SetTooltip(textCopy);
- }
-
- if (ImGui.IsItemClicked()) ImGui.SetClipboardText($"{textCopy}");
- }
-
private void DrawUnitBase(AtkUnitBase* atkUnitBase)
{
var isVisible = (atkUnitBase->Flags & 0x20) == 0x20;
@@ -120,8 +106,8 @@ namespace Dalamud.Interface.Internal
}
ImGui.Separator();
- ClickToCopyText($"Address: {(ulong)atkUnitBase:X}", $"{(ulong)atkUnitBase:X}");
- ClickToCopyText($"Agent: {(ulong)agent:X}", $"{(ulong)agent:X}");
+ ImGuiHelpers.ClickToCopyText($"Address: {(ulong)atkUnitBase:X}", $"{(ulong)atkUnitBase:X}");
+ ImGuiHelpers.ClickToCopyText($"Agent: {(ulong)agent:X}", $"{(ulong)agent:X}");
ImGui.Separator();
ImGui.Text($"Position: [ {atkUnitBase->X} , {atkUnitBase->Y} ]");
@@ -132,7 +118,7 @@ namespace Dalamud.Interface.Internal
object addonObj = *atkUnitBase;
- this.PrintOutObject(addonObj, (ulong)atkUnitBase, new List());
+ Util.PrintOutObject(addonObj, (ulong)atkUnitBase, new List());
ImGui.Dummy(new Vector2(25 * ImGui.GetIO().FontGlobalScale));
ImGui.Separator();
@@ -205,16 +191,16 @@ namespace Dalamud.Interface.Internal
ImGui.Text("Node: ");
ImGui.SameLine();
- ClickToCopyText($"{(ulong)node:X}");
+ ImGuiHelpers.ClickToCopyText($"{(ulong)node:X}");
ImGui.SameLine();
switch (node->Type)
{
- case NodeType.Text: this.PrintOutObject(*(AtkTextNode*)node, (ulong)node, new List()); break;
- case NodeType.Image: this.PrintOutObject(*(AtkImageNode*)node, (ulong)node, new List()); break;
- case NodeType.Collision: this.PrintOutObject(*(AtkCollisionNode*)node, (ulong)node, new List()); break;
- case NodeType.NineGrid: this.PrintOutObject(*(AtkNineGridNode*)node, (ulong)node, new List()); break;
- case NodeType.Counter: this.PrintOutObject(*(AtkCounterNode*)node, (ulong)node, new List()); break;
- default: this.PrintOutObject(*node, (ulong)node, new List()); break;
+ case NodeType.Text: Util.PrintOutObject(*(AtkTextNode*)node, (ulong)node); break;
+ case NodeType.Image: Util.PrintOutObject(*(AtkImageNode*)node, (ulong)node); break;
+ case NodeType.Collision: Util.PrintOutObject(*(AtkCollisionNode*)node, (ulong)node); break;
+ case NodeType.NineGrid: Util.PrintOutObject(*(AtkNineGridNode*)node, (ulong)node); break;
+ case NodeType.Counter: Util.PrintOutObject(*(AtkCounterNode*)node, (ulong)node); break;
+ default: Util.PrintOutObject(*node, (ulong)node, new List()); break;
}
this.PrintResNode(node);
@@ -341,25 +327,25 @@ namespace Dalamud.Interface.Internal
ImGui.Text("Node: ");
ImGui.SameLine();
- ClickToCopyText($"{(ulong)node:X}");
+ ImGuiHelpers.ClickToCopyText($"{(ulong)node:X}");
ImGui.SameLine();
- this.PrintOutObject(*compNode, (ulong)compNode, new List());
+ Util.PrintOutObject(*compNode, (ulong)compNode);
ImGui.Text("Component: ");
ImGui.SameLine();
- ClickToCopyText($"{(ulong)compNode->Component:X}");
+ ImGuiHelpers.ClickToCopyText($"{(ulong)compNode->Component:X}");
ImGui.SameLine();
switch (objectInfo->ComponentType)
{
- case ComponentType.Button: this.PrintOutObject(*(AtkComponentButton*)compNode->Component, (ulong)compNode->Component, new List()); break;
- case ComponentType.Slider: this.PrintOutObject(*(AtkComponentSlider*)compNode->Component, (ulong)compNode->Component, new List()); break;
- case ComponentType.Window: this.PrintOutObject(*(AtkComponentWindow*)compNode->Component, (ulong)compNode->Component, new List()); break;
- case ComponentType.CheckBox: this.PrintOutObject(*(AtkComponentCheckBox*)compNode->Component, (ulong)compNode->Component, new List()); break;
- case ComponentType.GaugeBar: this.PrintOutObject(*(AtkComponentGaugeBar*)compNode->Component, (ulong)compNode->Component, new List()); break;
- case ComponentType.RadioButton: this.PrintOutObject(*(AtkComponentRadioButton*)compNode->Component, (ulong)compNode->Component, new List()); break;
- case ComponentType.TextInput: this.PrintOutObject(*(AtkComponentTextInput*)compNode->Component, (ulong)compNode->Component, new List()); break;
- case ComponentType.Icon: this.PrintOutObject(*(AtkComponentIcon*)compNode->Component, (ulong)compNode->Component, new List()); break;
- default: this.PrintOutObject(*compNode->Component, (ulong)compNode->Component, new List()); break;
+ case ComponentType.Button: Util.PrintOutObject(*(AtkComponentButton*)compNode->Component, (ulong)compNode->Component); break;
+ case ComponentType.Slider: Util.PrintOutObject(*(AtkComponentSlider*)compNode->Component, (ulong)compNode->Component); break;
+ case ComponentType.Window: Util.PrintOutObject(*(AtkComponentWindow*)compNode->Component, (ulong)compNode->Component); break;
+ case ComponentType.CheckBox: Util.PrintOutObject(*(AtkComponentCheckBox*)compNode->Component, (ulong)compNode->Component); break;
+ case ComponentType.GaugeBar: Util.PrintOutObject(*(AtkComponentGaugeBar*)compNode->Component, (ulong)compNode->Component); break;
+ case ComponentType.RadioButton: Util.PrintOutObject(*(AtkComponentRadioButton*)compNode->Component, (ulong)compNode->Component); break;
+ case ComponentType.TextInput: Util.PrintOutObject(*(AtkComponentTextInput*)compNode->Component, (ulong)compNode->Component); break;
+ case ComponentType.Icon: Util.PrintOutObject(*(AtkComponentIcon*)compNode->Component, (ulong)compNode->Component); break;
+ default: Util.PrintOutObject(*compNode->Component, (ulong)compNode->Component); break;
}
this.PrintResNode(node);
@@ -609,124 +595,5 @@ namespace Dalamud.Interface.Internal
ImGui.GetForegroundDrawList(ImGuiHelpers.MainViewport).AddRect(position, position + size, nodeVisible ? 0xFF00FF00 : 0xFF0000FF);
}
-
- private void PrintOutValue(ulong addr, IEnumerable path, Type type, object value)
- {
- if (type.IsPointer)
- {
- var val = (Pointer)value;
- var unboxed = Pointer.Unbox(val);
- if (unboxed != null)
- {
- var unboxedAddr = (ulong)unboxed;
- ClickToCopyText($"{(ulong)unboxed:X}");
- if (this.beginModule > 0 && unboxedAddr >= this.beginModule && unboxedAddr <= this.endModule)
- {
- ImGui.SameLine();
- ImGui.PushStyleColor(ImGuiCol.Text, 0xffcbc0ff);
- ClickToCopyText($"ffxiv_dx11.exe+{unboxedAddr - this.beginModule:X}");
- ImGui.PopStyleColor();
- }
-
- try
- {
- var eType = type.GetElementType();
- var ptrObj = Marshal.PtrToStructure(new IntPtr(unboxed), eType);
- ImGui.SameLine();
- this.PrintOutObject(ptrObj, (ulong)unboxed, new List(path));
- }
- catch
- {
- // Ignored
- }
- }
- else
- {
- ImGui.Text("null");
- }
- }
- else
- {
- if (!type.IsPrimitive)
- {
- this.PrintOutObject(value, addr, new List(path));
- }
- else
- {
- ImGui.Text($"{value}");
- }
- }
- }
-
- private void PrintOutObject(object obj, ulong addr, List path, bool autoExpand = false)
- {
- if (this.endModule == 0 && this.beginModule == 0)
- {
- try
- {
- var processModule = Process.GetCurrentProcess().MainModule;
- if (processModule != null)
- {
- this.beginModule = (ulong)processModule.BaseAddress.ToInt64();
- this.endModule = this.beginModule + (ulong)processModule.ModuleMemorySize;
- }
- else
- {
- this.endModule = 1;
- }
- }
- catch
- {
- this.endModule = 1;
- }
- }
-
- ImGui.PushStyleColor(ImGuiCol.Text, 0xFF00FFFF);
- if (autoExpand)
- {
- ImGui.SetNextItemOpen(true, ImGuiCond.Appearing);
- }
-
- if (ImGui.TreeNode($"{obj}##print-obj-{addr:X}-{string.Join("-", path)}"))
- {
- ImGui.PopStyleColor();
- foreach (var f in obj.GetType().GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance))
- {
- var fixedBuffer = (FixedBufferAttribute)f.GetCustomAttribute(typeof(FixedBufferAttribute));
- if (fixedBuffer != null)
- {
- ImGui.Text($"fixed");
- ImGui.SameLine();
- ImGui.TextColored(new Vector4(0.2f, 0.9f, 0.9f, 1), $"{fixedBuffer.ElementType.Name}[0x{fixedBuffer.Length:X}]");
- }
- else
- {
- ImGui.TextColored(new Vector4(0.2f, 0.9f, 0.9f, 1), $"{f.FieldType.Name}");
- }
-
- ImGui.SameLine();
- ImGui.TextColored(new Vector4(0.2f, 0.9f, 0.4f, 1), $"{f.Name}: ");
- ImGui.SameLine();
-
- this.PrintOutValue(addr, new List(path) { f.Name }, f.FieldType, f.GetValue(obj));
- }
-
- foreach (var p in obj.GetType().GetProperties())
- {
- ImGui.TextColored(new Vector4(0.2f, 0.9f, 0.9f, 1), $"{p.PropertyType.Name}");
- ImGui.SameLine();
- ImGui.TextColored(new Vector4(0.2f, 0.6f, 0.4f, 1), $"{p.Name}: ");
- ImGui.SameLine();
-
- this.PrintOutValue(addr, new List(path) { p.Name }, p.PropertyType, p.GetValue(obj));
- }
-
- ImGui.TreePop();
- }
- else
- {
- ImGui.PopStyleColor();
- }
- }
}
}
diff --git a/Dalamud/Utility/Util.cs b/Dalamud/Utility/Util.cs
index f69a75f60..fcb6d3c1d 100644
--- a/Dalamud/Utility/Util.cs
+++ b/Dalamud/Utility/Util.cs
@@ -1,10 +1,14 @@
using System;
+using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http;
+using System.Numerics;
using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using System.Text;
using Dalamud.Configuration.Internal;
@@ -156,6 +160,130 @@ namespace Dalamud.Utility
return sb.ToString().TrimEnd(Environment.NewLine.ToCharArray());
}
+ private static ulong moduleStartAddr;
+ private static ulong moduleEndAddr;
+
+ private static unsafe void PrintOutValue(ulong addr, IEnumerable path, Type type, object value)
+ {
+ if (type.IsPointer)
+ {
+ var val = (Pointer)value;
+ var unboxed = Pointer.Unbox(val);
+ if (unboxed != null)
+ {
+ var unboxedAddr = (ulong)unboxed;
+ ImGuiHelpers.ClickToCopyText($"{(ulong)unboxed:X}");
+ if (moduleStartAddr > 0 && unboxedAddr >= moduleStartAddr && unboxedAddr <= moduleEndAddr)
+ {
+ ImGui.SameLine();
+ ImGui.PushStyleColor(ImGuiCol.Text, 0xffcbc0ff);
+ ImGuiHelpers.ClickToCopyText($"ffxiv_dx11.exe+{unboxedAddr - moduleStartAddr:X}");
+ ImGui.PopStyleColor();
+ }
+
+ try
+ {
+ var eType = type.GetElementType();
+ var ptrObj = Marshal.PtrToStructure(new IntPtr(unboxed), eType);
+ ImGui.SameLine();
+ PrintOutObject(ptrObj, (ulong)unboxed, new List(path));
+ }
+ catch
+ {
+ // Ignored
+ }
+ }
+ else
+ {
+ ImGui.Text("null");
+ }
+ }
+ else
+ {
+ if (!type.IsPrimitive)
+ {
+ PrintOutObject(value, addr, new List(path));
+ }
+ else
+ {
+ ImGui.Text($"{value}");
+ }
+ }
+ }
+
+ public static void PrintOutObject(object obj, ulong addr, IEnumerable? path = null, bool autoExpand = false)
+ {
+ path ??= new List();
+
+ if (moduleEndAddr == 0 && moduleStartAddr == 0)
+ {
+ try
+ {
+ var processModule = Process.GetCurrentProcess().MainModule;
+ if (processModule != null)
+ {
+ moduleStartAddr = (ulong)processModule.BaseAddress.ToInt64();
+ moduleEndAddr = moduleStartAddr + (ulong)processModule.ModuleMemorySize;
+ }
+ else
+ {
+ moduleEndAddr = 1;
+ }
+ }
+ catch
+ {
+ moduleEndAddr = 1;
+ }
+ }
+
+ ImGui.PushStyleColor(ImGuiCol.Text, 0xFF00FFFF);
+ if (autoExpand)
+ {
+ ImGui.SetNextItemOpen(true, ImGuiCond.Appearing);
+ }
+
+ if (ImGui.TreeNode($"{obj}##print-obj-{addr:X}-{string.Join("-", path)}"))
+ {
+ ImGui.PopStyleColor();
+ foreach (var f in obj.GetType().GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance))
+ {
+ var fixedBuffer = (FixedBufferAttribute)f.GetCustomAttribute(typeof(FixedBufferAttribute));
+ if (fixedBuffer != null)
+ {
+ ImGui.Text($"fixed");
+ ImGui.SameLine();
+ ImGui.TextColored(new Vector4(0.2f, 0.9f, 0.9f, 1), $"{fixedBuffer.ElementType.Name}[0x{fixedBuffer.Length:X}]");
+ }
+ else
+ {
+ ImGui.TextColored(new Vector4(0.2f, 0.9f, 0.9f, 1), $"{f.FieldType.Name}");
+ }
+
+ ImGui.SameLine();
+ ImGui.TextColored(new Vector4(0.2f, 0.9f, 0.4f, 1), $"{f.Name}: ");
+ ImGui.SameLine();
+
+ PrintOutValue(addr, new List(path) { f.Name }, f.FieldType, f.GetValue(obj));
+ }
+
+ foreach (var p in obj.GetType().GetProperties())
+ {
+ ImGui.TextColored(new Vector4(0.2f, 0.9f, 0.9f, 1), $"{p.PropertyType.Name}");
+ ImGui.SameLine();
+ ImGui.TextColored(new Vector4(0.2f, 0.6f, 0.4f, 1), $"{p.Name}: ");
+ ImGui.SameLine();
+
+ PrintOutValue(addr, new List(path) { p.Name }, p.PropertyType, p.GetValue(obj));
+ }
+
+ ImGui.TreePop();
+ }
+ else
+ {
+ ImGui.PopStyleColor();
+ }
+ }
+
///
/// Show all properties and fields of the provided object via ImGui.
///