diff --git a/Dalamud.CorePlugin/GlobalSuppressions.cs b/Dalamud.CorePlugin/GlobalSuppressions.cs
index bfaba20d0..771e6f182 100644
--- a/Dalamud.CorePlugin/GlobalSuppressions.cs
+++ b/Dalamud.CorePlugin/GlobalSuppressions.cs
@@ -6,12 +6,12 @@
using System.Diagnostics.CodeAnalysis;
// General
-[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1118:Parameter should not span multiple lines", Justification = "Preventing long lines", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
-[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1124:Do not use regions", Justification = "I like regions", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
-[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1123:Do not place regions within elements", Justification = "I like regions in elements too", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
-[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1503:Braces should not be omitted", Justification = "This is annoying", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
-[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1512:Single-line comments should not be followed by blank line", Justification = "I like this better", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
-[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1515:Single-line comment should be preceded by blank line", Justification = "I like this better", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
-[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "I like this better", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
-[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1503:Braces should not be omitted", Justification = "I like this better", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
+[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1118:Parameter should not span multiple lines", Justification = "Preventing long lines")]
+[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1124:Do not use regions", Justification = "I like regions")]
+[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1123:Do not place regions within elements", Justification = "I like regions in elements too")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1503:Braces should not be omitted", Justification = "This is annoying")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1512:Single-line comments should not be followed by blank line", Justification = "I like this better")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1515:Single-line comment should be preceded by blank line", Justification = "I like this better")]
+[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "I like this better")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1503:Braces should not be omitted", Justification = "I like this better")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1633:File should have header", Justification = "We don't do those yet")]
diff --git a/Dalamud.CorePlugin/PluginImpl.cs b/Dalamud.CorePlugin/PluginImpl.cs
index d352ad2c8..9026ea0dd 100644
--- a/Dalamud.CorePlugin/PluginImpl.cs
+++ b/Dalamud.CorePlugin/PluginImpl.cs
@@ -54,6 +54,7 @@ namespace Dalamud.CorePlugin
/// Initializes a new instance of the class.
///
/// Dalamud plugin interface.
+ /// Logging service.
public PluginImpl(DalamudPluginInterface pluginInterface, PluginLog log)
{
try
diff --git a/Dalamud.Injector/EntryPoint.cs b/Dalamud.Injector/EntryPoint.cs
index fbefbd92a..c4c553a47 100644
--- a/Dalamud.Injector/EntryPoint.cs
+++ b/Dalamud.Injector/EntryPoint.cs
@@ -739,10 +739,12 @@ namespace Dalamud.Injector
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
[System.Runtime.InteropServices.DllImport("c")]
- static extern ulong clock_gettime_nsec_np(int clock_id);
+#pragma warning disable SA1300
+ static extern ulong clock_gettime_nsec_np(int clockId);
+#pragma warning restore SA1300
const int CLOCK_MONOTONIC_RAW = 4;
- var rawTickCountFixed = (clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW) / 1000000);
+ var rawTickCountFixed = clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW) / 1000000;
Log.Information("ArgumentBuilder::DeriveKey() fixing up rawTickCount from {0} to {1} on macOS", rawTickCount, rawTickCountFixed);
rawTickCount = (uint)rawTickCountFixed;
}
@@ -764,21 +766,27 @@ namespace Dalamud.Injector
gameArgumentString = string.Join(" ", gameArguments.Select(x => EncodeParameterArgument(x)));
}
- var process = GameStart.LaunchGame(Path.GetDirectoryName(gamePath), gamePath, gameArgumentString, noFixAcl, (Process p) =>
- {
- if (!withoutDalamud && mode == "entrypoint")
+ var process = GameStart.LaunchGame(
+ Path.GetDirectoryName(gamePath),
+ gamePath,
+ gameArgumentString,
+ noFixAcl,
+ p =>
{
- var startInfo = AdjustStartInfo(dalamudStartInfo, gamePath);
- Log.Information("Using start info: {0}", JsonConvert.SerializeObject(startInfo));
- if (RewriteRemoteEntryPointW(p.Handle, gamePath, JsonConvert.SerializeObject(startInfo)) != 0)
+ if (!withoutDalamud && mode == "entrypoint")
{
- Log.Error("[HOOKS] RewriteRemoteEntryPointW failed");
- throw new Exception("RewriteRemoteEntryPointW failed");
- }
+ var startInfo = AdjustStartInfo(dalamudStartInfo, gamePath);
+ Log.Information("Using start info: {0}", JsonConvert.SerializeObject(startInfo));
+ if (RewriteRemoteEntryPointW(p.Handle, gamePath, JsonConvert.SerializeObject(startInfo)) != 0)
+ {
+ Log.Error("[HOOKS] RewriteRemoteEntryPointW failed");
+ throw new Exception("RewriteRemoteEntryPointW failed");
+ }
- Log.Verbose("RewriteRemoteEntryPointW called!");
- }
- }, waitForGameWindow);
+ Log.Verbose("RewriteRemoteEntryPointW called!");
+ }
+ },
+ waitForGameWindow);
Log.Verbose("Game process started with PID {0}", process.Id);
diff --git a/Dalamud.Injector/GameStart.cs b/Dalamud.Injector/GameStart.cs
index 95e963a9a..e34048978 100644
--- a/Dalamud.Injector/GameStart.cs
+++ b/Dalamud.Injector/GameStart.cs
@@ -211,6 +211,9 @@ namespace Dalamud.Injector
}
}
+ ///
+ /// Claim a SE Debug Privilege.
+ ///
public static void ClaimSeDebug()
{
var hToken = PInvoke.INVALID_HANDLE_VALUE;
@@ -345,8 +348,6 @@ namespace Dalamud.Injector
private static class PInvoke
{
#region Constants
- public static readonly IntPtr INVALID_HANDLE_VALUE = new(-1);
-
public const string SE_DEBUG_NAME = "SeDebugPrivilege";
public const UInt32 STANDARD_RIGHTS_ALL = 0x001F0000;
@@ -369,6 +370,8 @@ namespace Dalamud.Injector
public const UInt32 ERROR_NO_TOKEN = 0x000003F0;
+ public static readonly IntPtr INVALID_HANDLE_VALUE = new(-1);
+
public enum MULTIPLE_TRUSTEE_OPERATION
{
NO_MULTIPLE_TRUSTEE,
@@ -431,7 +434,7 @@ namespace Dalamud.Injector
SecurityAnonymous,
SecurityIdentification,
SecurityImpersonation,
- SecurityDelegation
+ SecurityDelegation,
}
#endregion
@@ -485,8 +488,7 @@ namespace Dalamud.Injector
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool ImpersonateSelf(
- SECURITY_IMPERSONATION_LEVEL impersonationLevel
- );
+ SECURITY_IMPERSONATION_LEVEL impersonationLevel);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool OpenProcessToken(
@@ -496,10 +498,10 @@ namespace Dalamud.Injector
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool OpenThreadToken(
- IntPtr ThreadHandle,
- uint DesiredAccess,
- bool OpenAsSelf,
- out IntPtr TokenHandle);
+ IntPtr threadHandle,
+ uint desiredAccess,
+ bool openAsSelf,
+ out IntPtr tokenHandle);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, ref LUID lpLuid);
diff --git a/Dalamud.Injector/GlobalSuppressions.cs b/Dalamud.Injector/GlobalSuppressions.cs
index e1978fae4..57d7f2d28 100644
--- a/Dalamud.Injector/GlobalSuppressions.cs
+++ b/Dalamud.Injector/GlobalSuppressions.cs
@@ -7,7 +7,7 @@ using System.Diagnostics.CodeAnalysis;
// General
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1633:File should have header", Justification = "We don't do those yet")]
-[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1503:Braces should not be omitted", Justification = "This is annoying", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
-[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1512:Single-line comments should not be followed by blank line", Justification = "I like this better", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
-[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1515:Single-line comment should be preceded by blank line", Justification = "I like this better", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
-[assembly: SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "I'll make what I want static", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1503:Braces should not be omitted", Justification = "This is annoying")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1512:Single-line comments should not be followed by blank line", Justification = "I like this better")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1515:Single-line comment should be preceded by blank line", Justification = "I like this better")]
+[assembly: SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "I'll make what I want static")]
diff --git a/Dalamud.Injector/LegacyBlowfish.cs b/Dalamud.Injector/LegacyBlowfish.cs
index 28cc584e4..99c514954 100644
--- a/Dalamud.Injector/LegacyBlowfish.cs
+++ b/Dalamud.Injector/LegacyBlowfish.cs
@@ -1,8 +1,16 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
namespace Dalamud.Injector
{
+ [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1124:Do not use regions", Justification = "Legacy code")]
+ [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1413:Use trailing comma in multi-line initializers", Justification = "Legacy code")]
+ [SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1519:Braces should not be omitted from multi-line child statement", Justification = "Legacy code")]
+ [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1414:Tuple types in signatures should have element names", Justification = "Legacy code")]
+ [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1101:Prefix local calls with this", Justification = "Legacy code")]
+ [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Legacy code")]
+ [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1204:Static elements should appear before instance elements", Justification = "Legacy code")]
internal class LegacyBlowfish
{
#region P-Array and S-Boxes
@@ -203,10 +211,9 @@ namespace Dalamud.Injector
private static readonly int Rounds = 16;
///
- /// Initialize a new blowfish.
+ /// Initializes a new instance of the class.
///
/// The key to use.
- /// Whether or not a sign confusion should be introduced during key init. This is needed for SE's implementation of blowfish.
public LegacyBlowfish(byte[] key)
{
foreach (var (i, keyFragment) in WrappingUInt32(key, this.p.Length))
@@ -306,7 +313,9 @@ namespace Dalamud.Injector
for (var j = 0; j < 4 && enumerator.MoveNext(); j++)
{
+#pragma warning disable CS0675
n = (uint)((n << 8) | (sbyte)enumerator.Current); // NOTE(goat): THIS IS A BUG! SE's implementation wrongly uses signed numbers for this, so we need to as well.
+#pragma warning restore CS0675
}
yield return (i, n);
diff --git a/Dalamud/Dalamud.cs b/Dalamud/Dalamud.cs
index 73914d2a7..c38594771 100644
--- a/Dalamud/Dalamud.cs
+++ b/Dalamud/Dalamud.cs
@@ -1,7 +1,9 @@
using System;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
@@ -97,6 +99,19 @@ internal sealed class Dalamud : IServiceType
/// Gets location of stored assets.
///
internal DirectoryInfo AssetDirectory => new(Service.Get().AssetDirectory!);
+
+ ///
+ /// Signal to the crash handler process that we should restart the game.
+ ///
+ public static void RestartGame()
+ {
+ [DllImport("kernel32.dll")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ static extern void RaiseException(uint dwExceptionCode, uint dwExceptionFlags, uint nNumberOfArguments, IntPtr lpArguments);
+
+ RaiseException(0x12345678, 0, 0, IntPtr.Zero);
+ Process.GetCurrentProcess().Kill();
+ }
///
/// Queue an unload of Dalamud when it gets the chance.
diff --git a/Dalamud/Game/ChatHandlers.cs b/Dalamud/Game/ChatHandlers.cs
index 4827c0d4f..7cd0869aa 100644
--- a/Dalamud/Game/ChatHandlers.cs
+++ b/Dalamud/Game/ChatHandlers.cs
@@ -248,7 +248,8 @@ public class ChatHandlers : IServiceType
var assemblyVersion = Assembly.GetAssembly(typeof(ChatHandlers)).GetName().Version.ToString();
- if (this.configuration.PrintDalamudWelcomeMsg) {
+ if (this.configuration.PrintDalamudWelcomeMsg)
+ {
chatGui.Print(string.Format(Loc.Localize("DalamudWelcome", "Dalamud vD{0} loaded."), assemblyVersion)
+ string.Format(Loc.Localize("PluginsWelcome", " {0} plugin(s) loaded."), pluginManager.InstalledPlugins.Count(x => x.IsLoaded)));
}
diff --git a/Dalamud/Game/ClientState/Objects/Enums/BattleNpcSubKind.cs b/Dalamud/Game/ClientState/Objects/Enums/BattleNpcSubKind.cs
index f9019ed77..9c10a84ab 100644
--- a/Dalamud/Game/ClientState/Objects/Enums/BattleNpcSubKind.cs
+++ b/Dalamud/Game/ClientState/Objects/Enums/BattleNpcSubKind.cs
@@ -10,9 +10,9 @@ public enum BattleNpcSubKind : byte
///
None = 0,
- ///
+ ///
/// Weak Spots / Battle NPC parts
- /// Eg: Titan's Heart (Naval), Tioman's left and right wing (Sohm Al), Golem Soulstone (The Sunken Temple of Qarn)
+ /// Eg: Titan's Heart (Naval), Tioman's left and right wing (Sohm Al), Golem Soulstone (The Sunken Temple of Qarn).
///
BattleNpcPart = 1,
diff --git a/Dalamud/Game/ClientState/Objects/Types/BattleChara.cs b/Dalamud/Game/ClientState/Objects/Types/BattleChara.cs
index 651f97834..63a5b828a 100644
--- a/Dalamud/Game/ClientState/Objects/Types/BattleChara.cs
+++ b/Dalamud/Game/ClientState/Objects/Types/BattleChara.cs
@@ -22,42 +22,42 @@ public unsafe class BattleChara : Character
///
/// Gets the current status effects.
///
- public StatusList StatusList => new(&this.Struct->StatusManager);
+ public StatusList StatusList => new(this.Struct->GetStatusManager);
///
/// Gets a value indicating whether the chara is currently casting.
///
- public bool IsCasting => this.Struct->SpellCastInfo.IsCasting > 0;
+ public bool IsCasting => this.Struct->GetCastInfo->IsCasting > 0;
///
/// Gets a value indicating whether the cast is interruptible.
///
- public bool IsCastInterruptible => this.Struct->SpellCastInfo.Interruptible > 0;
+ public bool IsCastInterruptible => this.Struct->GetCastInfo->Interruptible > 0;
///
/// Gets the spell action type of the spell being cast by the actor.
///
- public byte CastActionType => (byte)this.Struct->SpellCastInfo.ActionType;
+ public byte CastActionType => (byte)this.Struct->GetCastInfo->ActionType;
///
/// Gets the spell action ID of the spell being cast by the actor.
///
- public uint CastActionId => this.Struct->SpellCastInfo.ActionID;
+ public uint CastActionId => this.Struct->GetCastInfo->ActionID;
///
/// Gets the object ID of the target currently being cast at by the chara.
///
- public uint CastTargetObjectId => this.Struct->SpellCastInfo.CastTargetID;
+ public uint CastTargetObjectId => this.Struct->GetCastInfo->CastTargetID;
///
/// Gets the current casting time of the spell being cast by the chara.
///
- public float CurrentCastTime => this.Struct->SpellCastInfo.CurrentCastTime;
+ public float CurrentCastTime => this.Struct->GetCastInfo->CurrentCastTime;
///
/// Gets the total casting time of the spell being cast by the chara.
///
- public float TotalCastTime => this.Struct->SpellCastInfo.TotalCastTime;
+ public float TotalCastTime => this.Struct->GetCastInfo->TotalCastTime;
///
/// Gets the underlying structure.
diff --git a/Dalamud/Game/ClientState/Objects/Types/Character.cs b/Dalamud/Game/ClientState/Objects/Types/Character.cs
index afc94bd0f..cdd1515b0 100644
--- a/Dalamud/Game/ClientState/Objects/Types/Character.cs
+++ b/Dalamud/Game/ClientState/Objects/Types/Character.cs
@@ -77,7 +77,7 @@ public unsafe class Character : GameObject
/// Gets a byte array describing the visual appearance of this Chara.
/// Indexed by .
///
- public byte[] Customize => MemoryHelper.Read((IntPtr)this.Struct->CustomizeData, 28);
+ public byte[] Customize => MemoryHelper.Read((IntPtr)this.Struct->DrawData.CustomizeData.Data, 28);
///
/// Gets the Free Company tag of this chara.
diff --git a/Dalamud/Game/Config/GameConfigSection.cs b/Dalamud/Game/Config/GameConfigSection.cs
index 89df468f0..107b0d4a8 100644
--- a/Dalamud/Game/Config/GameConfigSection.cs
+++ b/Dalamud/Game/Config/GameConfigSection.cs
@@ -67,7 +67,8 @@ public class GameConfigSection
/// Name of the config option.
/// The returned value of the config option.
/// A value representing the success.
- public unsafe bool TryGetBool(string name, out bool value) {
+ public unsafe bool TryGetBool(string name, out bool value)
+ {
value = false;
if (!this.TryGetIndex(name, out var index))
{
@@ -97,7 +98,8 @@ public class GameConfigSection
/// Name of the config option.
/// Value of the config option.
/// Thrown if the config option is not found.
- public bool GetBool(string name) {
+ public bool GetBool(string name)
+ {
if (!this.TryGetBool(name, out var value))
{
throw new ConfigOptionNotFoundException(this.SectionName, name);
@@ -114,7 +116,8 @@ public class GameConfigSection
/// New value of the config option.
/// Throw if the config option is not found.
/// Thrown if the name of the config option is found, but the struct was not.
- public unsafe void Set(string name, bool value) {
+ public unsafe void Set(string name, bool value)
+ {
if (!this.TryGetIndex(name, out var index))
{
throw new ConfigOptionNotFoundException(this.SectionName, name);
@@ -139,7 +142,8 @@ public class GameConfigSection
/// Name of the config option.
/// The returned value of the config option.
/// A value representing the success.
- public unsafe bool TryGetUInt(string name, out uint value) {
+ public unsafe bool TryGetUInt(string name, out uint value)
+ {
value = 0;
if (!this.TryGetIndex(name, out var index))
{
@@ -169,7 +173,8 @@ public class GameConfigSection
/// Name of the config option.
/// Value of the config option.
/// Thrown if the config option is not found.
- public uint GetUInt(string name) {
+ public uint GetUInt(string name)
+ {
if (!this.TryGetUInt(name, out var value))
{
throw new ConfigOptionNotFoundException(this.SectionName, name);
@@ -186,8 +191,10 @@ public class GameConfigSection
/// New value of the config option.
/// Throw if the config option is not found.
/// Thrown if the name of the config option is found, but the struct was not.
- public unsafe void Set(string name, uint value) {
- this.framework.RunOnFrameworkThread(() => {
+ public unsafe void Set(string name, uint value)
+ {
+ this.framework.RunOnFrameworkThread(() =>
+ {
if (!this.TryGetIndex(name, out var index))
{
throw new ConfigOptionNotFoundException(this.SectionName, name);
@@ -213,7 +220,8 @@ public class GameConfigSection
/// Name of the config option.
/// The returned value of the config option.
/// A value representing the success.
- public unsafe bool TryGetFloat(string name, out float value) {
+ public unsafe bool TryGetFloat(string name, out float value)
+ {
value = 0;
if (!this.TryGetIndex(name, out var index))
{
@@ -243,7 +251,8 @@ public class GameConfigSection
/// Name of the config option.
/// Value of the config option.
/// Thrown if the config option is not found.
- public float GetFloat(string name) {
+ public float GetFloat(string name)
+ {
if (!this.TryGetFloat(name, out var value))
{
throw new ConfigOptionNotFoundException(this.SectionName, name);
@@ -260,8 +269,10 @@ public class GameConfigSection
/// New value of the config option.
/// Throw if the config option is not found.
/// Thrown if the name of the config option is found, but the struct was not.
- public unsafe void Set(string name, float value) {
- this.framework.RunOnFrameworkThread(() => {
+ public unsafe void Set(string name, float value)
+ {
+ this.framework.RunOnFrameworkThread(() =>
+ {
if (!this.TryGetIndex(name, out var index))
{
throw new ConfigOptionNotFoundException(this.SectionName, name);
@@ -287,7 +298,8 @@ public class GameConfigSection
/// Name of the config option.
/// The returned value of the config option.
/// A value representing the success.
- public unsafe bool TryGetString(string name, out string value) {
+ public unsafe bool TryGetString(string name, out string value)
+ {
value = string.Empty;
if (!this.TryGetIndex(name, out var index))
{
@@ -327,7 +339,8 @@ public class GameConfigSection
/// Name of the config option.
/// Value of the config option.
/// Thrown if the config option is not found.
- public string GetString(string name) {
+ public string GetString(string name)
+ {
if (!this.TryGetString(name, out var value))
{
throw new ConfigOptionNotFoundException(this.SectionName, name);
@@ -344,8 +357,10 @@ public class GameConfigSection
/// New value of the config option.
/// Throw if the config option is not found.
/// Thrown if the name of the config option is found, but the struct was not.
- public unsafe void Set(string name, string value) {
- this.framework.RunOnFrameworkThread(() => {
+ public unsafe void Set(string name, string value)
+ {
+ this.framework.RunOnFrameworkThread(() =>
+ {
if (!this.TryGetIndex(name, out var index))
{
throw new ConfigOptionNotFoundException(this.SectionName, name);
@@ -365,7 +380,8 @@ public class GameConfigSection
});
}
- private unsafe bool TryGetIndex(string name, out uint index) {
+ private unsafe bool TryGetIndex(string name, out uint index)
+ {
if (this.indexMap.TryGetValue(name, out index))
{
return true;
@@ -373,14 +389,16 @@ public class GameConfigSection
var configBase = this.GetConfigBase();
var e = configBase->ConfigEntry;
- for (var i = 0U; i < configBase->ConfigCount; i++, e++) {
+ for (var i = 0U; i < configBase->ConfigCount; i++, e++)
+ {
if (e->Name == null)
{
continue;
}
var eName = MemoryHelper.ReadStringNullTerminated(new IntPtr(e->Name));
- if (eName.Equals(name)) {
+ if (eName.Equals(name))
+ {
this.indexMap.TryAdd(name, i);
this.nameMap.TryAdd(i, name);
index = i;
@@ -392,7 +410,8 @@ public class GameConfigSection
return false;
}
- private unsafe bool TryGetEntry(uint index, out ConfigEntry* entry) {
+ private unsafe bool TryGetEntry(uint index, out ConfigEntry* entry)
+ {
entry = null;
var configBase = this.GetConfigBase();
if (configBase->ConfigEntry == null || index >= configBase->ConfigCount)
diff --git a/Dalamud/Game/Framework.cs b/Dalamud/Game/Framework.cs
index 21bd9e646..b3083e913 100644
--- a/Dalamud/Game/Framework.cs
+++ b/Dalamud/Game/Framework.cs
@@ -25,25 +25,25 @@ namespace Dalamud.Game;
[ServiceManager.BlockingEarlyLoadedService]
public sealed class Framework : IDisposable, IServiceType
{
+ private static readonly Stopwatch StatsStopwatch = new();
+
private readonly GameLifecycle lifecycle;
- private static Stopwatch statsStopwatch = new();
-
private readonly Stopwatch updateStopwatch = new();
private readonly HitchDetector hitchDetector;
private readonly Hook updateHook;
private readonly Hook destroyHook;
+ [ServiceManager.ServiceDependency]
+ private readonly DalamudConfiguration configuration = Service.Get();
+
private readonly object runOnNextTickTaskListSync = new();
private List runOnNextTickTaskList = new();
private List runOnNextTickTaskList2 = new();
private Thread? frameworkUpdateThread;
- [ServiceManager.ServiceDependency]
- private readonly DalamudConfiguration configuration = Service.Get();
-
[ServiceManager.ServiceConstructor]
private Framework(SigScanner sigScanner, GameLifecycle lifecycle)
{
@@ -346,7 +346,7 @@ public sealed class Framework : IDisposable, IServiceType
this.destroyHook.Dispose();
this.updateStopwatch.Reset();
- statsStopwatch.Reset();
+ StatsStopwatch.Reset();
}
[ServiceManager.CallWhenServicesReady]
@@ -420,11 +420,11 @@ public sealed class Framework : IDisposable, IServiceType
if (StatsEnabled)
{
- statsStopwatch.Restart();
+ StatsStopwatch.Restart();
this.RunPendingTickTasks();
- statsStopwatch.Stop();
+ StatsStopwatch.Stop();
- AddToStats(nameof(this.RunPendingTickTasks), statsStopwatch.Elapsed.TotalMilliseconds);
+ AddToStats(nameof(this.RunPendingTickTasks), StatsStopwatch.Elapsed.TotalMilliseconds);
}
else
{
@@ -440,7 +440,7 @@ public sealed class Framework : IDisposable, IServiceType
// Individually invoke OnUpdate handlers and time them.
foreach (var d in invokeList)
{
- statsStopwatch.Restart();
+ StatsStopwatch.Restart();
try
{
d.Method.Invoke(d.Target, new object[] { this });
@@ -450,13 +450,13 @@ public sealed class Framework : IDisposable, IServiceType
Log.Error(ex, "Exception while dispatching Framework::Update event.");
}
- statsStopwatch.Stop();
+ StatsStopwatch.Stop();
var key = $"{d.Target}::{d.Method.Name}";
if (notUpdated.Contains(key))
notUpdated.Remove(key);
- AddToStats(key, statsStopwatch.Elapsed.TotalMilliseconds);
+ AddToStats(key, StatsStopwatch.Elapsed.TotalMilliseconds);
}
// Cleanup handlers that are no longer being called
diff --git a/Dalamud/Game/Network/GameNetwork.cs b/Dalamud/Game/Network/GameNetwork.cs
index 767c9bc9a..d1fc0bfba 100644
--- a/Dalamud/Game/Network/GameNetwork.cs
+++ b/Dalamud/Game/Network/GameNetwork.cs
@@ -1,13 +1,12 @@
using System;
-using System.Collections.Generic;
using System.Runtime.InteropServices;
+
using Dalamud.Configuration.Internal;
using Dalamud.Hooking;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Utility;
using Serilog;
-using Serilog.Core;
namespace Dalamud.Game.Network;
@@ -26,11 +25,11 @@ public sealed class GameNetwork : IDisposable, IServiceType
private readonly HitchDetector hitchDetectorUp;
private readonly HitchDetector hitchDetectorDown;
- private IntPtr baseAddress;
-
[ServiceManager.ServiceDependency]
private readonly DalamudConfiguration configuration = Service.Get();
-
+
+ private IntPtr baseAddress;
+
[ServiceManager.ServiceConstructor]
private GameNetwork(SigScanner sigScanner)
{
diff --git a/Dalamud/GlobalSuppressions.cs b/Dalamud/GlobalSuppressions.cs
index 5c3b40ebc..7426ed5c8 100644
--- a/Dalamud/GlobalSuppressions.cs
+++ b/Dalamud/GlobalSuppressions.cs
@@ -6,12 +6,12 @@
using System.Diagnostics.CodeAnalysis;
// General
-[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1118:Parameter should not span multiple lines", Justification = "Preventing long lines", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
-[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1124:Do not use regions", Justification = "I like regions", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
-[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1123:Do not place regions within elements", Justification = "I like regions in elements too", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
-[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1503:Braces should not be omitted", Justification = "This is annoying", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
-[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1512:Single-line comments should not be followed by blank line", Justification = "I like this better", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
-[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1515:Single-line comment should be preceded by blank line", Justification = "I like this better", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
-[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "I like this better", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
-[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1028:Code should not contain trailing whitespace", Justification = "I don't care anymore", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
+[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1118:Parameter should not span multiple lines", Justification = "Preventing long lines")]
+[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1124:Do not use regions", Justification = "I like regions")]
+[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1123:Do not place regions within elements", Justification = "I like regions in elements too")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1503:Braces should not be omitted", Justification = "This is annoying")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1512:Single-line comments should not be followed by blank line", Justification = "I like this better")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1515:Single-line comment should be preceded by blank line", Justification = "I like this better")]
+[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "I like this better")]
+[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1028:Code should not contain trailing whitespace", Justification = "I don't care anymore")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1633:File should have header", Justification = "We don't do those yet")]
diff --git a/Dalamud/Hooking/Internal/HookManager.cs b/Dalamud/Hooking/Internal/HookManager.cs
index f185450eb..9c288a276 100644
--- a/Dalamud/Hooking/Internal/HookManager.cs
+++ b/Dalamud/Hooking/Internal/HookManager.cs
@@ -17,7 +17,7 @@ namespace Dalamud.Hooking.Internal;
internal class HookManager : IDisposable, IServiceType
{
///
- /// Logger shared with
+ /// Logger shared with .
///
internal static readonly ModuleLog Log = new("HM");
@@ -41,6 +41,11 @@ internal class HookManager : IDisposable, IServiceType
///
internal static ConcurrentDictionary Unhookers { get; } = new();
+ ///
+ /// Gets a static dictionary of the number of hooks on a given address.
+ ///
+ internal static ConcurrentDictionary> MultiHookTracker { get; } = new();
+
///
/// Creates a new Unhooker instance for the provided address if no such unhooker was already registered, or returns
/// an existing instance if the address was registered previously. By default, the unhooker will restore between 0
@@ -68,11 +73,6 @@ internal class HookManager : IDisposable, IServiceType
return Unhookers.GetOrAdd(address, _ => new Unhooker(address, minBytes, maxBytes));
}
- ///
- /// Gets a static dictionary of the number of hooks on a given address.
- ///
- internal static ConcurrentDictionary> MultiHookTracker { get; } = new();
-
///
public void Dispose()
{
diff --git a/Dalamud/Interface/Internal/DalamudCommands.cs b/Dalamud/Interface/Internal/DalamudCommands.cs
index dfcccf79d..307f79436 100644
--- a/Dalamud/Interface/Internal/DalamudCommands.cs
+++ b/Dalamud/Interface/Internal/DalamudCommands.cs
@@ -29,13 +29,19 @@ internal class DalamudCommands : IServiceType
HelpMessage = Loc.Localize("DalamudUnloadHelp", "Unloads XIVLauncher in-game addon."),
ShowInHelp = false,
});
-
+
commandManager.AddHandler("/xlkill", new CommandInfo(this.OnKillCommand)
{
HelpMessage = "Kill the game.",
ShowInHelp = false,
});
+ commandManager.AddHandler("/xlrestart", new CommandInfo(this.OnRestartCommand)
+ {
+ HelpMessage = "Restart the game.",
+ ShowInHelp = false,
+ });
+
commandManager.AddHandler("/xlhelp", new CommandInfo(this.OnHelpCommand)
{
HelpMessage = Loc.Localize("DalamudCmdInfoHelp", "Shows list of commands available. If an argument is provided, shows help for that command."),
@@ -147,12 +153,17 @@ internal class DalamudCommands : IServiceType
Service.Get().Print("Unloading...");
Service.Get().Unload();
}
-
+
private void OnKillCommand(string command, string arguments)
{
Process.GetCurrentProcess().Kill();
}
+ private void OnRestartCommand(string command, string arguments)
+ {
+ Dalamud.RestartGame();
+ }
+
private void OnHelpCommand(string command, string arguments)
{
var chatGui = Service.Get();
diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs
index 75c3b2b03..ca7cbe287 100644
--- a/Dalamud/Interface/Internal/DalamudInterface.cs
+++ b/Dalamud/Interface/Internal/DalamudInterface.cs
@@ -717,12 +717,7 @@ internal class DalamudInterface : IDisposable, IServiceType
if (ImGui.MenuItem("Restart game"))
{
- [DllImport("kernel32.dll")]
- [return: MarshalAs(UnmanagedType.Bool)]
- static extern void RaiseException(uint dwExceptionCode, uint dwExceptionFlags, uint nNumberOfArguments, IntPtr lpArguments);
-
- RaiseException(0x12345678, 0, 0, IntPtr.Zero);
- Process.GetCurrentProcess().Kill();
+ Dalamud.RestartGame();
}
if (ImGui.MenuItem("Kill game"))
diff --git a/Dalamud/Interface/Internal/Windows/DataWindow.cs b/Dalamud/Interface/Internal/Windows/DataWindow.cs
index 2c328d7f1..c46916343 100644
--- a/Dalamud/Interface/Internal/Windows/DataWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/DataWindow.cs
@@ -1792,7 +1792,8 @@ internal class DataWindow : Window
ImGui.TableNextColumn();
ImGui.TextUnformatted(string.Join(", ", share.Users));
}
- } finally
+ }
+ finally
{
ImGui.EndTable();
}
diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelogManager.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelogManager.cs
index a3a965e80..2dc182e9a 100644
--- a/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelogManager.cs
+++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelogManager.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Json;
using System.Threading.Tasks;
+
using Dalamud.Networking.Http;
using Dalamud.Plugin.Internal;
using Dalamud.Utility;
diff --git a/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs b/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs
index 1db4b21f3..44e43fbd3 100644
--- a/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs
@@ -23,6 +23,8 @@ namespace Dalamud.Interface.Internal.Windows;
internal class PluginStatWindow : Window
{
private bool showDalamudHooks;
+ private string drawSearchText = string.Empty;
+ private string frameworkSearchText = string.Empty;
private string hookSearchText = string.Empty;
///
@@ -79,6 +81,12 @@ internal class PluginStatWindow : Window
ImGui.SameLine();
ImGuiComponents.TextWithLabel("Collective Average", $"{(loadedPlugins.Any() ? totalAverage / loadedPlugins.Count() / 10000f : 0):F4}ms", "Average of all average draw times");
+ ImGui.InputTextWithHint(
+ "###PluginStatWindow_DrawSearch",
+ "Search",
+ ref this.drawSearchText,
+ 500);
+
if (ImGui.BeginTable(
"##PluginStatsDrawTimes",
4,
@@ -114,6 +122,12 @@ internal class PluginStatWindow : Window
foreach (var plugin in loadedPlugins)
{
+ if (!this.drawSearchText.IsNullOrEmpty()
+ && !plugin.Manifest.Name.Contains(this.drawSearchText, StringComparison.OrdinalIgnoreCase))
+ {
+ continue;
+ }
+
ImGui.TableNextRow();
ImGui.TableNextColumn();
@@ -168,6 +182,12 @@ internal class PluginStatWindow : Window
ImGui.SameLine();
ImGuiComponents.TextWithLabel("Collective Average", $"{(statsHistory.Any() ? totalAverage / statsHistory.Length : 0):F4}ms", "Average of all average update times");
+ ImGui.InputTextWithHint(
+ "###PluginStatWindow_FrameworkSearch",
+ "Search",
+ ref this.frameworkSearchText,
+ 500);
+
if (ImGui.BeginTable(
"##PluginStatsFrameworkTimes",
4,
@@ -208,6 +228,13 @@ internal class PluginStatWindow : Window
continue;
}
+ if (!this.frameworkSearchText.IsNullOrEmpty()
+ && handlerHistory.Key != null
+ && !handlerHistory.Key.Contains(this.frameworkSearchText, StringComparison.OrdinalIgnoreCase))
+ {
+ continue;
+ }
+
ImGui.TableNextRow();
ImGui.TableNextColumn();
diff --git a/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs b/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs
index 6352d7b69..83be6a052 100644
--- a/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs
+++ b/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs
@@ -23,8 +23,16 @@ internal sealed class SettingsEntry : SettingsEntry
private object? valueBacking;
private object? fallbackValue;
- public SettingsEntry(string name, string description, LoadSettingDelegate load, SaveSettingDelegate save, Action? change = null, Func? warning = null, Func? validity = null, Func? visibility = null,
- object? fallbackValue = null)
+ public SettingsEntry(
+ string name,
+ string description,
+ LoadSettingDelegate load,
+ SaveSettingDelegate save,
+ Action? change = null,
+ Func? warning = null,
+ Func? validity = null,
+ Func? visibility = null,
+ object? fallbackValue = null)
{
this.load = load;
this.save = save;
diff --git a/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs b/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs
index 3c70c644c..143fda6ab 100644
--- a/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs
@@ -254,7 +254,6 @@ internal class TitleScreenMenuWindow : Window, IDisposable
var initialCursor = ImGui.GetCursorPos();
-
using (ImRaii.PushStyle(ImGuiStyleVar.Alpha, (float)shadeEasing.Value))
{
ImGui.Image(this.shadeTexture.ImGuiHandle, new Vector2(this.shadeTexture.Width * scale, this.shadeTexture.Height * scale));
diff --git a/Dalamud/Interface/UiBuilder.cs b/Dalamud/Interface/UiBuilder.cs
index da4f241ac..eca0f64a0 100644
--- a/Dalamud/Interface/UiBuilder.cs
+++ b/Dalamud/Interface/UiBuilder.cs
@@ -31,12 +31,12 @@ public sealed class UiBuilder : IDisposable
private readonly InterfaceManager interfaceManager = Service.Get();
private readonly GameFontManager gameFontManager = Service.Get();
- private bool hasErrorWindow = false;
- private bool lastFrameUiHideState = false;
-
[ServiceManager.ServiceDependency]
private readonly DalamudConfiguration configuration = Service.Get();
+ private bool hasErrorWindow = false;
+ private bool lastFrameUiHideState = false;
+
///
/// Initializes a new instance of the class and registers it.
/// You do not have to call this manually.
diff --git a/Dalamud/Logging/PluginLog.cs b/Dalamud/Logging/PluginLog.cs
index 83cc90bc4..acbd663e7 100644
--- a/Dalamud/Logging/PluginLog.cs
+++ b/Dalamud/Logging/PluginLog.cs
@@ -277,6 +277,12 @@ public class PluginLog : IServiceType, IDisposable
public static void LogRaw(LogEventLevel level, Exception? exception, string messageTemplate, params object[] values)
=> WriteLog(Assembly.GetCallingAssembly().GetName().Name, level, messageTemplate, exception, values);
+ ///
+ void IDisposable.Dispose()
+ {
+ // ignored
+ }
+
#region New instanced methods
///
@@ -290,12 +296,6 @@ public class PluginLog : IServiceType, IDisposable
#endregion
- ///
- void IDisposable.Dispose()
- {
- // ignored
- }
-
private static ILogger GetPluginLogger(string? pluginName)
{
return Serilog.Log.ForContext("SourceContext", pluginName ?? string.Empty);
diff --git a/Dalamud/NativeFunctions.cs b/Dalamud/NativeFunctions.cs
index 50a58bfe7..b77f71d08 100644
--- a/Dalamud/NativeFunctions.cs
+++ b/Dalamud/NativeFunctions.cs
@@ -1132,6 +1132,7 @@ internal static partial class NativeFunctions
///
/// Native kernel32 functions.
///
+[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1629:Documentation text should end with a period", Justification = "Stupid rule")]
internal static partial class NativeFunctions
{
///
@@ -1394,7 +1395,7 @@ internal static partial class NativeFunctions
}
///
- /// HEAP_* from heapapi
+ /// HEAP_* from heapapi.
///
[Flags]
public enum HeapOptions
diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs
index 645d2975b..a0283ca67 100644
--- a/Dalamud/Plugin/Internal/PluginManager.cs
+++ b/Dalamud/Plugin/Internal/PluginManager.cs
@@ -62,7 +62,6 @@ internal partial class PluginManager : IDisposable, IServiceType
private readonly object pluginListLock = new();
private readonly DirectoryInfo pluginDirectory;
- private readonly DirectoryInfo devPluginDirectory;
private readonly BannedPlugin[]? bannedPlugins;
private readonly DalamudLinkPayload openInstallerWindowPluginChangelogsLink;
diff --git a/Dalamud/ServiceManager.cs b/Dalamud/ServiceManager.cs
index c13d39f4c..41ffe33ca 100644
--- a/Dalamud/ServiceManager.cs
+++ b/Dalamud/ServiceManager.cs
@@ -16,18 +16,15 @@ using JetBrains.Annotations;
namespace Dalamud;
+// TODO:
+// - Unify dependency walking code(load/unload
+// - Visualize/output .dot or imgui thing
+
///
/// Class to initialize Service<T>s.
///
internal static class ServiceManager
{
- /**
- * TODO:
- * - Unify dependency walking code(load/unload
- * - Visualize/output .dot or imgui thing
- */
-
-
///
/// Static log facility for Service{T}, to avoid duplicate instances for different types.
///
diff --git a/Dalamud/Service{T}.cs b/Dalamud/Service{T}.cs
index a1a56a9f0..aa10ead6e 100644
--- a/Dalamud/Service{T}.cs
+++ b/Dalamud/Service{T}.cs
@@ -141,7 +141,6 @@ internal static class Service where T : IServiceType
.OfType()
.Select(x => x.GetType().GetGenericArguments().First()));
-
// HACK: PluginManager needs to depend on ALL plugin exposed services
if (typeof(T) == typeof(PluginManager))
{
diff --git a/Dalamud/Support/BugBait.cs b/Dalamud/Support/BugBait.cs
index ce74c03ec..cdbf94616 100644
--- a/Dalamud/Support/BugBait.cs
+++ b/Dalamud/Support/BugBait.cs
@@ -1,6 +1,7 @@
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
+
using Dalamud.Networking.Http;
using Dalamud.Plugin.Internal.Types;
using Dalamud.Utility;
diff --git a/Dalamud/Utility/AsyncUtils.cs b/Dalamud/Utility/AsyncUtils.cs
index c0fbbb8a4..d02c90195 100644
--- a/Dalamud/Utility/AsyncUtils.cs
+++ b/Dalamud/Utility/AsyncUtils.cs
@@ -19,7 +19,7 @@ public static class AsyncUtils
/// A list of tasks to race.
/// The return type of all raced tasks.
/// Thrown when all tasks given to this method fail.
- /// Returns the first task that completes, according to .
+ /// Returns the first task that completes, according to .
public static Task FirstSuccessfulTask(ICollection> tasks)
{
var tcs = new TaskCompletionSource();
diff --git a/Dalamud/Utility/Numerics/VectorExtensions.cs b/Dalamud/Utility/Numerics/VectorExtensions.cs
index cd958deb8..910dbdd00 100644
--- a/Dalamud/Utility/Numerics/VectorExtensions.cs
+++ b/Dalamud/Utility/Numerics/VectorExtensions.cs
@@ -1,5 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
+
using FFXIVClientStructs.FFXIV.Client.Graphics;
namespace Dalamud.Utility.Numerics;