mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-15 05:04:15 +01:00
Merge branch 'master' of https://github.com/goatcorp/Dalamud
This commit is contained in:
commit
f4f86d3030
10 changed files with 308 additions and 60 deletions
|
|
@ -153,6 +153,19 @@ namespace Dalamud
|
|||
Service<NetworkHandlers>.Set();
|
||||
Log.Information("[T2] NH OK!");
|
||||
|
||||
try
|
||||
{
|
||||
Service<DataManager>.Set().Initialize(this.AssetDirectory.FullName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e, "Could not initialize DataManager.");
|
||||
this.Unload();
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Information("[T2] Data OK!");
|
||||
|
||||
var clientState = Service<ClientState>.Set();
|
||||
Log.Information("[T2] CS OK!");
|
||||
|
||||
|
|
@ -192,19 +205,6 @@ namespace Dalamud
|
|||
Log.Information(e, "Could not init IME.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Service<DataManager>.Set().Initialize(this.AssetDirectory.FullName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e, "Could not initialize DataManager.");
|
||||
this.Unload();
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Information("[T2] Data OK!");
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
Service<SeStringManager>.Set();
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ namespace Dalamud.Game.ClientState
|
|||
/// </summary>
|
||||
public void Enable()
|
||||
{
|
||||
Service<Condition>.Get().Enable();
|
||||
Service<GamepadState>.Get().Enable();
|
||||
this.setupTerritoryTypeHook.Enable();
|
||||
}
|
||||
|
|
@ -135,6 +136,7 @@ namespace Dalamud.Game.ClientState
|
|||
public void Dispose()
|
||||
{
|
||||
this.setupTerritoryTypeHook.Dispose();
|
||||
Service<Condition>.Get().Dispose();
|
||||
Service<GamepadState>.Get().Dispose();
|
||||
Service<Framework>.Get().Update -= this.FrameworkOnOnUpdateEvent;
|
||||
Service<NetworkHandlers>.Get().CfPop -= this.NetworkHandlersOnCfPop;
|
||||
|
|
|
|||
|
|
@ -47,6 +47,11 @@ namespace Dalamud.Game.ClientState
|
|||
/// </summary>
|
||||
public IntPtr KeyboardState { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the keyboard state index array which translates the VK enumeration to the key state.
|
||||
/// </summary>
|
||||
public IntPtr KeyboardStateIndexArray { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the target manager.
|
||||
/// </summary>
|
||||
|
|
@ -93,9 +98,11 @@ namespace Dalamud.Game.ClientState
|
|||
|
||||
this.SetupTerritoryType = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B F9 66 89 91 ?? ?? ?? ??");
|
||||
|
||||
// This resolves to a fixed offset only, without the base address added in,
|
||||
// so GetStaticAddressFromSig() can't be used. lea rcx, ds:1DB9F74h[rax*4]
|
||||
// These resolve to fixed offsets only, without the base address added in, so GetStaticAddressFromSig() can't be used.
|
||||
// lea rcx, ds:1DB9F74h[rax*4] KeyboardState
|
||||
// movzx edx, byte ptr [rbx+rsi+1D5E0E0h] KeyboardStateIndexArray
|
||||
this.KeyboardState = sig.ScanText("48 8D 0C 85 ?? ?? ?? ?? 8B 04 31 85 C2 0F 85") + 0x4;
|
||||
this.KeyboardStateIndexArray = sig.ScanText("0F B6 94 33 ?? ?? ?? ?? 84 D2") + 0x4;
|
||||
|
||||
this.ConditionFlags = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? BA ?? ?? ?? ?? E8 ?? ?? ?? ?? B0 01 48 83 C4 30");
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System;
|
|||
|
||||
using Dalamud.IoC;
|
||||
using Dalamud.IoC.Internal;
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Game.ClientState.Conditions
|
||||
{
|
||||
|
|
@ -10,45 +11,61 @@ namespace Dalamud.Game.ClientState.Conditions
|
|||
/// </summary>
|
||||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
public class Condition
|
||||
public sealed partial class Condition
|
||||
{
|
||||
/// <summary>
|
||||
/// The current max number of conditions. You can get this just by looking at the condition sheet and how many rows it has.
|
||||
/// </summary>
|
||||
public const int MaxConditionEntries = 100;
|
||||
|
||||
private readonly bool[] cache = new bool[MaxConditionEntries];
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Condition"/> class.
|
||||
/// </summary>
|
||||
/// <param name="resolver">The ClientStateAddressResolver instance.</param>
|
||||
internal Condition(ClientStateAddressResolver resolver)
|
||||
{
|
||||
this.ConditionArrayBase = resolver.ConditionFlags;
|
||||
this.Address = resolver.ConditionFlags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the condition array base pointer.
|
||||
/// Would typically be private but is used in /xldata windows.
|
||||
/// A delegate type used with the <see cref="ConditionChange"/> event.
|
||||
/// </summary>
|
||||
internal IntPtr ConditionArrayBase { get; private set; }
|
||||
/// <param name="flag">The changed condition.</param>
|
||||
/// <param name="value">The value the condition is set to.</param>
|
||||
public delegate void ConditionChangeDelegate(ConditionFlag flag, bool value);
|
||||
|
||||
/// <summary>
|
||||
/// Event that gets fired when a condition is set.
|
||||
/// Should only get fired for actual changes, so the previous value will always be !value.
|
||||
/// </summary>
|
||||
public event ConditionChangeDelegate? ConditionChange;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the condition array base pointer.
|
||||
/// </summary>
|
||||
public IntPtr Address { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Check the value of a specific condition/state flag.
|
||||
/// </summary>
|
||||
/// <param name="flag">The condition flag to check.</param>
|
||||
public unsafe bool this[ConditionFlag flag]
|
||||
public unsafe bool this[int flag]
|
||||
{
|
||||
get
|
||||
{
|
||||
var idx = (int)flag;
|
||||
|
||||
if (idx < 0 || idx >= MaxConditionEntries)
|
||||
if (flag < 0 || flag >= MaxConditionEntries)
|
||||
return false;
|
||||
|
||||
return *(bool*)(this.ConditionArrayBase + idx);
|
||||
return *(bool*)(this.Address + flag);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="this[int]"/>
|
||||
public unsafe bool this[ConditionFlag flag]
|
||||
=> this[(int)flag];
|
||||
|
||||
/// <summary>
|
||||
/// Check if any condition flags are set.
|
||||
/// </summary>
|
||||
|
|
@ -57,8 +74,7 @@ namespace Dalamud.Game.ClientState.Conditions
|
|||
{
|
||||
for (var i = 0; i < MaxConditionEntries; i++)
|
||||
{
|
||||
var typedCondition = (ConditionFlag)i;
|
||||
var cond = this[typedCondition];
|
||||
var cond = this[i];
|
||||
|
||||
if (cond)
|
||||
return true;
|
||||
|
|
@ -66,5 +82,77 @@ namespace Dalamud.Game.ClientState.Conditions
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables the hooks of the Condition class function.
|
||||
/// </summary>
|
||||
public void Enable()
|
||||
{
|
||||
// Initialization
|
||||
for (var i = 0; i < MaxConditionEntries; i++)
|
||||
this.cache[i] = this[i];
|
||||
|
||||
Service<Framework>.Get().Update += this.FrameworkUpdate;
|
||||
}
|
||||
|
||||
private void FrameworkUpdate(Framework framework)
|
||||
{
|
||||
for (var i = 0; i < MaxConditionEntries; i++)
|
||||
{
|
||||
var value = this[i];
|
||||
|
||||
if (value != this.cache[i])
|
||||
{
|
||||
this.cache[i] = value;
|
||||
|
||||
try
|
||||
{
|
||||
this.ConditionChange?.Invoke((ConditionFlag)i, value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"While invoking {nameof(this.ConditionChange)}, an exception was thrown.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to conditions (generally player state). You can check whether a player is in combat, mounted, etc.
|
||||
/// </summary>
|
||||
public sealed partial class Condition : IDisposable
|
||||
{
|
||||
private bool isDisposed;
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="Condition" /> class.
|
||||
/// </summary>
|
||||
~Condition()
|
||||
{
|
||||
this.Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes this instance, alongside its hooks.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
this.Dispose(true);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (this.isDisposed)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
Service<Framework>.Get().Update -= this.FrameworkUpdate;
|
||||
}
|
||||
|
||||
this.isDisposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Dalamud.IoC;
|
||||
|
|
@ -10,6 +11,15 @@ namespace Dalamud.Game.ClientState.Keys
|
|||
/// <summary>
|
||||
/// Wrapper around the game keystate buffer, which contains the pressed state for all keyboard keys, indexed by virtual vkCode.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The stored key state is actually a combination field, however the below ephemeral states are consumed each frame. Setting
|
||||
/// the value may be mildly useful, however retrieving the value is largely pointless. In testing, it wasn't possible without
|
||||
/// setting the statue manually.
|
||||
/// index & 0 = key pressed.
|
||||
/// index & 1 = key down (ephemeral).
|
||||
/// index & 2 = key up (ephemeral).
|
||||
/// index & 3 = short key press (ephemeral).
|
||||
/// </remarks>
|
||||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
public class KeyState
|
||||
|
|
@ -18,7 +28,9 @@ namespace Dalamud.Game.ClientState.Keys
|
|||
// but there is other state data past this point, and keys beyond here aren't
|
||||
// generally valid for most things anyway
|
||||
private const int MaxKeyCodeIndex = 0xA0;
|
||||
private IntPtr bufferBase;
|
||||
private readonly IntPtr bufferBase;
|
||||
private readonly IntPtr indexBase;
|
||||
private VirtualKey[] validVirtualKeyCache = null;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="KeyState"/> class.
|
||||
|
|
@ -29,40 +41,81 @@ namespace Dalamud.Game.ClientState.Keys
|
|||
var moduleBaseAddress = Service<SigScanner>.Get().Module.BaseAddress;
|
||||
|
||||
this.bufferBase = moduleBaseAddress + Marshal.ReadInt32(addressResolver.KeyboardState);
|
||||
this.indexBase = moduleBaseAddress + Marshal.ReadInt32(addressResolver.KeyboardStateIndexArray);
|
||||
|
||||
Log.Verbose($"Keyboard state buffer address 0x{this.bufferBase.ToInt64():X}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get or set the keypressed state for a given vkCode.
|
||||
/// Get or set the key-pressed state for a given vkCode.
|
||||
/// </summary>
|
||||
/// <param name="vkCode">The virtual key to change.</param>
|
||||
/// <returns>Whether the specified key is currently pressed.</returns>
|
||||
public bool this[int vkCode]
|
||||
/// <exception cref="ArgumentException">If the vkCode is not valid. Refer to <see cref="IsVirtualKeyValid(int)"/> or <see cref="GetValidVirtualKeys"/>.</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">If the set value is non-zero.</exception>
|
||||
public unsafe bool this[int vkCode]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (vkCode < 0 || vkCode > MaxKeyCodeIndex)
|
||||
throw new ArgumentException($"Keycode state only appears to be valid up to {MaxKeyCodeIndex}");
|
||||
get => this.GetRawValue(vkCode) != 0;
|
||||
set => this.SetRawValue(vkCode, value ? 1 : 0);
|
||||
}
|
||||
|
||||
return Marshal.ReadInt32(this.bufferBase + (4 * vkCode)) != 0;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (vkCode < 0 || vkCode > MaxKeyCodeIndex)
|
||||
throw new ArgumentException($"Keycode state only appears to be valid up to {MaxKeyCodeIndex}");
|
||||
|
||||
Marshal.WriteInt32(this.bufferBase + (4 * vkCode), value ? 1 : 0);
|
||||
}
|
||||
/// <inheritdoc cref="this[int]"/>
|
||||
public bool this[VirtualKey vkCode]
|
||||
{
|
||||
get => this[(int)vkCode];
|
||||
set => this[(int)vkCode] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get or set the keypressed state for a given VirtualKey enum.
|
||||
/// Gets the value in the index array.
|
||||
/// </summary>
|
||||
/// <param name="vk">The virtual key to change.</param>
|
||||
/// <returns>Whether the specified key is currently pressed.</returns>
|
||||
public bool this[VirtualKey vk] => this[(int)vk];
|
||||
/// <param name="vkCode">The virtual key to change.</param>
|
||||
/// <returns>The raw value stored in the index array.</returns>
|
||||
/// <exception cref="ArgumentException">If the vkCode is not valid. Refer to <see cref="IsVirtualKeyValid(int)"/> or <see cref="GetValidVirtualKeys"/>.</exception>
|
||||
public int GetRawValue(int vkCode)
|
||||
=> this.GetRefValue(vkCode);
|
||||
|
||||
/// <inheritdoc cref="GetRawValue(int)"/>
|
||||
public int GetRawValue(VirtualKey vkCode)
|
||||
=> this.GetRawValue((int)vkCode);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value in the index array.
|
||||
/// </summary>
|
||||
/// <param name="vkCode">The virtual key to change.</param>
|
||||
/// <param name="value">The raw value to set in the index array.</param>
|
||||
/// <exception cref="ArgumentException">If the vkCode is not valid. Refer to <see cref="IsVirtualKeyValid(int)"/> or <see cref="GetValidVirtualKeys"/>.</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">If the set value is non-zero.</exception>
|
||||
public void SetRawValue(int vkCode, int value)
|
||||
{
|
||||
if (value != 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(value), "Dalamud does not support pressing keys, only preventing them via zero or False. If you have a valid use-case for this, please contact the dev team.");
|
||||
|
||||
this.GetRefValue(vkCode) = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="SetRawValue(int, int)"/>
|
||||
public void SetRawValue(VirtualKey vkCode, int value)
|
||||
=> this.SetRawValue((int)vkCode, value);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the given VirtualKey code is regarded as valid input by the game.
|
||||
/// </summary>
|
||||
/// <param name="vkCode">Virtual key code.</param>
|
||||
/// <returns>If the code is valid.</returns>
|
||||
public bool IsVirtualKeyValid(int vkCode)
|
||||
=> vkCode > 0 && vkCode < MaxKeyCodeIndex && this.ConvertVirtualKey(vkCode) != 0;
|
||||
|
||||
/// <inheritdoc cref="IsVirtualKeyValid(int)"/>
|
||||
public bool IsVirtualKeyValid(VirtualKey vkCode)
|
||||
=> this.IsVirtualKeyValid((int)vkCode);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an array of virtual keys the game considers valid input.
|
||||
/// </summary>
|
||||
/// <returns>An array of valid virtual keys.</returns>
|
||||
public VirtualKey[] GetValidVirtualKeys()
|
||||
=> this.validVirtualKeyCache ??= Enum.GetValues<VirtualKey>().Where(vk => this.IsVirtualKeyValid(vk)).ToArray();
|
||||
|
||||
/// <summary>
|
||||
/// Clears the pressed state for all keys.
|
||||
|
|
@ -71,8 +124,40 @@ namespace Dalamud.Game.ClientState.Keys
|
|||
{
|
||||
for (var i = 0; i < MaxKeyCodeIndex; i++)
|
||||
{
|
||||
Marshal.WriteInt32(this.bufferBase + (i * 4), 0);
|
||||
this.GetRefValue(i) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a virtual key into the equivalent value that the game uses.
|
||||
/// Valid values are non-zero.
|
||||
/// </summary>
|
||||
/// <param name="vkCode">Virtual key.</param>
|
||||
/// <returns>Converted value.</returns>
|
||||
private unsafe byte ConvertVirtualKey(int vkCode)
|
||||
{
|
||||
if (vkCode <= 0 || vkCode >= 240)
|
||||
return 0;
|
||||
|
||||
return *(byte*)(this.indexBase + vkCode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw value from the key state array.
|
||||
/// </summary>
|
||||
/// <param name="vkCode">Virtual key code.</param>
|
||||
/// <returns>A reference to the indexed array.</returns>
|
||||
private unsafe ref int GetRefValue(int vkCode)
|
||||
{
|
||||
if (vkCode < 0 || vkCode > MaxKeyCodeIndex)
|
||||
throw new ArgumentException($"Keycode state is only valid up to {MaxKeyCodeIndex}");
|
||||
|
||||
vkCode = this.ConvertVirtualKey(vkCode);
|
||||
|
||||
if (vkCode == 0)
|
||||
throw new ArgumentException($"Keycode state is only valid for certain values. Reference GetValidVirtualKeys for help.");
|
||||
|
||||
return ref *(int*)(this.bufferBase + (4 * vkCode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ namespace Dalamud.Game
|
|||
public sealed class Framework : IDisposable
|
||||
{
|
||||
private static Stopwatch statsStopwatch = new();
|
||||
private Stopwatch updateStopwatch = new();
|
||||
|
||||
private Hook<OnUpdateDetour> updateHook;
|
||||
private Hook<OnDestroyDetour> destroyHook;
|
||||
|
|
@ -92,6 +93,21 @@ namespace Dalamud.Game
|
|||
/// </summary>
|
||||
public FrameworkAddressResolver Address { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last time that the Framework Update event was triggered.
|
||||
/// </summary>
|
||||
public DateTime LastUpdate { get; private set; } = DateTime.MinValue;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last time in UTC that the Framework Update event was triggered.
|
||||
/// </summary>
|
||||
public DateTime LastUpdateUTC { get; private set; } = DateTime.MinValue;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the delta between the last Framework Update and the currently executing one.
|
||||
/// </summary>
|
||||
public TimeSpan UpdateDelta { get; private set; } = TimeSpan.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to dispatch update events.
|
||||
/// </summary>
|
||||
|
|
@ -127,6 +143,9 @@ namespace Dalamud.Game
|
|||
this.updateHook?.Dispose();
|
||||
this.destroyHook?.Dispose();
|
||||
this.realDestroyHook?.Dispose();
|
||||
|
||||
this.updateStopwatch.Reset();
|
||||
statsStopwatch.Reset();
|
||||
}
|
||||
|
||||
private void HookVTable()
|
||||
|
|
@ -173,6 +192,13 @@ namespace Dalamud.Game
|
|||
|
||||
if (this.DispatchUpdateEvents)
|
||||
{
|
||||
this.updateStopwatch.Stop();
|
||||
this.UpdateDelta = TimeSpan.FromMilliseconds(this.updateStopwatch.ElapsedMilliseconds);
|
||||
this.updateStopwatch.Restart();
|
||||
|
||||
this.LastUpdate = DateTime.Now;
|
||||
this.LastUpdateUTC = DateTime.UtcNow;
|
||||
|
||||
try
|
||||
{
|
||||
if (StatsEnabled && this.Update != null)
|
||||
|
|
@ -180,16 +206,23 @@ namespace Dalamud.Game
|
|||
// Stat Tracking for Framework Updates
|
||||
var invokeList = this.Update.GetInvocationList();
|
||||
var notUpdated = StatsHistory.Keys.ToList();
|
||||
|
||||
// Individually invoke OnUpdate handlers and time them.
|
||||
foreach (var d in invokeList)
|
||||
{
|
||||
statsStopwatch.Restart();
|
||||
d.Method.Invoke(d.Target, new object[] { this });
|
||||
statsStopwatch.Stop();
|
||||
|
||||
var key = $"{d.Target}::{d.Method.Name}";
|
||||
if (notUpdated.Contains(key)) notUpdated.Remove(key);
|
||||
if (!StatsHistory.ContainsKey(key)) StatsHistory.Add(key, new List<double>());
|
||||
if (notUpdated.Contains(key))
|
||||
notUpdated.Remove(key);
|
||||
|
||||
if (!StatsHistory.ContainsKey(key))
|
||||
StatsHistory.Add(key, new List<double>());
|
||||
|
||||
StatsHistory[key].Add(statsStopwatch.Elapsed.TotalMilliseconds);
|
||||
|
||||
if (StatsHistory[key].Count > 1000)
|
||||
{
|
||||
StatsHistory[key].RemoveRange(0, StatsHistory[key].Count - 1000);
|
||||
|
|
|
|||
|
|
@ -15,17 +15,17 @@ namespace Dalamud.Interface.Colors
|
|||
/// <summary>
|
||||
/// Gets grey used in dalamud.
|
||||
/// </summary>
|
||||
public static Vector4 DalamudGrey { get; } = new Vector4(0.70f, 0.70f, 0.70f, 1.00f);
|
||||
public static Vector4 DalamudGrey { get; } = new Vector4(0.7f, 0.7f, 0.7f, 1f);
|
||||
|
||||
/// <summary>
|
||||
/// Gets grey used in dalamud.
|
||||
/// </summary>
|
||||
public static Vector4 DalamudGrey2 { get; } = new Vector4(0.7f, 0.7f, 0.7f, 1.0f);
|
||||
public static Vector4 DalamudGrey2 { get; } = new Vector4(0.7f, 0.7f, 0.7f, 1f);
|
||||
|
||||
/// <summary>
|
||||
/// Gets grey used in dalamud.
|
||||
/// </summary>
|
||||
public static Vector4 DalamudGrey3 { get; } = new Vector4(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
public static Vector4 DalamudGrey3 { get; } = new Vector4(0.5f, 0.5f, 0.5f, 1f);
|
||||
|
||||
/// <summary>
|
||||
/// Gets white used in dalamud.
|
||||
|
|
@ -45,16 +45,16 @@ namespace Dalamud.Interface.Colors
|
|||
/// <summary>
|
||||
/// Gets tank blue (UIColor37).
|
||||
/// </summary>
|
||||
public static Vector4 TankBlue { get; } = new Vector4(0, 0.6f, 1, 1);
|
||||
public static Vector4 TankBlue { get; } = new Vector4(0f, 0.6f, 1f, 1f);
|
||||
|
||||
/// <summary>
|
||||
/// Gets healer green (UIColor504).
|
||||
/// </summary>
|
||||
public static Vector4 HealerGreen { get; } = new Vector4(0, 0.8f, 0.1333333f, 1);
|
||||
public static Vector4 HealerGreen { get; } = new Vector4(0f, 0.8f, 0.1333333f, 1f);
|
||||
|
||||
/// <summary>
|
||||
/// Gets dps red (UIColor545).
|
||||
/// </summary>
|
||||
public static Vector4 DPSRed { get; } = new Vector4(0.7058824f, 0, 0, 1);
|
||||
public static Vector4 DPSRed { get; } = new Vector4(0.7058824f, 0f, 0f, 1f);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ using Dalamud.Game.ClientState.GamePad;
|
|||
using Dalamud.Game.ClientState.JobGauge;
|
||||
using Dalamud.Game.ClientState.JobGauge.Enums;
|
||||
using Dalamud.Game.ClientState.JobGauge.Types;
|
||||
using Dalamud.Game.ClientState.Keys;
|
||||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
|
|
@ -22,6 +23,7 @@ using Dalamud.Game.Gui;
|
|||
using Dalamud.Game.Gui.FlyText;
|
||||
using Dalamud.Game.Gui.Toast;
|
||||
using Dalamud.Game.Text;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using Dalamud.Memory;
|
||||
|
|
@ -131,6 +133,7 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
FlyText,
|
||||
ImGui,
|
||||
Tex,
|
||||
KeyState,
|
||||
Gamepad,
|
||||
}
|
||||
|
||||
|
|
@ -288,6 +291,10 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
this.DrawTex();
|
||||
break;
|
||||
|
||||
case DataKind.KeyState:
|
||||
this.DrawKeyState();
|
||||
break;
|
||||
|
||||
case DataKind.Gamepad:
|
||||
this.DrawGamepad();
|
||||
break;
|
||||
|
|
@ -674,7 +681,7 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
var condition = Service<Condition>.Get();
|
||||
|
||||
#if DEBUG
|
||||
ImGui.Text($"ptr: 0x{condition.ConditionArrayBase.ToInt64():X}");
|
||||
ImGui.Text($"ptr: 0x{condition.Address.ToInt64():X}");
|
||||
#endif
|
||||
|
||||
ImGui.Text("Current Conditions:");
|
||||
|
|
@ -1150,6 +1157,32 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
}
|
||||
}
|
||||
|
||||
private void DrawKeyState()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
private void DrawGamepad()
|
||||
{
|
||||
var gamepadState = Service<GamepadState>.Get();
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ namespace Dalamud.Plugin
|
|||
/// <summary>
|
||||
/// Gets the timespan delta from when this plugin was loaded.
|
||||
/// </summary>
|
||||
public TimeSpan DeltaLoadTime => DateTime.Now - this.LoadTime;
|
||||
public TimeSpan LoadTimeDelta => DateTime.Now - this.LoadTime;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the directory Dalamud assets are stored in.
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit dbc0bcfb01e32a1b53986ecf9e56f594731b1ea5
|
||||
Subproject commit 24f26cbb924e8941165e8b33817fcd2e2cb014f2
|
||||
Loading…
Add table
Add a link
Reference in a new issue