mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-25 18:09:17 +01:00
/xldata window refactor (#1257)
Reworks the `/xldata` window so that each individual section is in its own file.
This commit is contained in:
parent
11ea64410e
commit
694159a510
37 changed files with 2701 additions and 1893 deletions
|
|
@ -16,6 +16,7 @@ using Dalamud.Interface.Animation.EasingFunctions;
|
|||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Internal.ManagedAsserts;
|
||||
using Dalamud.Interface.Internal.Windows;
|
||||
using Dalamud.Interface.Internal.Windows.Data;
|
||||
using Dalamud.Interface.Internal.Windows.PluginInstaller;
|
||||
using Dalamud.Interface.Internal.Windows.SelfTest;
|
||||
using Dalamud.Interface.Internal.Windows.Settings;
|
||||
|
|
|
|||
|
|
@ -53,8 +53,6 @@ internal unsafe class UiDebug
|
|||
{
|
||||
}
|
||||
|
||||
private delegate AtkStage* GetAtkStageSingleton();
|
||||
|
||||
/// <summary>
|
||||
/// Renders this window.
|
||||
/// </summary>
|
||||
|
|
@ -165,7 +163,7 @@ internal unsafe class UiDebug
|
|||
private void PrintSimpleNode(AtkResNode* node, string treePrefix)
|
||||
{
|
||||
var popped = false;
|
||||
var isVisible = (node->Flags & 0x10) == 0x10;
|
||||
var isVisible = node->NodeFlags.HasFlag(NodeFlags.Visible);
|
||||
|
||||
if (isVisible)
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0, 255, 0, 255));
|
||||
|
|
@ -296,7 +294,7 @@ internal unsafe class UiDebug
|
|||
var compNode = (AtkComponentNode*)node;
|
||||
|
||||
var popped = false;
|
||||
var isVisible = (node->Flags & 0x10) == 0x10;
|
||||
var isVisible = node->NodeFlags.HasFlag(NodeFlags.Visible);
|
||||
|
||||
var componentInfo = compNode->Component->UldManager;
|
||||
|
||||
|
|
@ -396,7 +394,7 @@ internal unsafe class UiDebug
|
|||
ImGui.SameLine();
|
||||
if (ImGui.SmallButton($"T:Visible##{(ulong)node:X}"))
|
||||
{
|
||||
node->Flags ^= 0x10;
|
||||
node->NodeFlags ^= NodeFlags.Visible;
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
|
@ -573,7 +571,7 @@ internal unsafe class UiDebug
|
|||
if (node == null) return false;
|
||||
while (node != null)
|
||||
{
|
||||
if ((node->Flags & (short)NodeFlags.Visible) != (short)NodeFlags.Visible) return false;
|
||||
if (!node->NodeFlags.HasFlag(NodeFlags.Visible)) return false;
|
||||
node = node->ParentNode;
|
||||
}
|
||||
|
||||
|
|
|
|||
158
Dalamud/Interface/Internal/Windows/Data/DataKindEnum.cs
Normal file
158
Dalamud/Interface/Internal/Windows/Data/DataKindEnum.cs
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
// ReSharper disable InconsistentNaming // Naming is suppressed so we can replace '_' with ' '
|
||||
namespace Dalamud.Interface.Internal.Windows;
|
||||
|
||||
/// <summary>
|
||||
/// Enum representing a DataKind for the Data Window.
|
||||
/// </summary>
|
||||
internal enum DataKind
|
||||
{
|
||||
/// <summary>
|
||||
/// Server Opcode Display.
|
||||
/// </summary>
|
||||
Server_OpCode,
|
||||
|
||||
/// <summary>
|
||||
/// Address.
|
||||
/// </summary>
|
||||
Address,
|
||||
|
||||
/// <summary>
|
||||
/// Object Table.
|
||||
/// </summary>
|
||||
Object_Table,
|
||||
|
||||
/// <summary>
|
||||
/// Fate Table.
|
||||
/// </summary>
|
||||
Fate_Table,
|
||||
|
||||
/// <summary>
|
||||
/// SE Font Test.
|
||||
/// </summary>
|
||||
SE_Font_Test,
|
||||
|
||||
/// <summary>
|
||||
/// FontAwesome Test.
|
||||
/// </summary>
|
||||
FontAwesome_Test,
|
||||
|
||||
/// <summary>
|
||||
/// Party List.
|
||||
/// </summary>
|
||||
Party_List,
|
||||
|
||||
/// <summary>
|
||||
/// Buddy List.
|
||||
/// </summary>
|
||||
Buddy_List,
|
||||
|
||||
/// <summary>
|
||||
/// Plugin IPC Test.
|
||||
/// </summary>
|
||||
Plugin_IPC,
|
||||
|
||||
/// <summary>
|
||||
/// Player Condition.
|
||||
/// </summary>
|
||||
Condition,
|
||||
|
||||
/// <summary>
|
||||
/// Gauge.
|
||||
/// </summary>
|
||||
Gauge,
|
||||
|
||||
/// <summary>
|
||||
/// Command.
|
||||
/// </summary>
|
||||
Command,
|
||||
|
||||
/// <summary>
|
||||
/// Addon.
|
||||
/// </summary>
|
||||
Addon,
|
||||
|
||||
/// <summary>
|
||||
/// Addon Inspector.
|
||||
/// </summary>
|
||||
Addon_Inspector,
|
||||
|
||||
/// <summary>
|
||||
/// AtkArrayData Browser.
|
||||
/// </summary>
|
||||
AtkArrayData_Browser,
|
||||
|
||||
/// <summary>
|
||||
/// StartInfo.
|
||||
/// </summary>
|
||||
StartInfo,
|
||||
|
||||
/// <summary>
|
||||
/// Target.
|
||||
/// </summary>
|
||||
Target,
|
||||
|
||||
/// <summary>
|
||||
/// Toast.
|
||||
/// </summary>
|
||||
Toast,
|
||||
|
||||
/// <summary>
|
||||
/// Fly Text.
|
||||
/// </summary>
|
||||
FlyText,
|
||||
|
||||
/// <summary>
|
||||
/// ImGui.
|
||||
/// </summary>
|
||||
ImGui,
|
||||
|
||||
/// <summary>
|
||||
/// Tex.
|
||||
/// </summary>
|
||||
Tex,
|
||||
|
||||
/// <summary>
|
||||
/// KeyState.
|
||||
/// </summary>
|
||||
KeyState,
|
||||
|
||||
/// <summary>
|
||||
/// GamePad.
|
||||
/// </summary>
|
||||
Gamepad,
|
||||
|
||||
/// <summary>
|
||||
/// Configuration.
|
||||
/// </summary>
|
||||
Configuration,
|
||||
|
||||
/// <summary>
|
||||
/// Task Scheduler.
|
||||
/// </summary>
|
||||
TaskSched,
|
||||
|
||||
/// <summary>
|
||||
/// Hook.
|
||||
/// </summary>
|
||||
Hook,
|
||||
|
||||
/// <summary>
|
||||
/// Aetherytes.
|
||||
/// </summary>
|
||||
Aetherytes,
|
||||
|
||||
/// <summary>
|
||||
/// DTR Bar.
|
||||
/// </summary>
|
||||
Dtr_Bar,
|
||||
|
||||
/// <summary>
|
||||
/// UIColor.
|
||||
/// </summary>
|
||||
UIColor,
|
||||
|
||||
/// <summary>
|
||||
/// Data Share.
|
||||
/// </summary>
|
||||
DataShare,
|
||||
}
|
||||
191
Dalamud/Interface/Internal/Windows/Data/DataWindow.cs
Normal file
191
Dalamud/Interface/Internal/Windows/Data/DataWindow.cs
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
|
||||
using Dalamud.Game.Gui;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using ImGuiNET;
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Class responsible for drawing the data/debug window.
|
||||
/// </summary>
|
||||
internal class DataWindow : Window
|
||||
{
|
||||
private readonly IDataWindowWidget[] modules =
|
||||
{
|
||||
new ServerOpcodeWidget(),
|
||||
new AddressesWidget(),
|
||||
new ObjectTableWidget(),
|
||||
new FateTableWidget(),
|
||||
new SeFontTestWidget(),
|
||||
new FontAwesomeTestWidget(),
|
||||
new PartyListWidget(),
|
||||
new BuddyListWidget(),
|
||||
new PluginIpcWidget(),
|
||||
new ConditionWidget(),
|
||||
new GaugeWidget(),
|
||||
new CommandWidget(),
|
||||
new AddonWidget(),
|
||||
new AddonInspectorWidget(),
|
||||
new AtkArrayDataBrowserWidget(),
|
||||
new StartInfoWidget(),
|
||||
new TargetWidget(),
|
||||
new ToastWidget(),
|
||||
new FlyTextWidget(),
|
||||
new ImGuiWidget(),
|
||||
new TexWidget(),
|
||||
new KeyStateWidget(),
|
||||
new GamepadWidget(),
|
||||
new ConfigurationWidget(),
|
||||
new TaskSchedulerWidget(),
|
||||
new HookWidget(),
|
||||
new AetherytesWidget(),
|
||||
new DtrBarWidget(),
|
||||
new UIColorWidget(),
|
||||
new DataShareWidget(),
|
||||
};
|
||||
|
||||
private readonly Dictionary<DataKind, string> dataKindNames = new();
|
||||
|
||||
private bool isExcept;
|
||||
private DataKind currentKind;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DataWindow"/> class.
|
||||
/// </summary>
|
||||
public DataWindow()
|
||||
: base("Dalamud Data")
|
||||
{
|
||||
this.Size = new Vector2(500, 500);
|
||||
this.SizeCondition = ImGuiCond.FirstUseEver;
|
||||
|
||||
this.RespectCloseHotkey = false;
|
||||
|
||||
foreach (var dataKind in Enum.GetValues<DataKind>())
|
||||
{
|
||||
this.dataKindNames[dataKind] = dataKind.ToString().Replace("_", " ");
|
||||
}
|
||||
|
||||
this.Load();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnOpen()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnClose()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the DataKind dropdown menu.
|
||||
/// </summary>
|
||||
/// <param name="dataKind">Data kind name, can be lower and/or without spaces.</param>
|
||||
public void SetDataKind(string dataKind)
|
||||
{
|
||||
if (string.IsNullOrEmpty(dataKind))
|
||||
return;
|
||||
|
||||
dataKind = dataKind switch
|
||||
{
|
||||
"ai" => "Addon Inspector",
|
||||
"at" => "Object Table", // Actor Table
|
||||
"ot" => "Object Table",
|
||||
"uic" => "UIColor",
|
||||
_ => dataKind,
|
||||
};
|
||||
|
||||
dataKind = dataKind.Replace(" ", string.Empty).ToLower();
|
||||
|
||||
var matched = Enum
|
||||
.GetValues<DataKind>()
|
||||
.FirstOrDefault(kind => Enum.GetName(kind)?.Replace("_", string.Empty).ToLower() == dataKind);
|
||||
|
||||
if (matched != default)
|
||||
{
|
||||
this.currentKind = matched;
|
||||
}
|
||||
else
|
||||
{
|
||||
Service<ChatGui>.Get().PrintError($"/xldata: Invalid data type {dataKind}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw the window via ImGui.
|
||||
/// </summary>
|
||||
public override void Draw()
|
||||
{
|
||||
if (ImGuiComponents.IconButton("forceReload", FontAwesomeIcon.Sync)) this.Load();
|
||||
if (ImGui.IsItemHovered()) ImGui.SetTooltip("Force Reload");
|
||||
ImGui.SameLine();
|
||||
var copy = ImGuiComponents.IconButton("copyAll", FontAwesomeIcon.ClipboardList);
|
||||
if (ImGui.IsItemHovered()) ImGui.SetTooltip("Copy All");
|
||||
ImGui.SameLine();
|
||||
|
||||
ImGui.SetNextItemWidth(275.0f * ImGuiHelpers.GlobalScale);
|
||||
if (ImGui.BeginCombo("Data Kind", this.dataKindNames[this.currentKind]))
|
||||
{
|
||||
foreach (var module in this.modules.OrderBy(module => this.dataKindNames[module.DataKind]))
|
||||
{
|
||||
if (ImGui.Selectable(this.dataKindNames[module.DataKind], this.currentKind == module.DataKind))
|
||||
{
|
||||
this.currentKind = module.DataKind;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndCombo();
|
||||
}
|
||||
|
||||
ImGuiHelpers.ScaledDummy(10.0f);
|
||||
|
||||
ImGui.BeginChild("scrolling", Vector2.Zero, false, ImGuiWindowFlags.HorizontalScrollbar);
|
||||
|
||||
if (copy)
|
||||
ImGui.LogToClipboard();
|
||||
|
||||
try
|
||||
{
|
||||
var selectedWidget = this.modules.FirstOrDefault(dataWindowWidget => dataWindowWidget.DataKind == this.currentKind);
|
||||
|
||||
if (selectedWidget is { Ready: true })
|
||||
{
|
||||
selectedWidget.Draw();
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextUnformatted("Data not ready.");
|
||||
}
|
||||
|
||||
this.isExcept = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!this.isExcept)
|
||||
{
|
||||
Log.Error(ex, "Could not draw data");
|
||||
}
|
||||
|
||||
this.isExcept = true;
|
||||
|
||||
ImGui.TextUnformatted(ex.ToString());
|
||||
}
|
||||
|
||||
ImGui.EndChild();
|
||||
}
|
||||
|
||||
private void Load()
|
||||
{
|
||||
foreach (var widget in this.modules)
|
||||
{
|
||||
widget.Load();
|
||||
}
|
||||
}
|
||||
}
|
||||
27
Dalamud/Interface/Internal/Windows/Data/IDataWindowWidget.cs
Normal file
27
Dalamud/Interface/Internal/Windows/Data/IDataWindowWidget.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
namespace Dalamud.Interface.Internal.Windows;
|
||||
|
||||
/// <summary>
|
||||
/// Class representing a date window entry.
|
||||
/// </summary>
|
||||
internal interface IDataWindowWidget
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the Data Kind for this data window module.
|
||||
/// </summary>
|
||||
DataKind DataKind { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this data window module is ready.
|
||||
/// </summary>
|
||||
bool Ready { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Loads the necessary data for this data window module.
|
||||
/// </summary>
|
||||
void Load();
|
||||
|
||||
/// <summary>
|
||||
/// Draws this data window module.
|
||||
/// </summary>
|
||||
void Draw();
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying addon inspector.
|
||||
/// </summary>
|
||||
internal class AddonInspectorWidget : IDataWindowWidget
|
||||
{
|
||||
private UiDebug? addonInspector;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Addon_Inspector;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.addonInspector = new UiDebug();
|
||||
|
||||
if (this.addonInspector is not null)
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
this.addonInspector?.Draw();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
using Dalamud.Game.Gui;
|
||||
using Dalamud.Memory;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying Addon Data.
|
||||
/// </summary>
|
||||
internal unsafe class AddonWidget : IDataWindowWidget
|
||||
{
|
||||
private string inputAddonName = string.Empty;
|
||||
private int inputAddonIndex;
|
||||
private nint findAgentInterfacePtr;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Addon;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
var gameGui = Service<GameGui>.Get();
|
||||
|
||||
ImGui.InputText("Addon Name", ref this.inputAddonName, 256);
|
||||
ImGui.InputInt("Addon Index", ref this.inputAddonIndex);
|
||||
|
||||
if (this.inputAddonName.IsNullOrEmpty())
|
||||
return;
|
||||
|
||||
var address = gameGui.GetAddonByName(this.inputAddonName, this.inputAddonIndex);
|
||||
|
||||
if (address == nint.Zero)
|
||||
{
|
||||
ImGui.Text("Null");
|
||||
return;
|
||||
}
|
||||
|
||||
var addon = (FFXIVClientStructs.FFXIV.Component.GUI.AtkUnitBase*)address;
|
||||
var name = MemoryHelper.ReadStringNullTerminated((nint)addon->Name);
|
||||
ImGui.TextUnformatted($"{name} - 0x{address.ToInt64():X}\n v:{addon->IsVisible} x:{addon->X} y:{addon->Y} s:{addon->Scale}, w:{addon->RootNode->Width}, h:{addon->RootNode->Height}");
|
||||
|
||||
if (ImGui.Button("Find Agent"))
|
||||
{
|
||||
this.findAgentInterfacePtr = gameGui.FindAgentInterface(address);
|
||||
}
|
||||
|
||||
if (this.findAgentInterfacePtr != nint.Zero)
|
||||
{
|
||||
ImGui.TextUnformatted($"Agent: 0x{this.findAgentInterfacePtr.ToInt64():X}");
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.Button("C"))
|
||||
ImGui.SetClipboardText(this.findAgentInterfacePtr.ToInt64().ToString("X"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
using Dalamud.Game;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget to display resolved .text sigs.
|
||||
/// </summary>
|
||||
internal class AddressesWidget : IDataWindowWidget
|
||||
{
|
||||
private string inputSig = string.Empty;
|
||||
private nint sigResult = nint.Zero;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Address;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
ImGui.InputText(".text sig", ref this.inputSig, 400);
|
||||
if (ImGui.Button("Resolve"))
|
||||
{
|
||||
try
|
||||
{
|
||||
var sigScanner = Service<SigScanner>.Get();
|
||||
this.sigResult = sigScanner.ScanText(this.inputSig);
|
||||
}
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
this.sigResult = new nint(-1);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.Text($"Result: {this.sigResult.ToInt64():X}");
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button($"C##{this.sigResult.ToInt64():X}"))
|
||||
ImGui.SetClipboardText(this.sigResult.ToInt64().ToString("X"));
|
||||
|
||||
foreach (var debugScannedValue in BaseAddressResolver.DebugScannedValues)
|
||||
{
|
||||
ImGui.TextUnformatted($"{debugScannedValue.Key}");
|
||||
foreach (var valueTuple in debugScannedValue.Value)
|
||||
{
|
||||
ImGui.TextUnformatted(
|
||||
$" {valueTuple.ClassName} - 0x{valueTuple.Address.ToInt64():X}");
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.Button($"C##{valueTuple.Address.ToInt64():X}"))
|
||||
ImGui.SetClipboardText(valueTuple.Address.ToInt64().ToString("X"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
using Dalamud.Game.ClientState.Aetherytes;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying aetheryte table.
|
||||
/// </summary>
|
||||
internal class AetherytesWidget : IDataWindowWidget
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Aetherytes;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
if (!ImGui.BeginTable("##aetheryteTable", 11, ImGuiTableFlags.ScrollY | ImGuiTableFlags.RowBg | ImGuiTableFlags.Borders))
|
||||
return;
|
||||
|
||||
ImGui.TableSetupScrollFreeze(0, 1);
|
||||
ImGui.TableSetupColumn("Idx", ImGuiTableColumnFlags.WidthFixed);
|
||||
ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthFixed);
|
||||
ImGui.TableSetupColumn("ID", ImGuiTableColumnFlags.WidthFixed);
|
||||
ImGui.TableSetupColumn("Zone", ImGuiTableColumnFlags.WidthFixed);
|
||||
ImGui.TableSetupColumn("Ward", ImGuiTableColumnFlags.WidthFixed);
|
||||
ImGui.TableSetupColumn("Plot", ImGuiTableColumnFlags.WidthFixed);
|
||||
ImGui.TableSetupColumn("Sub", ImGuiTableColumnFlags.WidthFixed);
|
||||
ImGui.TableSetupColumn("Gil", ImGuiTableColumnFlags.WidthFixed);
|
||||
ImGui.TableSetupColumn("Fav", ImGuiTableColumnFlags.WidthFixed);
|
||||
ImGui.TableSetupColumn("Shared", ImGuiTableColumnFlags.WidthFixed);
|
||||
ImGui.TableSetupColumn("Apartment", ImGuiTableColumnFlags.WidthFixed);
|
||||
ImGui.TableHeadersRow();
|
||||
|
||||
var tpList = Service<AetheryteList>.Get();
|
||||
|
||||
for (var i = 0; i < tpList.Length; i++)
|
||||
{
|
||||
var info = tpList[i];
|
||||
if (info == null)
|
||||
continue;
|
||||
|
||||
ImGui.TableNextColumn(); // Idx
|
||||
ImGui.TextUnformatted($"{i}");
|
||||
|
||||
ImGui.TableNextColumn(); // Name
|
||||
ImGui.TextUnformatted($"{info.AetheryteData.GameData?.PlaceName.Value?.Name}");
|
||||
|
||||
ImGui.TableNextColumn(); // ID
|
||||
ImGui.TextUnformatted($"{info.AetheryteId}");
|
||||
|
||||
ImGui.TableNextColumn(); // Zone
|
||||
ImGui.TextUnformatted($"{info.TerritoryId}");
|
||||
|
||||
ImGui.TableNextColumn(); // Ward
|
||||
ImGui.TextUnformatted($"{info.Ward}");
|
||||
|
||||
ImGui.TableNextColumn(); // Plot
|
||||
ImGui.TextUnformatted($"{info.Plot}");
|
||||
|
||||
ImGui.TableNextColumn(); // Sub
|
||||
ImGui.TextUnformatted($"{info.SubIndex}");
|
||||
|
||||
ImGui.TableNextColumn(); // Gil
|
||||
ImGui.TextUnformatted($"{info.GilCost}");
|
||||
|
||||
ImGui.TableNextColumn(); // Favourite
|
||||
ImGui.TextUnformatted($"{info.IsFavourite}");
|
||||
|
||||
ImGui.TableNextColumn(); // Shared
|
||||
ImGui.TextUnformatted($"{info.IsSharedHouse}");
|
||||
|
||||
ImGui.TableNextColumn(); // Apartment
|
||||
ImGui.TextUnformatted($"{info.IsAppartment}");
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
using Dalamud.Memory;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying AtkArrayData.
|
||||
/// </summary>
|
||||
internal unsafe class AtkArrayDataBrowserWidget : IDataWindowWidget
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.AtkArrayData_Browser;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
var fontWidth = ImGui.CalcTextSize("A").X;
|
||||
var fontHeight = ImGui.GetTextLineHeightWithSpacing();
|
||||
var uiModule = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance()->GetUiModule();
|
||||
|
||||
if (uiModule == null)
|
||||
{
|
||||
ImGui.Text("UIModule unavailable.");
|
||||
return;
|
||||
}
|
||||
|
||||
var atkArrayDataHolder = &uiModule->GetRaptureAtkModule()->AtkModule.AtkArrayDataHolder;
|
||||
|
||||
if (ImGui.BeginTabBar("AtkArrayDataBrowserTabBar"))
|
||||
{
|
||||
if (ImGui.BeginTabItem($"NumberArrayData [{atkArrayDataHolder->NumberArrayCount}]"))
|
||||
{
|
||||
if (ImGui.BeginTable("NumberArrayDataTable", 3, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY))
|
||||
{
|
||||
ImGui.TableSetupColumn("Index", ImGuiTableColumnFlags.WidthFixed, fontWidth * 10);
|
||||
ImGui.TableSetupColumn("Size", ImGuiTableColumnFlags.WidthFixed, fontWidth * 10);
|
||||
ImGui.TableSetupColumn("Pointer", ImGuiTableColumnFlags.WidthStretch);
|
||||
ImGui.TableHeadersRow();
|
||||
for (var numberArrayIndex = 0; numberArrayIndex < atkArrayDataHolder->NumberArrayCount; numberArrayIndex++)
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text($"{numberArrayIndex} [{numberArrayIndex * 8:X}]");
|
||||
ImGui.TableNextColumn();
|
||||
var numberArrayData = atkArrayDataHolder->NumberArrays[numberArrayIndex];
|
||||
if (numberArrayData != null)
|
||||
{
|
||||
ImGui.Text($"{numberArrayData->AtkArrayData.Size}");
|
||||
ImGui.TableNextColumn();
|
||||
if (ImGui.TreeNodeEx($"{(long)numberArrayData:X}###{numberArrayIndex}", ImGuiTreeNodeFlags.SpanFullWidth))
|
||||
{
|
||||
ImGui.NewLine();
|
||||
var tableHeight = Math.Min(40, numberArrayData->AtkArrayData.Size + 4);
|
||||
if (ImGui.BeginTable($"NumberArrayDataTable", 4, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY, new Vector2(0.0F, fontHeight * tableHeight)))
|
||||
{
|
||||
ImGui.TableSetupColumn("Index", ImGuiTableColumnFlags.WidthFixed, fontWidth * 6);
|
||||
ImGui.TableSetupColumn("Hex", ImGuiTableColumnFlags.WidthFixed, fontWidth * 9);
|
||||
ImGui.TableSetupColumn("Integer", ImGuiTableColumnFlags.WidthFixed, fontWidth * 12);
|
||||
ImGui.TableSetupColumn("Float", ImGuiTableColumnFlags.WidthFixed, fontWidth * 20);
|
||||
ImGui.TableHeadersRow();
|
||||
for (var numberIndex = 0; numberIndex < numberArrayData->AtkArrayData.Size; numberIndex++)
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text($"{numberIndex}");
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text($"{numberArrayData->IntArray[numberIndex]:X}");
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text($"{numberArrayData->IntArray[numberIndex]}");
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text($"{*(float*)&numberArrayData->IntArray[numberIndex]}");
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
ImGui.TreePop();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextDisabled("--");
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TextDisabled("--");
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui.BeginTabItem($"StringArrayData [{atkArrayDataHolder->StringArrayCount}]"))
|
||||
{
|
||||
if (ImGui.BeginTable("StringArrayDataTable", 3, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY))
|
||||
{
|
||||
ImGui.TableSetupColumn("Index", ImGuiTableColumnFlags.WidthFixed, fontWidth * 10);
|
||||
ImGui.TableSetupColumn("Size", ImGuiTableColumnFlags.WidthFixed, fontWidth * 10);
|
||||
ImGui.TableSetupColumn("Pointer", ImGuiTableColumnFlags.WidthStretch);
|
||||
ImGui.TableHeadersRow();
|
||||
for (var stringArrayIndex = 0; stringArrayIndex < atkArrayDataHolder->StringArrayCount; stringArrayIndex++)
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text($"{stringArrayIndex} [{stringArrayIndex * 8:X}]");
|
||||
ImGui.TableNextColumn();
|
||||
var stringArrayData = atkArrayDataHolder->StringArrays[stringArrayIndex];
|
||||
if (stringArrayData != null)
|
||||
{
|
||||
ImGui.Text($"{stringArrayData->AtkArrayData.Size}");
|
||||
ImGui.TableNextColumn();
|
||||
if (ImGui.TreeNodeEx($"{(long)stringArrayData:X}###{stringArrayIndex}", ImGuiTreeNodeFlags.SpanFullWidth))
|
||||
{
|
||||
ImGui.NewLine();
|
||||
var tableHeight = Math.Min(40, stringArrayData->AtkArrayData.Size + 4);
|
||||
if (ImGui.BeginTable($"StringArrayDataTable", 2, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY, new Vector2(0.0F, fontHeight * tableHeight)))
|
||||
{
|
||||
ImGui.TableSetupColumn("Index", ImGuiTableColumnFlags.WidthFixed, fontWidth * 6);
|
||||
ImGui.TableSetupColumn("String", ImGuiTableColumnFlags.WidthStretch);
|
||||
ImGui.TableHeadersRow();
|
||||
for (var stringIndex = 0; stringIndex < stringArrayData->AtkArrayData.Size; stringIndex++)
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text($"{stringIndex}");
|
||||
ImGui.TableNextColumn();
|
||||
if (stringArrayData->StringArray[stringIndex] != null)
|
||||
{
|
||||
ImGui.Text($"{MemoryHelper.ReadSeStringNullTerminated(new IntPtr(stringArrayData->StringArray[stringIndex]))}");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextDisabled("--");
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
ImGui.TreePop();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextDisabled("--");
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TextDisabled("--");
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
||||
ImGui.EndTabBar();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
using Dalamud.Game.ClientState.Buddy;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying data about the Buddy List.
|
||||
/// </summary>
|
||||
internal class BuddyListWidget : IDataWindowWidget
|
||||
{
|
||||
private bool resolveGameData;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Buddy_List;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
var buddyList = Service<BuddyList>.Get();
|
||||
|
||||
ImGui.Checkbox("Resolve GameData", ref this.resolveGameData);
|
||||
|
||||
ImGui.Text($"BuddyList: {buddyList.BuddyListAddress.ToInt64():X}");
|
||||
{
|
||||
var member = buddyList.CompanionBuddy;
|
||||
if (member == null)
|
||||
{
|
||||
ImGui.Text("[Companion] null");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.Text($"[Companion] {member.Address.ToInt64():X} - {member.ObjectId} - {member.DataID}");
|
||||
if (this.resolveGameData)
|
||||
{
|
||||
var gameObject = member.GameObject;
|
||||
if (gameObject == null)
|
||||
{
|
||||
ImGui.Text("GameObject was null");
|
||||
}
|
||||
else
|
||||
{
|
||||
Util.PrintGameObject(gameObject, "-", this.resolveGameData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
var member = buddyList.PetBuddy;
|
||||
if (member == null)
|
||||
{
|
||||
ImGui.Text("[Pet] null");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.Text($"[Pet] {member.Address.ToInt64():X} - {member.ObjectId} - {member.DataID}");
|
||||
if (this.resolveGameData)
|
||||
{
|
||||
var gameObject = member.GameObject;
|
||||
if (gameObject == null)
|
||||
{
|
||||
ImGui.Text("GameObject was null");
|
||||
}
|
||||
else
|
||||
{
|
||||
Util.PrintGameObject(gameObject, "-", this.resolveGameData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
var count = buddyList.Length;
|
||||
if (count == 0)
|
||||
{
|
||||
ImGui.Text("[BattleBuddy] None present");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var member = buddyList[i];
|
||||
ImGui.Text($"[BattleBuddy] [{i}] {member?.Address.ToInt64():X} - {member?.ObjectId} - {member?.DataID}");
|
||||
if (this.resolveGameData)
|
||||
{
|
||||
var gameObject = member?.GameObject;
|
||||
if (gameObject == null)
|
||||
{
|
||||
ImGui.Text("GameObject was null");
|
||||
}
|
||||
else
|
||||
{
|
||||
Util.PrintGameObject(gameObject, "-", this.resolveGameData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
using Dalamud.Game.Command;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying command info.
|
||||
/// </summary>
|
||||
internal class CommandWidget : IDataWindowWidget
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Command;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
var commandManager = Service<CommandManager>.Get();
|
||||
|
||||
foreach (var command in commandManager.Commands)
|
||||
{
|
||||
ImGui.Text($"{command.Key}\n -> {command.Value.HelpMessage}\n -> In help: {command.Value.ShowInHelp}\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
using Dalamud.Game.ClientState.Conditions;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying current character condition flags.
|
||||
/// </summary>
|
||||
internal class ConditionWidget : IDataWindowWidget
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Condition;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
var condition = Service<Condition>.Get();
|
||||
|
||||
#if DEBUG
|
||||
ImGui.Text($"ptr: 0x{condition.Address.ToInt64():X}");
|
||||
#endif
|
||||
|
||||
ImGui.Text("Current Conditions:");
|
||||
ImGui.Separator();
|
||||
|
||||
var didAny = false;
|
||||
|
||||
for (var i = 0; i < Condition.MaxConditionEntries; i++)
|
||||
{
|
||||
var typedCondition = (ConditionFlag)i;
|
||||
var cond = condition[typedCondition];
|
||||
|
||||
if (!cond) continue;
|
||||
|
||||
didAny = true;
|
||||
|
||||
ImGui.Text($"ID: {i} Enum: {typedCondition}");
|
||||
}
|
||||
|
||||
if (!didAny)
|
||||
ImGui.Text("None. Talk to a shop NPC or visit a market board to find out more!");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Utility;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying configuration info.
|
||||
/// </summary>
|
||||
internal class ConfigurationWidget : IDataWindowWidget
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Configuration;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
var config = Service<DalamudConfiguration>.Get();
|
||||
Util.ShowObject(config);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
using Dalamud.Plugin.Ipc.Internal;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying plugin data share modules.
|
||||
/// </summary>
|
||||
internal class DataShareWidget : IDataWindowWidget
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.DataShare;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
if (!ImGui.BeginTable("###DataShareTable", 4, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
ImGui.TableSetupColumn("Shared Tag");
|
||||
ImGui.TableSetupColumn("Creator Assembly");
|
||||
ImGui.TableSetupColumn("#", ImGuiTableColumnFlags.WidthFixed, 30 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.TableSetupColumn("Consumers");
|
||||
ImGui.TableHeadersRow();
|
||||
foreach (var share in Service<DataShare>.Get().GetAllShares())
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TextUnformatted(share.Tag);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TextUnformatted(share.CreatorAssembly);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TextUnformatted(share.Users.Length.ToString());
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TextUnformatted(string.Join(", ", share.Users));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
ImGui.EndTable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Game.Gui.Dtr;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying dtr test.
|
||||
/// </summary>
|
||||
internal class DtrBarWidget : IDataWindowWidget
|
||||
{
|
||||
private DtrBarEntry? dtrTest1;
|
||||
private DtrBarEntry? dtrTest2;
|
||||
private DtrBarEntry? dtrTest3;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Dtr_Bar;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
this.DrawDtrTestEntry(ref this.dtrTest1, "DTR Test #1");
|
||||
ImGui.Separator();
|
||||
this.DrawDtrTestEntry(ref this.dtrTest2, "DTR Test #2");
|
||||
ImGui.Separator();
|
||||
this.DrawDtrTestEntry(ref this.dtrTest3, "DTR Test #3");
|
||||
ImGui.Separator();
|
||||
|
||||
var configuration = Service<DalamudConfiguration>.Get();
|
||||
if (configuration.DtrOrder != null)
|
||||
{
|
||||
ImGui.Separator();
|
||||
|
||||
foreach (var order in configuration.DtrOrder)
|
||||
{
|
||||
ImGui.Text(order);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawDtrTestEntry(ref DtrBarEntry? entry, string title)
|
||||
{
|
||||
var dtrBar = Service<DtrBar>.Get();
|
||||
|
||||
if (entry != null)
|
||||
{
|
||||
ImGui.Text(title);
|
||||
|
||||
var text = entry.Text?.TextValue ?? string.Empty;
|
||||
if (ImGui.InputText($"Text###{entry.Title}t", ref text, 255))
|
||||
entry.Text = text;
|
||||
|
||||
var shown = entry.Shown;
|
||||
if (ImGui.Checkbox($"Shown###{entry.Title}s", ref shown))
|
||||
entry.Shown = shown;
|
||||
|
||||
if (ImGui.Button($"Remove###{entry.Title}r"))
|
||||
{
|
||||
entry.Remove();
|
||||
entry = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ImGui.Button($"Add###{title}"))
|
||||
{
|
||||
entry = dtrBar.Get(title, title);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
using Dalamud.Game.ClientState.Fates;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying the Fate Table.
|
||||
/// </summary>
|
||||
internal class FateTableWidget : IDataWindowWidget
|
||||
{
|
||||
private bool resolveGameData;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Fate_Table;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
ImGui.Checkbox("Resolve GameData", ref this.resolveGameData);
|
||||
|
||||
var fateTable = Service<FateTable>.Get();
|
||||
|
||||
var stateString = string.Empty;
|
||||
if (fateTable.Length == 0)
|
||||
{
|
||||
ImGui.TextUnformatted("No fates or data not ready.");
|
||||
}
|
||||
else
|
||||
{
|
||||
stateString += $"FateTableLen: {fateTable.Length}\n";
|
||||
|
||||
ImGui.TextUnformatted(stateString);
|
||||
|
||||
for (var i = 0; i < fateTable.Length; i++)
|
||||
{
|
||||
var fate = fateTable[i];
|
||||
if (fate == null)
|
||||
continue;
|
||||
|
||||
var fateString = $"{fate.Address.ToInt64():X}:[{i}]" +
|
||||
$" - Lv.{fate.Level} {fate.Name} ({fate.Progress}%)" +
|
||||
$" - X{fate.Position.X} Y{fate.Position.Y} Z{fate.Position.Z}" +
|
||||
$" - Territory {(this.resolveGameData ? (fate.TerritoryType.GameData?.Name ?? fate.TerritoryType.Id.ToString()) : fate.TerritoryType.Id.ToString())}\n";
|
||||
|
||||
fateString += $" StartTimeEpoch: {fate.StartTimeEpoch}" +
|
||||
$" - Duration: {fate.Duration}" +
|
||||
$" - State: {fate.State}" +
|
||||
$" - GameData name: {(this.resolveGameData ? (fate.GameData.Name ?? fate.FateId.ToString()) : fate.FateId.ToString())}";
|
||||
|
||||
ImGui.TextUnformatted(fateString);
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("C"))
|
||||
{
|
||||
ImGui.SetClipboardText(fate.Address.ToString("X"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
using Dalamud.Game.Gui.FlyText;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying fly text info.
|
||||
/// </summary>
|
||||
internal class FlyTextWidget : IDataWindowWidget
|
||||
{
|
||||
private int flyActor;
|
||||
private FlyTextKind flyKind;
|
||||
private int flyVal1;
|
||||
private int flyVal2;
|
||||
private string flyText1 = string.Empty;
|
||||
private string flyText2 = string.Empty;
|
||||
private int flyIcon;
|
||||
private int flyDmgIcon;
|
||||
private Vector4 flyColor = new(1, 0, 0, 1);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.FlyText;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
if (ImGui.BeginCombo("Kind", this.flyKind.ToString()))
|
||||
{
|
||||
var names = Enum.GetNames(typeof(FlyTextKind));
|
||||
for (var i = 0; i < names.Length; i++)
|
||||
{
|
||||
if (ImGui.Selectable($"{names[i]} ({i})"))
|
||||
this.flyKind = (FlyTextKind)i;
|
||||
}
|
||||
|
||||
ImGui.EndCombo();
|
||||
}
|
||||
|
||||
ImGui.InputText("Text1", ref this.flyText1, 200);
|
||||
ImGui.InputText("Text2", ref this.flyText2, 200);
|
||||
|
||||
ImGui.InputInt("Val1", ref this.flyVal1);
|
||||
ImGui.InputInt("Val2", ref this.flyVal2);
|
||||
|
||||
ImGui.InputInt("Icon ID", ref this.flyIcon);
|
||||
ImGui.InputInt("Damage Icon ID", ref this.flyDmgIcon);
|
||||
ImGui.ColorEdit4("Color", ref this.flyColor);
|
||||
ImGui.InputInt("Actor Index", ref this.flyActor);
|
||||
var sendColor = ImGui.ColorConvertFloat4ToU32(this.flyColor);
|
||||
|
||||
if (ImGui.Button("Send"))
|
||||
{
|
||||
Service<FlyTextGui>.Get().AddFlyText(
|
||||
this.flyKind,
|
||||
unchecked((uint)this.flyActor),
|
||||
unchecked((uint)this.flyVal1),
|
||||
unchecked((uint)this.flyVal2),
|
||||
this.flyText1,
|
||||
this.flyText2,
|
||||
sendColor,
|
||||
unchecked((uint)this.flyIcon),
|
||||
unchecked((uint)this.flyDmgIcon));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget to display FontAwesome Symbols.
|
||||
/// </summary>
|
||||
internal class FontAwesomeTestWidget : IDataWindowWidget
|
||||
{
|
||||
private List<FontAwesomeIcon>? icons;
|
||||
private List<string>? iconNames;
|
||||
private string[]? iconCategories;
|
||||
private int selectedIconCategory;
|
||||
private string iconSearchInput = string.Empty;
|
||||
private bool iconSearchChanged = true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.FontAwesome_Test;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero);
|
||||
|
||||
this.iconCategories ??= FontAwesomeHelpers.GetCategories();
|
||||
|
||||
if (this.iconSearchChanged)
|
||||
{
|
||||
this.icons = FontAwesomeHelpers.SearchIcons(this.iconSearchInput, this.iconCategories[this.selectedIconCategory]);
|
||||
this.iconNames = this.icons.Select(icon => Enum.GetName(icon)!).ToList();
|
||||
this.iconSearchChanged = false;
|
||||
}
|
||||
|
||||
ImGui.SetNextItemWidth(160f);
|
||||
var categoryIndex = this.selectedIconCategory;
|
||||
if (ImGui.Combo("####FontAwesomeCategorySearch", ref categoryIndex, this.iconCategories, this.iconCategories.Length))
|
||||
{
|
||||
this.selectedIconCategory = categoryIndex;
|
||||
this.iconSearchChanged = true;
|
||||
}
|
||||
|
||||
ImGui.SameLine(170f);
|
||||
ImGui.SetNextItemWidth(180f);
|
||||
if (ImGui.InputTextWithHint($"###FontAwesomeInputSearch", "search icons", ref this.iconSearchInput, 50))
|
||||
{
|
||||
this.iconSearchChanged = true;
|
||||
}
|
||||
|
||||
ImGuiHelpers.ScaledDummy(10f);
|
||||
for (var i = 0; i < this.icons?.Count; i++)
|
||||
{
|
||||
ImGui.Text($"0x{(int)this.icons[i].ToIconChar():X}");
|
||||
ImGuiHelpers.ScaledRelativeSameLine(50f);
|
||||
ImGui.Text($"{this.iconNames?[i]}");
|
||||
ImGuiHelpers.ScaledRelativeSameLine(280f);
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
ImGui.Text(this.icons[i].ToIconString());
|
||||
ImGui.PopFont();
|
||||
ImGuiHelpers.ScaledDummy(2f);
|
||||
}
|
||||
|
||||
ImGui.PopStyleVar();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
using System;
|
||||
|
||||
using Dalamud.Game.ClientState.GamePad;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying gamepad info.
|
||||
/// </summary>
|
||||
internal class GamepadWidget : IDataWindowWidget
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Gamepad;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
var gamepadState = Service<GamepadState>.Get();
|
||||
|
||||
static void DrawHelper(string text, uint mask, Func<GamepadButtons, float> resolve)
|
||||
{
|
||||
ImGui.Text($"{text} {mask:X4}");
|
||||
ImGui.Text($"DPadLeft {resolve(GamepadButtons.DpadLeft)} " +
|
||||
$"DPadUp {resolve(GamepadButtons.DpadUp)} " +
|
||||
$"DPadRight {resolve(GamepadButtons.DpadRight)} " +
|
||||
$"DPadDown {resolve(GamepadButtons.DpadDown)} ");
|
||||
ImGui.Text($"West {resolve(GamepadButtons.West)} " +
|
||||
$"North {resolve(GamepadButtons.North)} " +
|
||||
$"East {resolve(GamepadButtons.East)} " +
|
||||
$"South {resolve(GamepadButtons.South)} ");
|
||||
ImGui.Text($"L1 {resolve(GamepadButtons.L1)} " +
|
||||
$"L2 {resolve(GamepadButtons.L2)} " +
|
||||
$"R1 {resolve(GamepadButtons.R1)} " +
|
||||
$"R2 {resolve(GamepadButtons.R2)} ");
|
||||
ImGui.Text($"Select {resolve(GamepadButtons.Select)} " +
|
||||
$"Start {resolve(GamepadButtons.Start)} " +
|
||||
$"L3 {resolve(GamepadButtons.L3)} " +
|
||||
$"R3 {resolve(GamepadButtons.R3)} ");
|
||||
}
|
||||
|
||||
ImGui.Text($"GamepadInput 0x{gamepadState.GamepadInputAddress.ToInt64():X}");
|
||||
|
||||
#if DEBUG
|
||||
if (ImGui.IsItemHovered())
|
||||
ImGui.SetMouseCursor(ImGuiMouseCursor.Hand);
|
||||
|
||||
if (ImGui.IsItemClicked())
|
||||
ImGui.SetClipboardText($"0x{gamepadState.GamepadInputAddress.ToInt64():X}");
|
||||
#endif
|
||||
|
||||
DrawHelper(
|
||||
"Buttons Raw",
|
||||
gamepadState.ButtonsRaw,
|
||||
gamepadState.Raw);
|
||||
DrawHelper(
|
||||
"Buttons Pressed",
|
||||
gamepadState.ButtonsPressed,
|
||||
gamepadState.Pressed);
|
||||
DrawHelper(
|
||||
"Buttons Repeat",
|
||||
gamepadState.ButtonsRepeat,
|
||||
gamepadState.Repeat);
|
||||
DrawHelper(
|
||||
"Buttons Released",
|
||||
gamepadState.ButtonsReleased,
|
||||
gamepadState.Released);
|
||||
ImGui.Text($"LeftStickLeft {gamepadState.LeftStickLeft:0.00} " +
|
||||
$"LeftStickUp {gamepadState.LeftStickUp:0.00} " +
|
||||
$"LeftStickRight {gamepadState.LeftStickRight:0.00} " +
|
||||
$"LeftStickDown {gamepadState.LeftStickDown:0.00} ");
|
||||
ImGui.Text($"RightStickLeft {gamepadState.RightStickLeft:0.00} " +
|
||||
$"RightStickUp {gamepadState.RightStickUp:0.00} " +
|
||||
$"RightStickRight {gamepadState.RightStickRight:0.00} " +
|
||||
$"RightStickDown {gamepadState.RightStickDown:0.00} ");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.ClientState.JobGauge;
|
||||
using Dalamud.Game.ClientState.JobGauge.Types;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying job gauge data.
|
||||
/// </summary>
|
||||
internal class GaugeWidget : IDataWindowWidget
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Gauge;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
var clientState = Service<ClientState>.Get();
|
||||
var jobGauges = Service<JobGauges>.Get();
|
||||
|
||||
var player = clientState.LocalPlayer;
|
||||
if (player == null)
|
||||
{
|
||||
ImGui.Text("Player is not present");
|
||||
return;
|
||||
}
|
||||
|
||||
var jobID = player.ClassJob.Id;
|
||||
JobGaugeBase? gauge = jobID switch
|
||||
{
|
||||
19 => jobGauges.Get<PLDGauge>(),
|
||||
20 => jobGauges.Get<MNKGauge>(),
|
||||
21 => jobGauges.Get<WARGauge>(),
|
||||
22 => jobGauges.Get<DRGGauge>(),
|
||||
23 => jobGauges.Get<BRDGauge>(),
|
||||
24 => jobGauges.Get<WHMGauge>(),
|
||||
25 => jobGauges.Get<BLMGauge>(),
|
||||
27 => jobGauges.Get<SMNGauge>(),
|
||||
28 => jobGauges.Get<SCHGauge>(),
|
||||
30 => jobGauges.Get<NINGauge>(),
|
||||
31 => jobGauges.Get<MCHGauge>(),
|
||||
32 => jobGauges.Get<DRKGauge>(),
|
||||
33 => jobGauges.Get<ASTGauge>(),
|
||||
34 => jobGauges.Get<SAMGauge>(),
|
||||
35 => jobGauges.Get<RDMGauge>(),
|
||||
37 => jobGauges.Get<GNBGauge>(),
|
||||
38 => jobGauges.Get<DNCGauge>(),
|
||||
39 => jobGauges.Get<RPRGauge>(),
|
||||
40 => jobGauges.Get<SGEGauge>(),
|
||||
_ => null,
|
||||
};
|
||||
|
||||
if (gauge == null)
|
||||
{
|
||||
ImGui.Text("No supported gauge exists for this job.");
|
||||
return;
|
||||
}
|
||||
|
||||
Util.ShowObject(gauge);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Dalamud.Hooking;
|
||||
using ImGuiNET;
|
||||
using PInvoke;
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying hook information.
|
||||
/// </summary>
|
||||
internal class HookWidget : IDataWindowWidget
|
||||
{
|
||||
private Hook<MessageBoxWDelegate>? messageBoxMinHook;
|
||||
private bool hookUseMinHook;
|
||||
|
||||
private delegate int MessageBoxWDelegate(
|
||||
IntPtr hWnd,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string text,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string caption,
|
||||
NativeFunctions.MessageBoxType type);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Hook;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
try
|
||||
{
|
||||
ImGui.Checkbox("Use MinHook", ref this.hookUseMinHook);
|
||||
|
||||
if (ImGui.Button("Create"))
|
||||
this.messageBoxMinHook = Hook<MessageBoxWDelegate>.FromSymbol("User32", "MessageBoxW", this.MessageBoxWDetour, this.hookUseMinHook);
|
||||
|
||||
if (ImGui.Button("Enable"))
|
||||
this.messageBoxMinHook?.Enable();
|
||||
|
||||
if (ImGui.Button("Disable"))
|
||||
this.messageBoxMinHook?.Disable();
|
||||
|
||||
if (ImGui.Button("Call Original"))
|
||||
this.messageBoxMinHook?.Original(IntPtr.Zero, "Hello from .Original", "Hook Test", NativeFunctions.MessageBoxType.Ok);
|
||||
|
||||
if (ImGui.Button("Dispose"))
|
||||
{
|
||||
this.messageBoxMinHook?.Dispose();
|
||||
this.messageBoxMinHook = null;
|
||||
}
|
||||
|
||||
if (ImGui.Button("Test"))
|
||||
_ = NativeFunctions.MessageBoxW(IntPtr.Zero, "Hi", "Hello", NativeFunctions.MessageBoxType.Ok);
|
||||
|
||||
if (this.messageBoxMinHook != null)
|
||||
ImGui.Text("Enabled: " + this.messageBoxMinHook?.IsEnabled);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "MinHook error caught");
|
||||
}
|
||||
}
|
||||
|
||||
private int MessageBoxWDetour(IntPtr hwnd, string text, string caption, NativeFunctions.MessageBoxType type)
|
||||
{
|
||||
Log.Information("[DATAHOOK] {Hwnd} {Text} {Caption} {Type}", hwnd, text, caption, type);
|
||||
|
||||
var result = this.messageBoxMinHook!.Original(hwnd, "Cause Access Violation?", caption, NativeFunctions.MessageBoxType.YesNo);
|
||||
|
||||
if (result == (int)User32.MessageBoxResult.IDYES)
|
||||
{
|
||||
Marshal.ReadByte(IntPtr.Zero);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
using System;
|
||||
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying ImGui test.
|
||||
/// </summary>
|
||||
internal class ImGuiWidget : IDataWindowWidget
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.ImGui;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
var interfaceManager = Service<InterfaceManager>.Get();
|
||||
var notifications = Service<NotificationManager>.Get();
|
||||
|
||||
ImGui.Text("Monitor count: " + ImGui.GetPlatformIO().Monitors.Size);
|
||||
ImGui.Text("OverrideGameCursor: " + interfaceManager.OverrideGameCursor);
|
||||
|
||||
ImGui.Button("THIS IS A BUTTON###hoverTestButton");
|
||||
interfaceManager.OverrideGameCursor = !ImGui.IsItemHovered();
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
ImGui.TextUnformatted($"WindowSystem.TimeSinceLastAnyFocus: {WindowSystem.TimeSinceLastAnyFocus.TotalMilliseconds:0}ms");
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
if (ImGui.Button("Add random notification"))
|
||||
{
|
||||
var rand = new Random();
|
||||
|
||||
var title = rand.Next(0, 5) switch
|
||||
{
|
||||
0 => "This is a toast",
|
||||
1 => "Truly, a toast",
|
||||
2 => "I am testing this toast",
|
||||
3 => "I hope this looks right",
|
||||
4 => "Good stuff",
|
||||
5 => "Nice",
|
||||
_ => null,
|
||||
};
|
||||
|
||||
var type = rand.Next(0, 4) switch
|
||||
{
|
||||
0 => NotificationType.Error,
|
||||
1 => NotificationType.Warning,
|
||||
2 => NotificationType.Info,
|
||||
3 => NotificationType.Success,
|
||||
4 => NotificationType.None,
|
||||
_ => NotificationType.None,
|
||||
};
|
||||
|
||||
const string text = "Bla bla bla bla bla bla bla bla bla bla bla.\nBla bla bla bla bla bla bla bla bla bla bla bla bla bla.";
|
||||
|
||||
notifications.AddNotification(text, title, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
using Dalamud.Game.ClientState.Keys;
|
||||
using Dalamud.Interface.Colors;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying keyboard state.
|
||||
/// </summary>
|
||||
internal class KeyStateWidget : IDataWindowWidget
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.KeyState;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
var keyState = Service<KeyState>.Get();
|
||||
|
||||
ImGui.Columns(4);
|
||||
|
||||
var i = 0;
|
||||
foreach (var vkCode in keyState.GetValidVirtualKeys())
|
||||
{
|
||||
var code = (int)vkCode;
|
||||
var value = keyState[code];
|
||||
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, value ? ImGuiColors.HealerGreen : ImGuiColors.DPSRed);
|
||||
|
||||
ImGui.Text($"{vkCode} ({code})");
|
||||
|
||||
ImGui.PopStyleColor();
|
||||
|
||||
i++;
|
||||
if (i % 24 == 0)
|
||||
ImGui.NextColumn();
|
||||
}
|
||||
|
||||
ImGui.Columns(1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Game.Gui;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget to display the Object Table.
|
||||
/// </summary>
|
||||
internal class ObjectTableWidget : IDataWindowWidget
|
||||
{
|
||||
private bool resolveGameData;
|
||||
private bool drawCharacters;
|
||||
private float maxCharaDrawDistance = 20.0f;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Object_Table;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
ImGui.Checkbox("Resolve GameData", ref this.resolveGameData);
|
||||
|
||||
var chatGui = Service<ChatGui>.Get();
|
||||
var clientState = Service<ClientState>.Get();
|
||||
var gameGui = Service<GameGui>.Get();
|
||||
var objectTable = Service<ObjectTable>.Get();
|
||||
|
||||
var stateString = string.Empty;
|
||||
|
||||
if (clientState.LocalPlayer == null)
|
||||
{
|
||||
ImGui.TextUnformatted("LocalPlayer null.");
|
||||
}
|
||||
else if (clientState.IsPvPExcludingDen)
|
||||
{
|
||||
ImGui.TextUnformatted("Cannot access object table while in PvP.");
|
||||
}
|
||||
else
|
||||
{
|
||||
stateString += $"ObjectTableLen: {objectTable.Length}\n";
|
||||
stateString += $"LocalPlayerName: {clientState.LocalPlayer.Name}\n";
|
||||
stateString += $"CurrentWorldName: {(this.resolveGameData ? clientState.LocalPlayer.CurrentWorld.GameData?.Name : clientState.LocalPlayer.CurrentWorld.Id.ToString())}\n";
|
||||
stateString += $"HomeWorldName: {(this.resolveGameData ? clientState.LocalPlayer.HomeWorld.GameData?.Name : clientState.LocalPlayer.HomeWorld.Id.ToString())}\n";
|
||||
stateString += $"LocalCID: {clientState.LocalContentId:X}\n";
|
||||
stateString += $"LastLinkedItem: {chatGui.LastLinkedItemId}\n";
|
||||
stateString += $"TerritoryType: {clientState.TerritoryType}\n\n";
|
||||
|
||||
ImGui.TextUnformatted(stateString);
|
||||
|
||||
ImGui.Checkbox("Draw characters on screen", ref this.drawCharacters);
|
||||
ImGui.SliderFloat("Draw Distance", ref this.maxCharaDrawDistance, 2f, 40f);
|
||||
|
||||
for (var i = 0; i < objectTable.Length; i++)
|
||||
{
|
||||
var obj = objectTable[i];
|
||||
|
||||
if (obj == null)
|
||||
continue;
|
||||
|
||||
Util.PrintGameObject(obj, i.ToString(), this.resolveGameData);
|
||||
|
||||
if (this.drawCharacters && gameGui.WorldToScreen(obj.Position, out var screenCoords))
|
||||
{
|
||||
// So, while WorldToScreen will return false if the point is off of game client screen, to
|
||||
// to avoid performance issues, we have to manually determine if creating a window would
|
||||
// produce a new viewport, and skip rendering it if so
|
||||
var objectText = $"{obj.Address.ToInt64():X}:{obj.ObjectId:X}[{i}] - {obj.ObjectKind} - {obj.Name}";
|
||||
|
||||
var screenPos = ImGui.GetMainViewport().Pos;
|
||||
var screenSize = ImGui.GetMainViewport().Size;
|
||||
|
||||
var windowSize = ImGui.CalcTextSize(objectText);
|
||||
|
||||
// Add some extra safety padding
|
||||
windowSize.X += ImGui.GetStyle().WindowPadding.X + 10;
|
||||
windowSize.Y += ImGui.GetStyle().WindowPadding.Y + 10;
|
||||
|
||||
if (screenCoords.X + windowSize.X > screenPos.X + screenSize.X ||
|
||||
screenCoords.Y + windowSize.Y > screenPos.Y + screenSize.Y)
|
||||
continue;
|
||||
|
||||
if (obj.YalmDistanceX > this.maxCharaDrawDistance)
|
||||
continue;
|
||||
|
||||
ImGui.SetNextWindowPos(new Vector2(screenCoords.X, screenCoords.Y));
|
||||
|
||||
ImGui.SetNextWindowBgAlpha(Math.Max(1f - (obj.YalmDistanceX / this.maxCharaDrawDistance), 0.2f));
|
||||
if (ImGui.Begin(
|
||||
$"Actor{i}##ActorWindow{i}",
|
||||
ImGuiWindowFlags.NoDecoration |
|
||||
ImGuiWindowFlags.AlwaysAutoResize |
|
||||
ImGuiWindowFlags.NoSavedSettings |
|
||||
ImGuiWindowFlags.NoMove |
|
||||
ImGuiWindowFlags.NoMouseInputs |
|
||||
ImGuiWindowFlags.NoDocking |
|
||||
ImGuiWindowFlags.NoFocusOnAppearing |
|
||||
ImGuiWindowFlags.NoNav))
|
||||
ImGui.Text(objectText);
|
||||
ImGui.End();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
using Dalamud.Game.ClientState.Party;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying information about the current party.
|
||||
/// </summary>
|
||||
internal class PartyListWidget : IDataWindowWidget
|
||||
{
|
||||
private bool resolveGameData;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Party_List;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
var partyList = Service<PartyList>.Get();
|
||||
|
||||
ImGui.Checkbox("Resolve GameData", ref this.resolveGameData);
|
||||
|
||||
ImGui.Text($"GroupManager: {partyList.GroupManagerAddress.ToInt64():X}");
|
||||
ImGui.Text($"GroupList: {partyList.GroupListAddress.ToInt64():X}");
|
||||
ImGui.Text($"AllianceList: {partyList.AllianceListAddress.ToInt64():X}");
|
||||
|
||||
ImGui.Text($"{partyList.Length} Members");
|
||||
|
||||
for (var i = 0; i < partyList.Length; i++)
|
||||
{
|
||||
var member = partyList[i];
|
||||
if (member == null)
|
||||
{
|
||||
ImGui.Text($"[{i}] was null");
|
||||
continue;
|
||||
}
|
||||
|
||||
ImGui.Text($"[{i}] {member.Address.ToInt64():X} - {member.Name} - {member.GameObject?.ObjectId}");
|
||||
if (this.resolveGameData)
|
||||
{
|
||||
var actor = member.GameObject;
|
||||
if (actor == null)
|
||||
{
|
||||
ImGui.Text("Actor was null");
|
||||
}
|
||||
else
|
||||
{
|
||||
Util.PrintGameObject(actor, "-", this.resolveGameData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
using System;
|
||||
|
||||
using Dalamud.Plugin.Ipc;
|
||||
using Dalamud.Plugin.Ipc.Internal;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for testing plugin IPC systems.
|
||||
/// </summary>
|
||||
internal class PluginIpcWidget : IDataWindowWidget
|
||||
{
|
||||
// IPC
|
||||
private ICallGateProvider<string, string>? ipcPub;
|
||||
private ICallGateSubscriber<string, string>? ipcSub;
|
||||
private string callGateResponse = string.Empty;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Plugin_IPC;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
if (this.ipcPub == null)
|
||||
{
|
||||
this.ipcPub = new CallGatePubSub<string, string>("dataDemo1");
|
||||
|
||||
this.ipcPub.RegisterAction(msg =>
|
||||
{
|
||||
Log.Information("Data action was called: {Msg}", msg);
|
||||
});
|
||||
|
||||
this.ipcPub.RegisterFunc(msg =>
|
||||
{
|
||||
Log.Information("Data func was called: {Msg}", msg);
|
||||
return Guid.NewGuid().ToString();
|
||||
});
|
||||
}
|
||||
|
||||
if (this.ipcSub == null)
|
||||
{
|
||||
this.ipcSub = new CallGatePubSub<string, string>("dataDemo1");
|
||||
this.ipcSub.Subscribe(_ =>
|
||||
{
|
||||
Log.Information("PONG1");
|
||||
});
|
||||
this.ipcSub.Subscribe(_ =>
|
||||
{
|
||||
Log.Information("PONG2");
|
||||
});
|
||||
this.ipcSub.Subscribe(_ => throw new Exception("PONG3"));
|
||||
}
|
||||
|
||||
if (ImGui.Button("PING"))
|
||||
{
|
||||
this.ipcPub.SendMessage("PING");
|
||||
}
|
||||
|
||||
if (ImGui.Button("Action"))
|
||||
{
|
||||
this.ipcSub.InvokeAction("button1");
|
||||
}
|
||||
|
||||
if (ImGui.Button("Func"))
|
||||
{
|
||||
this.callGateResponse = this.ipcSub.InvokeFunc("button2");
|
||||
}
|
||||
|
||||
if (!this.callGateResponse.IsNullOrEmpty())
|
||||
ImGui.Text($"Response: {this.callGateResponse}");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
using Dalamud.Game.Text;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying test data for SE Font Symbols.
|
||||
/// </summary>
|
||||
internal class SeFontTestWidget : IDataWindowWidget
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.SE_Font_Test;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
var specialChars = string.Empty;
|
||||
|
||||
for (var i = 0xE020; i <= 0xE0DB; i++)
|
||||
specialChars += $"0x{i:X} - {(SeIconChar)i} - {(char)i}\n";
|
||||
|
||||
ImGui.TextUnformatted(specialChars);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
using Dalamud.Data;
|
||||
using ImGuiNET;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget to display the currently set server opcodes.
|
||||
/// </summary>
|
||||
internal class ServerOpcodeWidget : IDataWindowWidget
|
||||
{
|
||||
private string? serverOpString;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Server_OpCode;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
var dataManager = Service<DataManager>.Get();
|
||||
|
||||
if (dataManager.IsDataReady)
|
||||
{
|
||||
this.serverOpString = JsonConvert.SerializeObject(dataManager.ServerOpCodes, Formatting.Indented);
|
||||
this.Ready = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
ImGui.TextUnformatted(this.serverOpString ?? "serverOpString not initialized");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
using ImGuiNET;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying start info.
|
||||
/// </summary>
|
||||
internal class StartInfoWidget : IDataWindowWidget
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.StartInfo;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
var startInfo = Service<DalamudStartInfo>.Get();
|
||||
|
||||
ImGui.Text(JsonConvert.SerializeObject(startInfo, Formatting.Indented));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying target info.
|
||||
/// </summary>
|
||||
internal class TargetWidget : IDataWindowWidget
|
||||
{
|
||||
private bool resolveGameData;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Target;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
ImGui.Checkbox("Resolve GameData", ref this.resolveGameData);
|
||||
|
||||
var clientState = Service<ClientState>.Get();
|
||||
var targetMgr = Service<TargetManager>.Get();
|
||||
|
||||
if (targetMgr.Target != null)
|
||||
{
|
||||
Util.PrintGameObject(targetMgr.Target, "CurrentTarget", this.resolveGameData);
|
||||
|
||||
ImGui.Text("Target");
|
||||
Util.ShowGameObjectStruct(targetMgr.Target);
|
||||
|
||||
var tot = targetMgr.Target.TargetObject;
|
||||
if (tot != null)
|
||||
{
|
||||
ImGuiHelpers.ScaledDummy(10);
|
||||
|
||||
ImGui.Separator();
|
||||
ImGui.Text("ToT");
|
||||
Util.ShowGameObjectStruct(tot);
|
||||
}
|
||||
|
||||
ImGuiHelpers.ScaledDummy(10);
|
||||
}
|
||||
|
||||
if (targetMgr.FocusTarget != null)
|
||||
Util.PrintGameObject(targetMgr.FocusTarget, "FocusTarget", this.resolveGameData);
|
||||
|
||||
if (targetMgr.MouseOverTarget != null)
|
||||
Util.PrintGameObject(targetMgr.MouseOverTarget, "MouseOverTarget", this.resolveGameData);
|
||||
|
||||
if (targetMgr.PreviousTarget != null)
|
||||
Util.PrintGameObject(targetMgr.PreviousTarget, "PreviousTarget", this.resolveGameData);
|
||||
|
||||
if (targetMgr.SoftTarget != null)
|
||||
Util.PrintGameObject(targetMgr.SoftTarget, "SoftTarget", this.resolveGameData);
|
||||
|
||||
if (ImGui.Button("Clear CT"))
|
||||
targetMgr.ClearTarget();
|
||||
|
||||
if (ImGui.Button("Clear FT"))
|
||||
targetMgr.ClearFocusTarget();
|
||||
|
||||
var localPlayer = clientState.LocalPlayer;
|
||||
|
||||
if (localPlayer != null)
|
||||
{
|
||||
if (ImGui.Button("Set CT"))
|
||||
targetMgr.SetTarget(localPlayer);
|
||||
|
||||
if (ImGui.Button("Set FT"))
|
||||
targetMgr.SetFocusTarget(localPlayer);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.Text("LocalPlayer is null.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
// ReSharper disable MethodSupportsCancellation // Using alternative method of cancelling tasks by throwing exceptions.
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Dalamud.Game;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Logging.Internal;
|
||||
using ImGuiNET;
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying task scheduler test.
|
||||
/// </summary>
|
||||
internal class TaskSchedulerWidget : IDataWindowWidget
|
||||
{
|
||||
private CancellationTokenSource taskSchedulerCancelSource = new();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.TaskSched;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
if (ImGui.Button("Clear list"))
|
||||
{
|
||||
TaskTracker.Clear();
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGuiHelpers.ScaledDummy(10);
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.Button("Cancel using CancellationTokenSource"))
|
||||
{
|
||||
this.taskSchedulerCancelSource.Cancel();
|
||||
this.taskSchedulerCancelSource = new();
|
||||
}
|
||||
|
||||
ImGui.Text("Run in any thread: ");
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.Button("Short Task.Run"))
|
||||
{
|
||||
Task.Run(() => { Thread.Sleep(500); });
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.Button("Task in task(Delay)"))
|
||||
{
|
||||
var token = this.taskSchedulerCancelSource.Token;
|
||||
Task.Run(async () => await this.TestTaskInTaskDelay(token), token);
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.Button("Task in task(Sleep)"))
|
||||
{
|
||||
Task.Run(async () => await this.TestTaskInTaskSleep());
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.Button("Faulting task"))
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
Thread.Sleep(200);
|
||||
|
||||
string a = null;
|
||||
a.Contains("dalamud"); // Intentional null exception.
|
||||
});
|
||||
}
|
||||
|
||||
ImGui.Text("Run in Framework.Update: ");
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.Button("ASAP"))
|
||||
{
|
||||
Task.Run(async () => await Service<Framework>.Get().RunOnTick(() => { }, cancellationToken: this.taskSchedulerCancelSource.Token));
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.Button("In 1s"))
|
||||
{
|
||||
Task.Run(async () => await Service<Framework>.Get().RunOnTick(() => { }, cancellationToken: this.taskSchedulerCancelSource.Token, delay: TimeSpan.FromSeconds(1)));
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.Button("In 60f"))
|
||||
{
|
||||
Task.Run(async () => await Service<Framework>.Get().RunOnTick(() => { }, cancellationToken: this.taskSchedulerCancelSource.Token, delayTicks: 60));
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.Button("Error in 1s"))
|
||||
{
|
||||
Task.Run(async () => await Service<Framework>.Get().RunOnTick(() => throw new Exception("Test Exception"), cancellationToken: this.taskSchedulerCancelSource.Token, delay: TimeSpan.FromSeconds(1)));
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.Button("As long as it's in Framework Thread"))
|
||||
{
|
||||
Task.Run(async () => await Service<Framework>.Get().RunOnFrameworkThread(() => { Log.Information("Task dispatched from non-framework.update thread"); }));
|
||||
Service<Framework>.Get().RunOnFrameworkThread(() => { Log.Information("Task dispatched from framework.update thread"); }).Wait();
|
||||
}
|
||||
|
||||
if (ImGui.Button("Drown in tasks"))
|
||||
{
|
||||
var token = this.taskSchedulerCancelSource.Token;
|
||||
Task.Run(
|
||||
() =>
|
||||
{
|
||||
for (var i = 0; i < 100; i++)
|
||||
{
|
||||
token.ThrowIfCancellationRequested();
|
||||
Task.Run(
|
||||
() =>
|
||||
{
|
||||
for (var j = 0; j < 100; j++)
|
||||
{
|
||||
token.ThrowIfCancellationRequested();
|
||||
Task.Run(
|
||||
() =>
|
||||
{
|
||||
for (var k = 0; k < 100; k++)
|
||||
{
|
||||
token.ThrowIfCancellationRequested();
|
||||
Task.Run(
|
||||
() =>
|
||||
{
|
||||
for (var l = 0; l < 100; l++)
|
||||
{
|
||||
token.ThrowIfCancellationRequested();
|
||||
Task.Run(
|
||||
async () =>
|
||||
{
|
||||
for (var m = 0; m < 100; m++)
|
||||
{
|
||||
token.ThrowIfCancellationRequested();
|
||||
await Task.Delay(1, token);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
ImGuiHelpers.ScaledDummy(20);
|
||||
|
||||
// Needed to init the task tracker, if we're not on a debug build
|
||||
Service<TaskTracker>.Get().Enable();
|
||||
|
||||
for (var i = 0; i < TaskTracker.Tasks.Count; i++)
|
||||
{
|
||||
var task = TaskTracker.Tasks[i];
|
||||
var subTime = DateTime.Now;
|
||||
if (task.Task == null)
|
||||
subTime = task.FinishTime;
|
||||
|
||||
switch (task.Status)
|
||||
{
|
||||
case TaskStatus.Created:
|
||||
case TaskStatus.WaitingForActivation:
|
||||
case TaskStatus.WaitingToRun:
|
||||
ImGui.PushStyleColor(ImGuiCol.Header, ImGuiColors.DalamudGrey);
|
||||
break;
|
||||
case TaskStatus.Running:
|
||||
case TaskStatus.WaitingForChildrenToComplete:
|
||||
ImGui.PushStyleColor(ImGuiCol.Header, ImGuiColors.ParsedBlue);
|
||||
break;
|
||||
case TaskStatus.RanToCompletion:
|
||||
ImGui.PushStyleColor(ImGuiCol.Header, ImGuiColors.ParsedGreen);
|
||||
break;
|
||||
case TaskStatus.Canceled:
|
||||
case TaskStatus.Faulted:
|
||||
ImGui.PushStyleColor(ImGuiCol.Header, ImGuiColors.DalamudRed);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
if (ImGui.CollapsingHeader($"#{task.Id} - {task.Status} {(subTime - task.StartTime).TotalMilliseconds}ms###task{i}"))
|
||||
{
|
||||
task.IsBeingViewed = true;
|
||||
|
||||
if (ImGui.Button("CANCEL (May not work)"))
|
||||
{
|
||||
try
|
||||
{
|
||||
var cancelFunc =
|
||||
typeof(Task).GetMethod("InternalCancel", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
cancelFunc?.Invoke(task, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Could not cancel task");
|
||||
}
|
||||
}
|
||||
|
||||
ImGuiHelpers.ScaledDummy(10);
|
||||
|
||||
ImGui.TextUnformatted(task.StackTrace?.ToString());
|
||||
|
||||
if (task.Exception != null)
|
||||
{
|
||||
ImGuiHelpers.ScaledDummy(15);
|
||||
ImGui.TextColored(ImGuiColors.DalamudRed, "EXCEPTION:");
|
||||
ImGui.TextUnformatted(task.Exception.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
task.IsBeingViewed = false;
|
||||
}
|
||||
|
||||
ImGui.PopStyleColor(1);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task TestTaskInTaskDelay(CancellationToken token)
|
||||
{
|
||||
await Task.Delay(5000, token);
|
||||
}
|
||||
|
||||
#pragma warning disable 1998
|
||||
private async Task TestTaskInTaskSleep()
|
||||
#pragma warning restore 1998
|
||||
{
|
||||
Thread.Sleep(5000);
|
||||
}
|
||||
}
|
||||
69
Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs
Normal file
69
Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
using Dalamud.Data;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
using ImGuiScene;
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying texture test.
|
||||
/// </summary>
|
||||
internal class TexWidget : IDataWindowWidget
|
||||
{
|
||||
private string inputTexPath = string.Empty;
|
||||
private TextureWrap? debugTex;
|
||||
private Vector2 inputTexUv0 = Vector2.Zero;
|
||||
private Vector2 inputTexUv1 = Vector2.One;
|
||||
private Vector4 inputTintCol = Vector4.One;
|
||||
private Vector2 inputTexScale = Vector2.Zero;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Tex;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
var dataManager = Service<DataManager>.Get();
|
||||
|
||||
ImGui.InputText("Tex Path", ref this.inputTexPath, 255);
|
||||
ImGui.InputFloat2("UV0", ref this.inputTexUv0);
|
||||
ImGui.InputFloat2("UV1", ref this.inputTexUv1);
|
||||
ImGui.InputFloat4("Tint", ref this.inputTintCol);
|
||||
ImGui.InputFloat2("Scale", ref this.inputTexScale);
|
||||
|
||||
if (ImGui.Button("Load Tex"))
|
||||
{
|
||||
try
|
||||
{
|
||||
this.debugTex = dataManager.GetImGuiTexture(this.inputTexPath);
|
||||
this.inputTexScale = new Vector2(this.debugTex?.Width ?? 0, this.debugTex?.Height ?? 0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Could not load tex");
|
||||
}
|
||||
}
|
||||
|
||||
ImGuiHelpers.ScaledDummy(10);
|
||||
|
||||
if (this.debugTex != null)
|
||||
{
|
||||
ImGui.Image(this.debugTex.ImGuiHandle, this.inputTexScale, this.inputTexUv0, this.inputTexUv1, this.inputTintCol);
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
Util.ShowObject(this.debugTex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
using System.Numerics;
|
||||
|
||||
using Dalamud.Game.Gui.Toast;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying toast test.
|
||||
/// </summary>
|
||||
internal class ToastWidget : IDataWindowWidget
|
||||
{
|
||||
private string inputTextToast = string.Empty;
|
||||
private int toastPosition;
|
||||
private int toastSpeed;
|
||||
private int questToastPosition;
|
||||
private bool questToastSound;
|
||||
private int questToastIconId;
|
||||
private bool questToastCheckmark;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.Toast;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
var toastGui = Service<ToastGui>.Get();
|
||||
|
||||
ImGui.InputText("Toast text", ref this.inputTextToast, 200);
|
||||
|
||||
ImGui.Combo("Toast Position", ref this.toastPosition, new[] { "Bottom", "Top", }, 2);
|
||||
ImGui.Combo("Toast Speed", ref this.toastSpeed, new[] { "Slow", "Fast", }, 2);
|
||||
ImGui.Combo("Quest Toast Position", ref this.questToastPosition, new[] { "Centre", "Right", "Left" }, 3);
|
||||
ImGui.Checkbox("Quest Checkmark", ref this.questToastCheckmark);
|
||||
ImGui.Checkbox("Quest Play Sound", ref this.questToastSound);
|
||||
ImGui.InputInt("Quest Icon ID", ref this.questToastIconId);
|
||||
|
||||
ImGuiHelpers.ScaledDummy(new Vector2(10, 10));
|
||||
|
||||
if (ImGui.Button("Show toast"))
|
||||
{
|
||||
toastGui.ShowNormal(this.inputTextToast, new ToastOptions
|
||||
{
|
||||
Position = (ToastPosition)this.toastPosition,
|
||||
Speed = (ToastSpeed)this.toastSpeed,
|
||||
});
|
||||
}
|
||||
|
||||
if (ImGui.Button("Show Quest toast"))
|
||||
{
|
||||
toastGui.ShowQuest(this.inputTextToast, new QuestToastOptions
|
||||
{
|
||||
Position = (QuestToastPosition)this.questToastPosition,
|
||||
DisplayCheckmark = this.questToastCheckmark,
|
||||
IconId = (uint)this.questToastIconId,
|
||||
PlaySound = this.questToastSound,
|
||||
});
|
||||
}
|
||||
|
||||
if (ImGui.Button("Show Error toast"))
|
||||
{
|
||||
toastGui.ShowError(this.inputTextToast);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
using System.Numerics;
|
||||
|
||||
using Dalamud.Data;
|
||||
using ImGuiNET;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Widget for displaying all UI Colors from Lumina.
|
||||
/// </summary>
|
||||
internal class UIColorWidget : IDataWindowWidget
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public DataKind DataKind { get; init; } = DataKind.UIColor;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
this.Ready = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
var colorSheet = Service<DataManager>.Get().GetExcelSheet<UIColor>();
|
||||
if (colorSheet is null) return;
|
||||
|
||||
foreach (var color in colorSheet)
|
||||
{
|
||||
this.DrawUiColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawUiColor(UIColor color)
|
||||
{
|
||||
ImGui.Text($"[{color.RowId:D3}] ");
|
||||
ImGui.SameLine();
|
||||
ImGui.TextColored(this.ConvertToVector4(color.Unknown2), $"Unknown2 ");
|
||||
ImGui.SameLine();
|
||||
ImGui.TextColored(this.ConvertToVector4(color.UIForeground), "UIForeground ");
|
||||
ImGui.SameLine();
|
||||
ImGui.TextColored(this.ConvertToVector4(color.Unknown3), "Unknown3 ");
|
||||
ImGui.SameLine();
|
||||
ImGui.TextColored(this.ConvertToVector4(color.UIGlow), "UIGlow");
|
||||
}
|
||||
|
||||
private Vector4 ConvertToVector4(uint color)
|
||||
{
|
||||
var r = (byte)(color >> 24);
|
||||
var g = (byte)(color >> 16);
|
||||
var b = (byte)(color >> 8);
|
||||
var a = (byte)color;
|
||||
|
||||
return new Vector4(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -13,6 +13,7 @@ using System.Text;
|
|||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Data;
|
||||
using Dalamud.Game;
|
||||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Colors;
|
||||
|
|
@ -672,6 +673,40 @@ public static class Util
|
|||
return names.ElementAt(rng.Next(0, names.Count() - 1)).Singular.RawString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Print formatted GameObject Information to ImGui
|
||||
/// </summary>
|
||||
/// <param name="actor">Game Object to Display.</param>
|
||||
/// <param name="tag">Display Tag.</param>
|
||||
/// <param name="resolveGameData">If the GameObjects data should be resolved.</param>
|
||||
internal static void PrintGameObject(GameObject actor, string tag, bool resolveGameData)
|
||||
{
|
||||
var actorString =
|
||||
$"{actor.Address.ToInt64():X}:{actor.ObjectId:X}[{tag}] - {actor.ObjectKind} - {actor.Name} - X{actor.Position.X} Y{actor.Position.Y} Z{actor.Position.Z} D{actor.YalmDistanceX} R{actor.Rotation} - Target: {actor.TargetObjectId:X}\n";
|
||||
|
||||
if (actor is Npc npc)
|
||||
actorString += $" DataId: {npc.DataId} NameId:{npc.NameId}\n";
|
||||
|
||||
if (actor is Character chara)
|
||||
{
|
||||
actorString +=
|
||||
$" Level: {chara.Level} ClassJob: {(resolveGameData ? chara.ClassJob.GameData?.Name : chara.ClassJob.Id.ToString())} CHP: {chara.CurrentHp} MHP: {chara.MaxHp} CMP: {chara.CurrentMp} MMP: {chara.MaxMp}\n Customize: {BitConverter.ToString(chara.Customize).Replace("-", " ")} StatusFlags: {chara.StatusFlags}\n";
|
||||
}
|
||||
|
||||
if (actor is PlayerCharacter pc)
|
||||
{
|
||||
actorString +=
|
||||
$" HomeWorld: {(resolveGameData ? pc.HomeWorld.GameData?.Name : pc.HomeWorld.Id.ToString())} CurrentWorld: {(resolveGameData ? pc.CurrentWorld.GameData?.Name : pc.CurrentWorld.Id.ToString())} FC: {pc.CompanyTag}\n";
|
||||
}
|
||||
|
||||
ImGui.TextUnformatted(actorString);
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button($"C##{actor.Address.ToInt64()}"))
|
||||
{
|
||||
ImGui.SetClipboardText(actor.Address.ToInt64().ToString("X"));
|
||||
}
|
||||
}
|
||||
|
||||
private static unsafe void ShowValue(ulong addr, IEnumerable<string> path, Type type, object value)
|
||||
{
|
||||
if (type.IsPointer)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue