diff --git a/.github/workflows/rollup.yml b/.github/workflows/rollup.yml index 745231eac..aae3555af 100644 --- a/.github/workflows/rollup.yml +++ b/.github/workflows/rollup.yml @@ -12,6 +12,7 @@ jobs: matrix: branches: - new_im_hooks + - apiX defaults: run: diff --git a/Dalamud.Boot/logging.h b/Dalamud.Boot/logging.h index eff112a1b..1428ec7ff 100644 --- a/Dalamud.Boot/logging.h +++ b/Dalamud.Boot/logging.h @@ -111,9 +111,17 @@ namespace logging { * @param arg1 First format parameter. * @param args Second and further format parameters, if any. */ - template - void print(Level level, const char* fmt, Arg&& arg1, Args&&...args) { - print(level, std::vformat(fmt, std::make_format_args(to_format_arg(std::forward(arg1)), to_format_arg(std::forward(args))...))); + template + void print(Level level, const char* fmt, Arg&& arg1, Args&&... args) { + // make_format_args only accepts references now due to https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2905r2.html + // we can switch std::runtime_format in C++26 :) https://isocpp.org/files/papers/P2918R0.html + auto transformed_args = std::make_tuple(to_format_arg(arg1), to_format_arg(args)...); + auto format_args = std::apply( + [&](auto&... elems) { return std::make_format_args(elems...); }, + transformed_args + ); + + print(level, std::vformat(fmt, format_args)); } template void V(Args&&...args) { print(Level::Verbose, std::forward(args)...); } diff --git a/Dalamud.CorePlugin/Dalamud.CorePlugin.csproj b/Dalamud.CorePlugin/Dalamud.CorePlugin.csproj index f9959a910..3e480154c 100644 --- a/Dalamud.CorePlugin/Dalamud.CorePlugin.csproj +++ b/Dalamud.CorePlugin/Dalamud.CorePlugin.csproj @@ -27,7 +27,7 @@ - + diff --git a/Dalamud.CorePlugin/PluginImpl.cs b/Dalamud.CorePlugin/PluginImpl.cs index 7c9adc6a8..52f54d140 100644 --- a/Dalamud.CorePlugin/PluginImpl.cs +++ b/Dalamud.CorePlugin/PluginImpl.cs @@ -2,7 +2,6 @@ using System; using System.IO; using Dalamud.Configuration.Internal; -using Dalamud.Game; using Dalamud.Game.Command; using Dalamud.Interface.Windowing; using Dalamud.Plugin; diff --git a/Dalamud.sln b/Dalamud.sln index 2d22932dd..d8a8d1d50 100644 --- a/Dalamud.sln +++ b/Dalamud.sln @@ -42,6 +42,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dalamud.Common", "Dalamud.C EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dalamud.LocExporter", "tools\Dalamud.LocExporter\Dalamud.LocExporter.csproj", "{A568929D-6FF6-4DFA-9D14-5D7DC08FA5E0}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InteropGenerator", "lib\FFXIVClientStructs\InteropGenerator\InteropGenerator.csproj", "{3620414C-7DFC-423E-929F-310E19F5D930}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InteropGenerator.Runtime", "lib\FFXIVClientStructs\InteropGenerator.Runtime\InteropGenerator.Runtime.csproj", "{A6AA1C3F-9470-4922-9D3F-D4549657AB22}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -108,6 +112,14 @@ Global {A568929D-6FF6-4DFA-9D14-5D7DC08FA5E0}.Debug|Any CPU.Build.0 = Debug|Any CPU {A568929D-6FF6-4DFA-9D14-5D7DC08FA5E0}.Release|Any CPU.ActiveCfg = Release|Any CPU {A568929D-6FF6-4DFA-9D14-5D7DC08FA5E0}.Release|Any CPU.Build.0 = Release|Any CPU + {3620414C-7DFC-423E-929F-310E19F5D930}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3620414C-7DFC-423E-929F-310E19F5D930}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3620414C-7DFC-423E-929F-310E19F5D930}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3620414C-7DFC-423E-929F-310E19F5D930}.Release|Any CPU.Build.0 = Release|Any CPU + {A6AA1C3F-9470-4922-9D3F-D4549657AB22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A6AA1C3F-9470-4922-9D3F-D4549657AB22}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A6AA1C3F-9470-4922-9D3F-D4549657AB22}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A6AA1C3F-9470-4922-9D3F-D4549657AB22}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -118,6 +130,8 @@ Global {2F7FF0A8-B619-4572-86C7-71E46FE22FB8} = {E15BDA6D-E881-4482-94BA-BE5527E917FF} {C9B87BD7-AF49-41C3-91F1-D550ADEB7833} = {E15BDA6D-E881-4482-94BA-BE5527E917FF} {05AB2F46-268B-4915-806F-DDF813E2D59D} = {E15BDA6D-E881-4482-94BA-BE5527E917FF} + {3620414C-7DFC-423E-929F-310E19F5D930} = {E15BDA6D-E881-4482-94BA-BE5527E917FF} + {A6AA1C3F-9470-4922-9D3F-D4549657AB22} = {E15BDA6D-E881-4482-94BA-BE5527E917FF} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {79B65AC9-C940-410E-AB61-7EA7E12C7599} diff --git a/Dalamud/ClientLanguage.cs b/Dalamud/ClientLanguage.cs index 8f2c52456..1bf1c884a 100644 --- a/Dalamud/ClientLanguage.cs +++ b/Dalamud/ClientLanguage.cs @@ -1,10 +1,11 @@ -namespace Dalamud; +using Dalamud.Utility; -// TODO(v10): Delete this, and use Dalamud.Common.ClientLanguage instead for everything. +namespace Dalamud; /// /// Enum describing the language the game loads in. /// +[Api10ToDo("Delete this, and use Dalamud.Common.ClientLanguage instead for everything.")] public enum ClientLanguage { /// diff --git a/Dalamud/ClientLanguageExtensions.cs b/Dalamud/ClientLanguageExtensions.cs index e19ca1eb1..40ff65867 100644 --- a/Dalamud/ClientLanguageExtensions.cs +++ b/Dalamud/ClientLanguageExtensions.cs @@ -1,10 +1,11 @@ -using System; +using Dalamud.Utility; namespace Dalamud; /// /// Extension methods for the class. /// +[Api10ToDo("Delete this, and use Dalamud.Common.ClientLanguage instead for everything.")] public static class ClientLanguageExtensions { /// diff --git a/Dalamud/Configuration/Internal/DalamudConfiguration.cs b/Dalamud/Configuration/Internal/DalamudConfiguration.cs index 9c5ea6ac9..619d233e1 100644 --- a/Dalamud/Configuration/Internal/DalamudConfiguration.cs +++ b/Dalamud/Configuration/Internal/DalamudConfiguration.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; @@ -7,6 +6,7 @@ using System.Linq; using System.Runtime.InteropServices; using Dalamud.Game.Text; +using Dalamud.Interface; using Dalamud.Interface.FontIdentifier; using Dalamud.Interface.Internal.Windows.PluginInstaller; using Dalamud.Interface.Style; @@ -162,6 +162,12 @@ internal sealed class DalamudConfiguration : IInternalDisposableService [Obsolete("It happens that nobody touched this setting", true)] public float FontGammaLevel { get; set; } = 1.4f; + /// Gets or sets the opacity of the IME state indicator. + /// 0 will hide the state indicator. 1 will make the state indicator fully visible. Values outside the + /// range will be clamped to [0, 1]. + /// See to . + public float ImeStateIndicatorOpacity { get; set; } = 1f; + /// /// Gets or sets a value indicating whether or not plugin UI should be hidden. /// @@ -456,7 +462,7 @@ internal sealed class DalamudConfiguration : IInternalDisposableService /// /// Gets or sets the page of the plugin installer that is shown by default when opened. /// - public PluginInstallerWindow.PluginInstallerOpenKind PluginInstallerOpen { get; set; } = PluginInstallerWindow.PluginInstallerOpenKind.AllPlugins; + public PluginInstallerOpenKind PluginInstallerOpen { get; set; } = PluginInstallerOpenKind.AllPlugins; /// /// Load a configuration from the provided path. diff --git a/Dalamud/Configuration/Internal/DevPluginSettings.cs b/Dalamud/Configuration/Internal/DevPluginSettings.cs index 63d56fdb6..361632a14 100644 --- a/Dalamud/Configuration/Internal/DevPluginSettings.cs +++ b/Dalamud/Configuration/Internal/DevPluginSettings.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; namespace Dalamud.Configuration.Internal; diff --git a/Dalamud/Configuration/Internal/EnvironmentConfiguration.cs b/Dalamud/Configuration/Internal/EnvironmentConfiguration.cs index a251da763..2df9ec5fe 100644 --- a/Dalamud/Configuration/Internal/EnvironmentConfiguration.cs +++ b/Dalamud/Configuration/Internal/EnvironmentConfiguration.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Configuration.Internal; /// diff --git a/Dalamud/Dalamud.cs b/Dalamud/Dalamud.cs index f9d2aff3c..1c9e14e6d 100644 --- a/Dalamud/Dalamud.cs +++ b/Dalamud/Dalamud.cs @@ -33,8 +33,9 @@ internal sealed class Dalamud : IServiceType { #region Internals + private static int shownServiceError = 0; private readonly ManualResetEvent unloadSignal; - + #endregion /// @@ -68,54 +69,47 @@ internal sealed class Dalamud : IServiceType // Set up FFXIVClientStructs this.SetupClientStructsResolver(cacheDir); - - if (!configuration.IsResumeGameAfterPluginLoad) + + void KickoffGameThread() { + Log.Verbose("=============== GAME THREAD KICKOFF ==============="); + Timings.Event("Game thread kickoff"); NativeFunctions.SetEvent(mainThreadContinueEvent); - ServiceManager.InitializeEarlyLoadableServices() - .ContinueWith(t => + } + + void HandleServiceInitFailure(Task t) + { + Log.Error(t.Exception!, "Service initialization failure"); + + if (Interlocked.CompareExchange(ref shownServiceError, 1, 0) != 0) + return; + + Util.Fatal( + "Dalamud failed to load all necessary services.\n\nThe game will continue, but you may not be able to use plugins.", + "Dalamud", false); + } + + ServiceManager.InitializeEarlyLoadableServices() + .ContinueWith( + t => { if (t.IsCompletedSuccessfully) return; - - Log.Error(t.Exception!, "Service initialization failure"); - Util.Fatal( - "Dalamud failed to load all necessary services.\n\nThe game will continue, but you may not be able to use plugins.", - "Dalamud", false); + + HandleServiceInitFailure(t); }); - } - else - { - Task.Run(async () => + + ServiceManager.BlockingResolved.ContinueWith( + t => { - try + if (t.IsCompletedSuccessfully) { - var tasks = new[] - { - ServiceManager.InitializeEarlyLoadableServices(), - ServiceManager.BlockingResolved, - }; - - await Task.WhenAny(tasks); - var faultedTasks = tasks.Where(x => x.IsFaulted).Select(x => (Exception)x.Exception!).ToArray(); - if (faultedTasks.Any()) - throw new AggregateException(faultedTasks); - - NativeFunctions.SetEvent(mainThreadContinueEvent); - - await Task.WhenAll(tasks); - } - catch (Exception e) - { - Log.Error(e, "Service initialization failure"); - Util.Fatal("Dalamud could not initialize correctly. Please report this error. \n\nThe game will continue, but you may not be able to use plugins.", "Dalamud", false); - } - finally - { - NativeFunctions.SetEvent(mainThreadContinueEvent); + KickoffGameThread(); + return; } + + HandleServiceInitFailure(t); }); - } this.DefaultExceptionFilter = NativeFunctions.SetUnhandledExceptionFilter(nint.Zero); NativeFunctions.SetUnhandledExceptionFilter(this.DefaultExceptionFilter); @@ -217,8 +211,10 @@ internal sealed class Dalamud : IServiceType { using (Timings.Start("CS Resolver Init")) { - FFXIVClientStructs.Interop.Resolver.GetInstance.SetupSearchSpace(Service.Get().SearchBase, new FileInfo(Path.Combine(cacheDir.FullName, $"{this.StartInfo.GameVersion}_cs.json"))); - FFXIVClientStructs.Interop.Resolver.GetInstance.Resolve(); + // the resolver tracks version as a field in the json + InteropGenerator.Runtime.Resolver.GetInstance.Setup(Service.Get().SearchBase, $"{this.StartInfo.GameVersion}", new FileInfo(Path.Combine(cacheDir.FullName, "cs.json"))); + FFXIVClientStructs.Interop.Generated.Addresses.Register(); + InteropGenerator.Runtime.Resolver.GetInstance.Resolve(); } } } diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj index 43caf1275..1286f089e 100644 --- a/Dalamud/Dalamud.csproj +++ b/Dalamud/Dalamud.csproj @@ -8,7 +8,7 @@ - 9.1.0.5 + 9.1.0.9 XIV Launcher addon framework $(DalamudVersion) $(DalamudVersion) @@ -69,9 +69,9 @@ - + - + all diff --git a/Dalamud/Data/DataManager.cs b/Dalamud/Data/DataManager.cs index 564b10fae..2398cdb16 100644 --- a/Dalamud/Data/DataManager.cs +++ b/Dalamud/Data/DataManager.cs @@ -1,4 +1,3 @@ -using System.Diagnostics; using System.IO; using System.Threading; @@ -52,15 +51,12 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager DefaultExcelLanguage = this.Language.ToLumina(), }; - var processModule = Process.GetCurrentProcess().MainModule; - if (processModule != null) + this.GameData = new( + Path.Combine(Path.GetDirectoryName(Environment.ProcessPath)!, "sqpack"), + luminaOptions) { - this.GameData = new GameData(Path.Combine(Path.GetDirectoryName(processModule.FileName)!, "sqpack"), luminaOptions); - } - else - { - throw new Exception("Could not main module."); - } + StreamPool = new(), + }; Log.Information("Lumina is ready: {0}", this.GameData.DataPath); @@ -107,7 +103,8 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager } catch (Exception ex) { - Log.Error(ex, "Could not download data."); + Log.Error(ex, "Could not initialize Lumina"); + throw; } } @@ -161,6 +158,7 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager void IInternalDisposableService.DisposeService() { this.luminaCancellationTokenSource.Cancel(); + this.GameData.Dispose(); } private class LauncherTroubleshootingInfo diff --git a/Dalamud/Game/Addon/Events/AddonEventEntry.cs b/Dalamud/Game/Addon/Events/AddonEventEntry.cs index a7430acf0..cf160bf6c 100644 --- a/Dalamud/Game/Addon/Events/AddonEventEntry.cs +++ b/Dalamud/Game/Addon/Events/AddonEventEntry.cs @@ -21,11 +21,11 @@ internal unsafe class AddonEventEntry /// Gets the pointer to the addons AtkUnitBase. /// required public nint Addon { get; init; } - + /// /// Gets the name of the addon this args referrers to. /// - public string AddonName => this.Addon == nint.Zero ? InvalidAddonName : this.addonName ??= MemoryHelper.ReadString((nint)((AtkUnitBase*)this.Addon)->Name, 0x20); + public string AddonName => this.Addon == nint.Zero ? InvalidAddonName : this.addonName ??= ((AtkUnitBase*)this.Addon)->NameString; /// /// Gets the pointer to the event source. diff --git a/Dalamud/Game/Addon/Events/AddonEventListener.cs b/Dalamud/Game/Addon/Events/AddonEventListener.cs index a2498d5a7..15c33e0ab 100644 --- a/Dalamud/Game/Addon/Events/AddonEventListener.cs +++ b/Dalamud/Game/Addon/Events/AddonEventListener.cs @@ -23,10 +23,10 @@ internal unsafe class AddonEventListener : IDisposable this.receiveEventDelegate = eventHandler; this.eventListener = (AtkEventListener*)Marshal.AllocHGlobal(sizeof(AtkEventListener)); - this.eventListener->vtbl = (void*)Marshal.AllocHGlobal(sizeof(void*) * 3); - this.eventListener->vfunc[0] = (delegate* unmanaged)&NullSub; - this.eventListener->vfunc[1] = (delegate* unmanaged)&NullSub; - this.eventListener->vfunc[2] = (void*)Marshal.GetFunctionPointerForDelegate(this.receiveEventDelegate); + this.eventListener->VirtualTable = (AtkEventListener.AtkEventListenerVirtualTable*)Marshal.AllocHGlobal(sizeof(void*) * 3); + this.eventListener->VirtualTable->Dtor = (delegate* unmanaged)(delegate* unmanaged)&NullSub; + this.eventListener->VirtualTable->ReceiveGlobalEvent = (delegate* unmanaged)(delegate* unmanaged)&NullSub; + this.eventListener->VirtualTable->ReceiveEvent = (delegate* unmanaged)Marshal.GetFunctionPointerForDelegate(this.receiveEventDelegate); } /// @@ -49,7 +49,7 @@ internal unsafe class AddonEventListener : IDisposable { if (this.eventListener is null) return; - Marshal.FreeHGlobal((nint)this.eventListener->vtbl); + Marshal.FreeHGlobal((nint)this.eventListener->VirtualTable); Marshal.FreeHGlobal((nint)this.eventListener); this.eventListener = null; diff --git a/Dalamud/Game/Addon/Events/AddonEventManager.cs b/Dalamud/Game/Addon/Events/AddonEventManager.cs index a9b9ef5fa..dda05a6bc 100644 --- a/Dalamud/Game/Addon/Events/AddonEventManager.cs +++ b/Dalamud/Game/Addon/Events/AddonEventManager.cs @@ -173,14 +173,14 @@ internal unsafe class AddonEventManager : IInternalDisposableService { try { - var atkStage = AtkStage.GetSingleton(); + var atkStage = AtkStage.Instance(); if (this.cursorOverride is not null && atkStage is not null) { var cursor = (AddonCursorType)atkStage->AtkCursor.Type; if (cursor != this.cursorOverride) { - AtkStage.GetSingleton()->AtkCursor.SetCursorType((AtkCursor.CursorType)this.cursorOverride, 1); + AtkStage.Instance()->AtkCursor.SetCursorType((AtkCursor.CursorType)this.cursorOverride, 1); } return nint.Zero; @@ -221,7 +221,7 @@ internal class AddonEventManagerPluginScoped : IInternalDisposableService, IAddo { this.plugin = plugin; - this.eventManagerService.AddPluginEventController(plugin.Manifest.WorkingPluginId); + this.eventManagerService.AddPluginEventController(plugin.EffectiveWorkingPluginId); } /// @@ -233,16 +233,16 @@ internal class AddonEventManagerPluginScoped : IInternalDisposableService, IAddo this.eventManagerService.ResetCursor(); } - this.eventManagerService.RemovePluginEventController(this.plugin.Manifest.WorkingPluginId); + this.eventManagerService.RemovePluginEventController(this.plugin.EffectiveWorkingPluginId); } /// public IAddonEventHandle? AddEvent(IntPtr atkUnitBase, IntPtr atkResNode, AddonEventType eventType, IAddonEventManager.AddonEventHandler eventHandler) - => this.eventManagerService.AddEvent(this.plugin.Manifest.WorkingPluginId, atkUnitBase, atkResNode, eventType, eventHandler); + => this.eventManagerService.AddEvent(this.plugin.EffectiveWorkingPluginId, atkUnitBase, atkResNode, eventType, eventHandler); /// public void RemoveEvent(IAddonEventHandle eventHandle) - => this.eventManagerService.RemoveEvent(this.plugin.Manifest.WorkingPluginId, eventHandle); + => this.eventManagerService.RemoveEvent(this.plugin.EffectiveWorkingPluginId, eventHandle); /// public void SetCursor(AddonCursorType cursor) diff --git a/Dalamud/Game/Addon/Events/PluginEventController.cs b/Dalamud/Game/Addon/Events/PluginEventController.cs index 3ba067a6d..a0461ea99 100644 --- a/Dalamud/Game/Addon/Events/PluginEventController.cs +++ b/Dalamud/Game/Addon/Events/PluginEventController.cs @@ -5,6 +5,7 @@ using Dalamud.Game.Gui; using Dalamud.Logging.Internal; using Dalamud.Memory; using Dalamud.Plugin.Services; + using FFXIVClientStructs.FFXIV.Component.GUI; namespace Dalamud.Game.Addon.Events; @@ -46,7 +47,7 @@ internal unsafe class PluginEventController : IDisposable var eventHandle = new AddonEventHandle { - AddonName = MemoryHelper.ReadStringNullTerminated((nint)addon->Name), + AddonName = addon->NameString, ParamKey = eventId, EventType = atkEventType, EventGuid = eventGuid, diff --git a/Dalamud/Game/Addon/Lifecycle/AddonArgTypes/AddonArgs.cs b/Dalamud/Game/Addon/Lifecycle/AddonArgTypes/AddonArgs.cs index 1095202cc..36083337e 100644 --- a/Dalamud/Game/Addon/Lifecycle/AddonArgTypes/AddonArgs.cs +++ b/Dalamud/Game/Addon/Lifecycle/AddonArgTypes/AddonArgs.cs @@ -1,4 +1,6 @@ -using Dalamud.Memory; +using System.Runtime.CompilerServices; + +using Dalamud.Memory; using FFXIVClientStructs.FFXIV.Component.GUI; @@ -64,9 +66,14 @@ public abstract unsafe class AddonArgs return false; var addonPointer = (AtkUnitBase*)this.Addon; - if (addonPointer->Name is null) return false; + if (addonPointer->Name[0] == 0) return false; - return MemoryHelper.EqualsZeroTerminatedString(name, (nint)addonPointer->Name, null, 0x20); + // note: might want to rewrite this to just compare to NameString + return MemoryHelper.EqualsZeroTerminatedString( + name, + (nint)Unsafe.AsPointer(ref addonPointer->Name[0]), + null, + 0x20); } /// @@ -78,8 +85,8 @@ public abstract unsafe class AddonArgs if (this.Addon == nint.Zero) return InvalidAddon; var addonPointer = (AtkUnitBase*)this.Addon; - if (addonPointer->Name is null) return InvalidAddon; + if (addonPointer->Name[0] == 0) return InvalidAddon; - return this.addonName ??= MemoryHelper.ReadString((nint)addonPointer->Name, 0x20); + return this.addonName ??= addonPointer->NameString; } } diff --git a/Dalamud/Game/Addon/Lifecycle/AddonLifecycle.cs b/Dalamud/Game/Addon/Lifecycle/AddonLifecycle.cs index eefb3b5e9..7270fb437 100644 --- a/Dalamud/Game/Addon/Lifecycle/AddonLifecycle.cs +++ b/Dalamud/Game/Addon/Lifecycle/AddonLifecycle.cs @@ -10,6 +10,7 @@ using Dalamud.IoC.Internal; using Dalamud.Logging.Internal; using Dalamud.Memory; using Dalamud.Plugin.Services; + using FFXIVClientStructs.FFXIV.Component.GUI; namespace Dalamud.Game.Addon.Lifecycle; @@ -133,6 +134,9 @@ internal unsafe class AddonLifecycle : IInternalDisposableService /// The listener to unregister. internal void UnregisterListener(AddonLifecycleEventListener listener) { + // Set removed state to true immediately, then lazily remove it from the EventListeners list on next Framework Update. + listener.Removed = true; + this.framework.RunOnTick(() => { this.EventListeners.Remove(listener); @@ -167,6 +171,10 @@ internal unsafe class AddonLifecycle : IInternalDisposableService if (listener.EventType != eventType) continue; + // If the listener is pending removal, and is waiting until the next Framework Update, don't invoke listener. + if (listener.Removed) + continue; + // Match on string.empty for listeners that want events for all addons. if (!string.IsNullOrWhiteSpace(listener.AddonName) && !args.IsAddon(listener.AddonName)) continue; @@ -186,8 +194,8 @@ internal unsafe class AddonLifecycle : IInternalDisposableService { // Hook the addon's ReceiveEvent function here, but only enable the hook if we have an active listener. // Disallows hooking the core internal event handler. - var addonName = MemoryHelper.ReadStringNullTerminated((nint)addon->Name); - var receiveEventAddress = (nint)addon->VTable->ReceiveEvent; + var addonName = addon->NameString; + var receiveEventAddress = (nint)addon->VirtualTable->ReceiveEvent; if (receiveEventAddress != this.disallowedReceiveEventAddress) { // If we have a ReceiveEvent listener already made for this hook address, add this addon's name to that handler. @@ -267,7 +275,7 @@ internal unsafe class AddonLifecycle : IInternalDisposableService { try { - var addonName = MemoryHelper.ReadStringNullTerminated((nint)atkUnitBase[0]->Name); + var addonName = atkUnitBase[0]->NameString; this.UnregisterReceiveEventHook(addonName); } catch (Exception e) @@ -363,7 +371,7 @@ internal unsafe class AddonLifecycle : IInternalDisposableService try { - addon->OnUpdate(numberArrayData, stringArrayData); + addon->OnRequestedUpdate(numberArrayData, stringArrayData); } catch (Exception e) { diff --git a/Dalamud/Game/Addon/Lifecycle/AddonLifecycleEventListener.cs b/Dalamud/Game/Addon/Lifecycle/AddonLifecycleEventListener.cs index 6464a1edd..9d411cdbc 100644 --- a/Dalamud/Game/Addon/Lifecycle/AddonLifecycleEventListener.cs +++ b/Dalamud/Game/Addon/Lifecycle/AddonLifecycleEventListener.cs @@ -26,6 +26,11 @@ internal class AddonLifecycleEventListener /// public string AddonName { get; init; } + /// + /// Gets or sets a value indicating whether this event has been unregistered. + /// + public bool Removed { get; set; } + /// /// Gets the event type this listener is looking for. /// diff --git a/Dalamud/Game/Addon/Lifecycle/AddonLifecycleReceiveEventListener.cs b/Dalamud/Game/Addon/Lifecycle/AddonLifecycleReceiveEventListener.cs index fd3b5d79d..90a8eb844 100644 --- a/Dalamud/Game/Addon/Lifecycle/AddonLifecycleReceiveEventListener.cs +++ b/Dalamud/Game/Addon/Lifecycle/AddonLifecycleReceiveEventListener.cs @@ -4,6 +4,7 @@ using Dalamud.Game.Addon.Lifecycle.AddonArgTypes; using Dalamud.Hooking; using Dalamud.Logging.Internal; using Dalamud.Memory; + using FFXIVClientStructs.FFXIV.Component.GUI; namespace Dalamud.Game.Addon.Lifecycle; @@ -71,7 +72,7 @@ internal unsafe class AddonLifecycleReceiveEventListener : IDisposable private void OnReceiveEvent(AtkUnitBase* addon, AtkEventType eventType, int eventParam, AtkEvent* atkEvent, nint data) { // Check that we didn't get here through a call to another addons handler. - var addonName = MemoryHelper.ReadString((nint)addon->Name, 0x20); + var addonName = addon->NameString; if (!this.AddonNames.Contains(addonName)) { this.Hook!.Original(addon, eventType, eventParam, atkEvent, data); diff --git a/Dalamud/Game/BaseAddressResolver.cs b/Dalamud/Game/BaseAddressResolver.cs index 7a455aea0..4133117d7 100644 --- a/Dalamud/Game/BaseAddressResolver.cs +++ b/Dalamud/Game/BaseAddressResolver.cs @@ -1,10 +1,7 @@ -using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; -using JetBrains.Annotations; - namespace Dalamud.Game; /// diff --git a/Dalamud/Game/ChatHandlers.cs b/Dalamud/Game/ChatHandlers.cs index fa966f30a..20beaefc9 100644 --- a/Dalamud/Game/ChatHandlers.cs +++ b/Dalamud/Game/ChatHandlers.cs @@ -12,11 +12,11 @@ using Dalamud.Game.Gui; using Dalamud.Game.Text; using Dalamud.Game.Text.SeStringHandling; using Dalamud.Game.Text.SeStringHandling.Payloads; +using Dalamud.Interface; using Dalamud.Interface.ImGuiNotification; using Dalamud.Interface.ImGuiNotification.Internal; using Dalamud.Interface.Internal; using Dalamud.Interface.Internal.Windows; -using Dalamud.Interface.Internal.Windows.PluginInstaller; using Dalamud.Logging.Internal; using Dalamud.Plugin.Internal; using Dalamud.Utility; @@ -125,7 +125,7 @@ internal class ChatHandlers : IServiceType this.openInstallerWindowLink = chatGui.AddChatLinkHandler("Dalamud", 1001, (i, m) => { - Service.GetNullable()?.OpenPluginInstallerTo(PluginInstallerWindow.PluginInstallerOpenKind.InstalledPlugins); + Service.GetNullable()?.OpenPluginInstallerTo(PluginInstallerOpenKind.InstalledPlugins); }); } @@ -139,7 +139,7 @@ internal class ChatHandlers : IServiceType /// public bool IsAutoUpdateComplete { get; private set; } - private void OnCheckMessageHandled(XivChatType type, uint senderid, ref SeString sender, ref SeString message, ref bool isHandled) + private void OnCheckMessageHandled(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled) { var textVal = message.TextValue; @@ -165,7 +165,7 @@ internal class ChatHandlers : IServiceType } } - private void OnChatMessage(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled) + private void OnChatMessage(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled) { var clientState = Service.GetNullable(); if (clientState == null) diff --git a/Dalamud/Game/ClientState/Aetherytes/AetheryteEntry.cs b/Dalamud/Game/ClientState/Aetherytes/AetheryteEntry.cs index 8113e0593..1c169d37a 100644 --- a/Dalamud/Game/ClientState/Aetherytes/AetheryteEntry.cs +++ b/Dalamud/Game/ClientState/Aetherytes/AetheryteEntry.cs @@ -60,9 +60,9 @@ public sealed class AetheryteEntry public bool IsSharedHouse => this.data.IsSharedHouse; /// - /// Gets a value indicating whether this Aetheryte is an Appartment or not. + /// Gets a value indicating whether this Aetheryte is an Apartment or not. /// - public bool IsAppartment => this.data.IsAppartment; + public bool IsApartment => this.data.IsApartment; /// /// Gets the Aetheryte data related to this aetheryte. diff --git a/Dalamud/Game/ClientState/Aetherytes/AetheryteList.cs b/Dalamud/Game/ClientState/Aetherytes/AetheryteList.cs index f4115511d..4793bcea5 100644 --- a/Dalamud/Game/ClientState/Aetherytes/AetheryteList.cs +++ b/Dalamud/Game/ClientState/Aetherytes/AetheryteList.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Plugin.Services; + using FFXIVClientStructs.FFXIV.Client.Game.UI; using Serilog; @@ -44,7 +45,7 @@ internal sealed unsafe partial class AetheryteList : IServiceType, IAetheryteLis if (this.telepoInstance->TeleportList.First == this.telepoInstance->TeleportList.Last) return 0; - return (int)this.telepoInstance->TeleportList.Size(); + return this.telepoInstance->TeleportList.Count; } } @@ -61,7 +62,7 @@ internal sealed unsafe partial class AetheryteList : IServiceType, IAetheryteLis if (this.clientState.LocalPlayer == null) return null; - return new AetheryteEntry(this.telepoInstance->TeleportList.Get((ulong)index)); + return new AetheryteEntry(this.telepoInstance->TeleportList[index]); } } diff --git a/Dalamud/Game/ClientState/Buddy/BuddyList.cs b/Dalamud/Game/ClientState/Buddy/BuddyList.cs index 949ccae25..9719b0cb3 100644 --- a/Dalamud/Game/ClientState/Buddy/BuddyList.cs +++ b/Dalamud/Game/ClientState/Buddy/BuddyList.cs @@ -1,11 +1,12 @@ -using System; using System.Collections; using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Plugin.Services; + using Serilog; namespace Dalamud.Game.ClientState.Buddy; @@ -97,13 +98,13 @@ internal sealed partial class BuddyList : IServiceType, IBuddyList /// public unsafe IntPtr GetCompanionBuddyMemberAddress() { - return (IntPtr)(&this.BuddyListStruct->Companion); + return (IntPtr)this.BuddyListStruct->CompanionInfo.Companion; } /// public unsafe IntPtr GetPetBuddyMemberAddress() { - return (IntPtr)(&this.BuddyListStruct->Pet); + return (IntPtr)this.BuddyListStruct->PetInfo.Pet; } /// @@ -112,7 +113,7 @@ internal sealed partial class BuddyList : IServiceType, IBuddyList if (index < 0 || index >= 3) return IntPtr.Zero; - return (IntPtr)(this.BuddyListStruct->BattleBuddies + (index * BuddyMemberSize)); + return (IntPtr)Unsafe.AsPointer(ref this.BuddyListStruct->BattleBuddies[index]); } /// diff --git a/Dalamud/Game/ClientState/Buddy/BuddyMember.cs b/Dalamud/Game/ClientState/Buddy/BuddyMember.cs index 80a510ce5..3b5c2f910 100644 --- a/Dalamud/Game/ClientState/Buddy/BuddyMember.cs +++ b/Dalamud/Game/ClientState/Buddy/BuddyMember.cs @@ -1,5 +1,3 @@ -using System; - using Dalamud.Game.ClientState.Objects; using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Game.ClientState.Resolvers; @@ -31,7 +29,7 @@ public unsafe class BuddyMember /// /// Gets the object ID of this buddy. /// - public uint ObjectId => this.Struct->ObjectID; + public uint ObjectId => this.Struct->EntityId; /// /// Gets the actor associated with this buddy. @@ -54,7 +52,7 @@ public unsafe class BuddyMember /// /// Gets the data ID of this buddy. /// - public uint DataID => this.Struct->DataID; + public uint DataID => this.Struct->DataId; /// /// Gets the Mount data related to this buddy. It should only be used with companion buddies. diff --git a/Dalamud/Game/ClientState/ClientStateAddressResolver.cs b/Dalamud/Game/ClientState/ClientStateAddressResolver.cs index 73ed24e95..0caced248 100644 --- a/Dalamud/Game/ClientState/ClientStateAddressResolver.cs +++ b/Dalamud/Game/ClientState/ClientStateAddressResolver.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState; /// diff --git a/Dalamud/Game/ClientState/Conditions/Condition.cs b/Dalamud/Game/ClientState/Conditions/Condition.cs index 98132798f..d281d7aec 100644 --- a/Dalamud/Game/ClientState/Conditions/Condition.cs +++ b/Dalamud/Game/ClientState/Conditions/Condition.cs @@ -1,6 +1,7 @@ using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Plugin.Services; + using Serilog; namespace Dalamud.Game.ClientState.Conditions; diff --git a/Dalamud/Game/ClientState/Fates/Fate.cs b/Dalamud/Game/ClientState/Fates/Fate.cs index 440767846..47b32dce0 100644 --- a/Dalamud/Game/ClientState/Fates/Fate.cs +++ b/Dalamud/Game/ClientState/Fates/Fate.cs @@ -1,4 +1,3 @@ -using System; using System.Numerics; using Dalamud.Data; diff --git a/Dalamud/Game/ClientState/Fates/FateTable.cs b/Dalamud/Game/ClientState/Fates/FateTable.cs index 182db18d4..0f8693d4d 100644 --- a/Dalamud/Game/ClientState/Fates/FateTable.cs +++ b/Dalamud/Game/ClientState/Fates/FateTable.cs @@ -1,10 +1,10 @@ -using System; using System.Collections; using System.Collections.Generic; using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Plugin.Services; + using Serilog; namespace Dalamud.Game.ClientState.Fates; @@ -49,7 +49,7 @@ internal sealed partial class FateTable : IServiceType, IFateTable if (Struct->Fates.First == null || Struct->Fates.Last == null) return 0; - return (int)Struct->Fates.Size(); + return Struct->Fates.Count; } } @@ -89,7 +89,7 @@ internal sealed partial class FateTable : IServiceType, IFateTable if (fateTable == IntPtr.Zero) return IntPtr.Zero; - return (IntPtr)this.Struct->Fates.Get((ulong)index).Value; + return (IntPtr)this.Struct->Fates[index].Value; } /// diff --git a/Dalamud/Game/ClientState/GamePad/GamepadButtons.cs b/Dalamud/Game/ClientState/GamePad/GamepadButtons.cs index a73f72857..5718c7ab6 100644 --- a/Dalamud/Game/ClientState/GamePad/GamepadButtons.cs +++ b/Dalamud/Game/ClientState/GamePad/GamepadButtons.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState.GamePad; /// diff --git a/Dalamud/Game/ClientState/GamePad/GamepadState.cs b/Dalamud/Game/ClientState/GamePad/GamepadState.cs index c684d1ec6..2e339b42f 100644 --- a/Dalamud/Game/ClientState/GamePad/GamepadState.cs +++ b/Dalamud/Game/ClientState/GamePad/GamepadState.cs @@ -1,10 +1,10 @@ -using System; using System.Numerics; using Dalamud.Hooking; using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Plugin.Services; + using ImGuiNET; using Serilog; diff --git a/Dalamud/Game/ClientState/JobGauge/Enums/Nadi.cs b/Dalamud/Game/ClientState/JobGauge/Enums/Nadi.cs index 159ecbb26..dd3434389 100644 --- a/Dalamud/Game/ClientState/JobGauge/Enums/Nadi.cs +++ b/Dalamud/Game/ClientState/JobGauge/Enums/Nadi.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Game.ClientState.JobGauge.Enums; +namespace Dalamud.Game.ClientState.JobGauge.Enums; /// /// MNK Nadi types. diff --git a/Dalamud/Game/ClientState/JobGauge/Enums/Sen.cs b/Dalamud/Game/ClientState/JobGauge/Enums/Sen.cs index bdd98b750..a1a6035c6 100644 --- a/Dalamud/Game/ClientState/JobGauge/Enums/Sen.cs +++ b/Dalamud/Game/ClientState/JobGauge/Enums/Sen.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState.JobGauge.Enums; /// diff --git a/Dalamud/Game/ClientState/JobGauge/JobGauges.cs b/Dalamud/Game/ClientState/JobGauge/JobGauges.cs index 5085c361c..8a0a84436 100644 --- a/Dalamud/Game/ClientState/JobGauge/JobGauges.cs +++ b/Dalamud/Game/ClientState/JobGauge/JobGauges.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Reflection; @@ -6,6 +5,7 @@ using Dalamud.Game.ClientState.JobGauge.Types; using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Plugin.Services; + using Serilog; namespace Dalamud.Game.ClientState.JobGauge; diff --git a/Dalamud/Game/ClientState/JobGauge/Types/ASTGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/ASTGauge.cs index 4549ff9c9..ae75aae3d 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/ASTGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/ASTGauge.cs @@ -1,4 +1,3 @@ -using System; using System.Linq; using Dalamud.Game.ClientState.JobGauge.Enums; diff --git a/Dalamud/Game/ClientState/JobGauge/Types/BLMGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/BLMGauge.cs index 4ed8eabe4..6b59aeef3 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/BLMGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/BLMGauge.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState.JobGauge.Types; /// diff --git a/Dalamud/Game/ClientState/JobGauge/Types/BRDGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/BRDGauge.cs index 1a7f7bd47..bfcf3cc38 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/BRDGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/BRDGauge.cs @@ -1,5 +1,3 @@ -using System; - using Dalamud.Game.ClientState.JobGauge.Enums; using FFXIVClientStructs.FFXIV.Client.Game.Gauge; diff --git a/Dalamud/Game/ClientState/JobGauge/Types/DNCGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/DNCGauge.cs index 455c5bca0..73a3819af 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/DNCGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/DNCGauge.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState.JobGauge.Types; /// diff --git a/Dalamud/Game/ClientState/JobGauge/Types/DRGGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/DRGGauge.cs index 39e39b41b..de530b699 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/DRGGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/DRGGauge.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState.JobGauge.Types; /// diff --git a/Dalamud/Game/ClientState/JobGauge/Types/DRKGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/DRKGauge.cs index 25a245ac6..834087040 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/DRKGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/DRKGauge.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState.JobGauge.Types; /// diff --git a/Dalamud/Game/ClientState/JobGauge/Types/GNBGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/GNBGauge.cs index 4acc9a712..5c1f6c1c1 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/GNBGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/GNBGauge.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState.JobGauge.Types; /// diff --git a/Dalamud/Game/ClientState/JobGauge/Types/JobGaugeBase.cs b/Dalamud/Game/ClientState/JobGauge/Types/JobGaugeBase.cs index 09280cf7c..4f14fb8d1 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/JobGaugeBase.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/JobGaugeBase.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState.JobGauge.Types; /// diff --git a/Dalamud/Game/ClientState/JobGauge/Types/JobGaugeBase{T}.cs b/Dalamud/Game/ClientState/JobGauge/Types/JobGaugeBase{T}.cs index dbe107d2c..624b98d51 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/JobGaugeBase{T}.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/JobGaugeBase{T}.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState.JobGauge.Types; /// diff --git a/Dalamud/Game/ClientState/JobGauge/Types/MCHGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/MCHGauge.cs index 76e3b00c4..b59f8e0ea 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/MCHGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/MCHGauge.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState.JobGauge.Types; /// diff --git a/Dalamud/Game/ClientState/JobGauge/Types/MNKGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/MNKGauge.cs index 4f572a7c4..98189068e 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/MNKGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/MNKGauge.cs @@ -1,4 +1,3 @@ -using System; using System.Linq; using Dalamud.Game.ClientState.JobGauge.Enums; diff --git a/Dalamud/Game/ClientState/JobGauge/Types/NINGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/NINGauge.cs index 998ee10a4..1e3b6df3c 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/NINGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/NINGauge.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState.JobGauge.Types; /// diff --git a/Dalamud/Game/ClientState/JobGauge/Types/PLDGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/PLDGauge.cs index 8998200c2..e14dc36e6 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/PLDGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/PLDGauge.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState.JobGauge.Types; /// diff --git a/Dalamud/Game/ClientState/JobGauge/Types/RDMGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/RDMGauge.cs index 0b10a2b4d..b53df9a05 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/RDMGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/RDMGauge.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState.JobGauge.Types; /// diff --git a/Dalamud/Game/ClientState/JobGauge/Types/RPRGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/RPRGauge.cs index 7ddafcc4c..967cdc824 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/RPRGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/RPRGauge.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState.JobGauge.Types; /// diff --git a/Dalamud/Game/ClientState/JobGauge/Types/SAMGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/SAMGauge.cs index 4d4c2d397..f3417f002 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/SAMGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/SAMGauge.cs @@ -1,5 +1,3 @@ -using System; - using Dalamud.Game.ClientState.JobGauge.Enums; namespace Dalamud.Game.ClientState.JobGauge.Types; diff --git a/Dalamud/Game/ClientState/JobGauge/Types/SCHGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/SCHGauge.cs index ae8c87f3a..e0cc8e384 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/SCHGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/SCHGauge.cs @@ -1,5 +1,3 @@ -using System; - using Dalamud.Game.ClientState.JobGauge.Enums; namespace Dalamud.Game.ClientState.JobGauge.Types; diff --git a/Dalamud/Game/ClientState/JobGauge/Types/SGEGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/SGEGauge.cs index 4775809c1..f6da8540b 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/SGEGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/SGEGauge.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState.JobGauge.Types; /// diff --git a/Dalamud/Game/ClientState/JobGauge/Types/SMNGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/SMNGauge.cs index 6b03a4c6e..aa7e27fd2 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/SMNGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/SMNGauge.cs @@ -1,5 +1,3 @@ -using System; - using Dalamud.Game.ClientState.JobGauge.Enums; using FFXIVClientStructs.FFXIV.Client.Game.Gauge; diff --git a/Dalamud/Game/ClientState/JobGauge/Types/WARGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/WARGauge.cs index 2a50e9d24..49cb4f7a5 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/WARGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/WARGauge.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState.JobGauge.Types; /// diff --git a/Dalamud/Game/ClientState/JobGauge/Types/WHMGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/WHMGauge.cs index afe19f59d..23af3c9a7 100644 --- a/Dalamud/Game/ClientState/JobGauge/Types/WHMGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge/Types/WHMGauge.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState.JobGauge.Types; /// diff --git a/Dalamud/Game/ClientState/Keys/KeyState.cs b/Dalamud/Game/ClientState/Keys/KeyState.cs index b32a7d88b..73a3da376 100644 --- a/Dalamud/Game/ClientState/Keys/KeyState.cs +++ b/Dalamud/Game/ClientState/Keys/KeyState.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; @@ -6,6 +5,7 @@ using System.Runtime.InteropServices; using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Plugin.Services; + using Serilog; namespace Dalamud.Game.ClientState.Keys; diff --git a/Dalamud/Game/ClientState/Keys/VirtualKeyAttribute.cs b/Dalamud/Game/ClientState/Keys/VirtualKeyAttribute.cs index 6d0750f0d..0a46b5122 100644 --- a/Dalamud/Game/ClientState/Keys/VirtualKeyAttribute.cs +++ b/Dalamud/Game/ClientState/Keys/VirtualKeyAttribute.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Game.ClientState.Keys; +namespace Dalamud.Game.ClientState.Keys; /// /// Attribute describing a VirtualKey. diff --git a/Dalamud/Game/ClientState/Objects/Enums/StatusFlags.cs b/Dalamud/Game/ClientState/Objects/Enums/StatusFlags.cs index 2fed2a655..7f642f649 100644 --- a/Dalamud/Game/ClientState/Objects/Enums/StatusFlags.cs +++ b/Dalamud/Game/ClientState/Objects/Enums/StatusFlags.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.ClientState.Objects.Enums; /// diff --git a/Dalamud/Game/ClientState/Objects/ObjectTable.cs b/Dalamud/Game/ClientState/Objects/ObjectTable.cs index b36b3ce92..30bfc5d6f 100644 --- a/Dalamud/Game/ClientState/Objects/ObjectTable.cs +++ b/Dalamud/Game/ClientState/Objects/ObjectTable.cs @@ -83,16 +83,16 @@ internal sealed partial class ObjectTable : IServiceType, IObjectTable } /// - public GameObject? SearchById(ulong objectId) + public GameObject? SearchById(ulong gameObjectId) { _ = this.WarnMultithreadedUsage(); - if (objectId is GameObject.InvalidGameObjectId or 0) + if (gameObjectId is 0) return null; foreach (var e in this.cachedObjectTable) { - if (e.Update() is { } o && o.ObjectId == objectId) + if (e.Update() is { } o && o.GameObjectId == gameObjectId) return o; } diff --git a/Dalamud/Game/ClientState/Objects/SubKinds/EventObj.cs b/Dalamud/Game/ClientState/Objects/SubKinds/EventObj.cs index 9d977ec95..ee2b62f0f 100644 --- a/Dalamud/Game/ClientState/Objects/SubKinds/EventObj.cs +++ b/Dalamud/Game/ClientState/Objects/SubKinds/EventObj.cs @@ -1,5 +1,3 @@ -using System; - using Dalamud.Game.ClientState.Objects.Types; namespace Dalamud.Game.ClientState.Objects.SubKinds; diff --git a/Dalamud/Game/ClientState/Objects/SubKinds/Npc.cs b/Dalamud/Game/ClientState/Objects/SubKinds/Npc.cs index 802e647ff..ee4f350a0 100644 --- a/Dalamud/Game/ClientState/Objects/SubKinds/Npc.cs +++ b/Dalamud/Game/ClientState/Objects/SubKinds/Npc.cs @@ -1,5 +1,3 @@ -using System; - using Dalamud.Game.ClientState.Objects.Types; namespace Dalamud.Game.ClientState.Objects.SubKinds; diff --git a/Dalamud/Game/ClientState/Objects/SubKinds/PlayerCharacter.cs b/Dalamud/Game/ClientState/Objects/SubKinds/PlayerCharacter.cs index 407aada26..34ab1e19e 100644 --- a/Dalamud/Game/ClientState/Objects/SubKinds/PlayerCharacter.cs +++ b/Dalamud/Game/ClientState/Objects/SubKinds/PlayerCharacter.cs @@ -21,15 +21,15 @@ public unsafe class PlayerCharacter : BattleChara /// /// Gets the current world of the character. /// - public ExcelResolver CurrentWorld => new(this.Struct->Character.CurrentWorld); + public ExcelResolver CurrentWorld => new(this.Struct->CurrentWorld); /// /// Gets the home world of the character. /// - public ExcelResolver HomeWorld => new(this.Struct->Character.HomeWorld); + public ExcelResolver HomeWorld => new(this.Struct->HomeWorld); /// /// Gets the target actor ID of the PlayerCharacter. /// - public override ulong TargetObjectId => this.Struct->Character.Gaze.Controller.GazesSpan[0].TargetInfo.TargetId; + public override ulong TargetObjectId => this.Struct->LookAt.Controller.Params[0].TargetParam.TargetId; } diff --git a/Dalamud/Game/ClientState/Objects/TargetManager.cs b/Dalamud/Game/ClientState/Objects/TargetManager.cs index 844813af4..92aaabd75 100644 --- a/Dalamud/Game/ClientState/Objects/TargetManager.cs +++ b/Dalamud/Game/ClientState/Objects/TargetManager.cs @@ -1,8 +1,7 @@ -using System; - using Dalamud.Game.ClientState.Objects.Types; using Dalamud.IoC; using Dalamud.IoC.Internal; + #pragma warning disable CS0618 namespace Dalamud.Game.ClientState.Objects; diff --git a/Dalamud/Game/ClientState/Objects/Types/BattleChara.cs b/Dalamud/Game/ClientState/Objects/Types/BattleChara.cs index 0c5d16675..e7adbbfd2 100644 --- a/Dalamud/Game/ClientState/Objects/Types/BattleChara.cs +++ b/Dalamud/Game/ClientState/Objects/Types/BattleChara.cs @@ -1,5 +1,3 @@ -using System; - using Dalamud.Game.ClientState.Statuses; using Dalamud.Utility; @@ -23,37 +21,37 @@ public unsafe class BattleChara : Character /// /// Gets the current status effects. /// - public StatusList StatusList => new(this.Struct->GetStatusManager); + public StatusList StatusList => new(this.Struct->GetStatusManager()); /// /// Gets a value indicating whether the chara is currently casting. /// - public bool IsCasting => this.Struct->GetCastInfo->IsCasting > 0; + public bool IsCasting => this.Struct->GetCastInfo()->IsCasting > 0; /// /// Gets a value indicating whether the cast is interruptible. /// - public bool IsCastInterruptible => this.Struct->GetCastInfo->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->GetCastInfo->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->GetCastInfo->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->GetCastInfo->CastTargetID; + public ulong CastTargetObjectId => this.Struct->GetCastInfo()->CastTargetId; /// /// Gets the current casting time of the spell being cast by the chara. /// - public float CurrentCastTime => this.Struct->GetCastInfo->CurrentCastTime; + public float CurrentCastTime => this.Struct->GetCastInfo()->CurrentCastTime; /// /// Gets the total casting time of the spell being cast by the chara. @@ -63,7 +61,7 @@ public unsafe class BattleChara : Character /// Use AdjustedTotalCastTime if you always need the total cast time. /// [Api10ToDo("Rename so it is not confused with AdjustedTotalCastTime")] - public float TotalCastTime => this.Struct->GetCastInfo->TotalCastTime; + public float TotalCastTime => this.Struct->GetCastInfo()->TotalCastTime; /// /// Gets the plus any adjustments from the game, such as Action offset 2B. Used for display purposes. @@ -72,7 +70,7 @@ public unsafe class BattleChara : Character /// This is the actual total cast time for all actions. /// [Api10ToDo("Rename so it is not confused with TotalCastTime")] - public float AdjustedTotalCastTime => this.Struct->GetCastInfo->AdjustedTotalCastTime; + public float AdjustedTotalCastTime => this.Struct->GetCastInfo()->AdjustedTotalCastTime; /// /// Gets the underlying structure. diff --git a/Dalamud/Game/ClientState/Objects/Types/Character.cs b/Dalamud/Game/ClientState/Objects/Types/Character.cs index ac11bcdd0..5de803d15 100644 --- a/Dalamud/Game/ClientState/Objects/Types/Character.cs +++ b/Dalamud/Game/ClientState/Objects/Types/Character.cs @@ -1,3 +1,5 @@ +using System.Runtime.CompilerServices; + using Dalamud.Game.ClientState.Objects.Enums; using Dalamud.Game.ClientState.Resolvers; using Dalamud.Game.Text.SeStringHandling; @@ -80,12 +82,12 @@ 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->DrawData.CustomizeData.Data, 28); + public byte[] Customize => this.Struct->DrawData.CustomizeData.Data.ToArray(); /// /// Gets the Free Company tag of this chara. /// - public SeString CompanyTag => MemoryHelper.ReadSeString((IntPtr)this.Struct->FreeCompanyTag, 6); + public SeString CompanyTag => MemoryHelper.ReadSeString((nint)Unsafe.AsPointer(ref this.Struct->FreeCompanyTag[0]), 6); /// /// Gets the target object ID of the character. @@ -95,7 +97,7 @@ public unsafe class Character : GameObject /// /// Gets the name ID of the character. /// - public uint NameId => this.Struct->NameID; + public uint NameId => this.Struct->NameId; /// /// Gets the current online status of the character. diff --git a/Dalamud/Game/ClientState/Objects/Types/GameObject.cs b/Dalamud/Game/ClientState/Objects/Types/GameObject.cs index 3d5b4c288..e0cb06789 100644 --- a/Dalamud/Game/ClientState/Objects/Types/GameObject.cs +++ b/Dalamud/Game/ClientState/Objects/Types/GameObject.cs @@ -1,5 +1,5 @@ -using System; using System.Numerics; +using System.Runtime.CompilerServices; using Dalamud.Game.ClientState.Objects.Enums; using Dalamud.Game.Text.SeStringHandling; @@ -12,11 +12,6 @@ namespace Dalamud.Game.ClientState.Objects.Types; /// public unsafe partial class GameObject : IEquatable { - /// - /// IDs of non-networked GameObjects. - /// - public const uint InvalidGameObjectId = 0xE0000000; - /// /// Initializes a new instance of the class. /// @@ -79,13 +74,13 @@ public unsafe partial class GameObject : IEquatable public bool IsValid() => IsValid(this); /// - bool IEquatable.Equals(GameObject other) => this.ObjectId == other?.ObjectId; + bool IEquatable.Equals(GameObject other) => this.GameObjectId == other?.GameObjectId; /// public override bool Equals(object obj) => ((IEquatable)this).Equals(obj as GameObject); /// - public override int GetHashCode() => this.ObjectId.GetHashCode(); + public override int GetHashCode() => this.GameObjectId.GetHashCode(); } /// @@ -96,22 +91,32 @@ public unsafe partial class GameObject /// /// Gets the name of this . /// - public SeString Name => MemoryHelper.ReadSeString((IntPtr)this.Struct->Name, 64); + public SeString Name => MemoryHelper.ReadSeString((nint)Unsafe.AsPointer(ref this.Struct->Name[0]), 64); /// - /// Gets the object ID of this . + /// Gets the GameObjectID for this GameObject. The Game Object ID is a globally unique identifier that points to + /// this specific object. This ID is used to reference specific objects on the local client (e.g. for targeting). + /// + /// Not to be confused with . /// - public uint ObjectId => this.Struct->ObjectID; + public ulong GameObjectId => this.Struct->GetObjectId(); + /// + /// Gets the Entity ID for this GameObject. Entity IDs are assigned to networked GameObjects. + /// + /// A value of 0xE000_0000 indicates that this entity is not networked and has specific interactivity rules. + /// + public uint EntityId => this.Struct->EntityId; + /// /// Gets the data ID for linking to other respective game data. /// - public uint DataId => this.Struct->DataID; + public uint DataId => this.Struct->BaseId; /// /// Gets the ID of this GameObject's owner. /// - public uint OwnerId => this.Struct->OwnerID; + public uint OwnerId => this.Struct->OwnerId; /// /// Gets the index of this object in the object table. @@ -185,5 +190,5 @@ public unsafe partial class GameObject protected internal FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)this.Address; /// - public override string ToString() => $"{this.ObjectId:X}({this.Name.TextValue} - {this.ObjectKind}) at {this.Address:X}"; + public override string ToString() => $"{this.GameObjectId:X}({this.Name.TextValue} - {this.ObjectKind}) at {this.Address:X}"; } diff --git a/Dalamud/Game/ClientState/Party/PartyList.cs b/Dalamud/Game/ClientState/Party/PartyList.cs index 0e16306f1..835a84865 100644 --- a/Dalamud/Game/ClientState/Party/PartyList.cs +++ b/Dalamud/Game/ClientState/Party/PartyList.cs @@ -1,11 +1,12 @@ -using System; using System.Collections; using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Plugin.Services; + using Serilog; namespace Dalamud.Game.ClientState.Party; @@ -50,10 +51,10 @@ internal sealed unsafe partial class PartyList : IServiceType, IPartyList public IntPtr GroupManagerAddress => this.address.GroupManager; /// - public IntPtr GroupListAddress => (IntPtr)GroupManagerStruct->PartyMembers; + public IntPtr GroupListAddress => (IntPtr)Unsafe.AsPointer(ref GroupManagerStruct->PartyMembers[0]); /// - public IntPtr AllianceListAddress => (IntPtr)this.GroupManagerStruct->AllianceMembers; + public IntPtr AllianceListAddress => (IntPtr)Unsafe.AsPointer(ref this.GroupManagerStruct->AllianceMembers[0]); /// public long PartyId => this.GroupManagerStruct->PartyId; diff --git a/Dalamud/Game/ClientState/Party/PartyMember.cs b/Dalamud/Game/ClientState/Party/PartyMember.cs index ef65e3b19..77539820a 100644 --- a/Dalamud/Game/ClientState/Party/PartyMember.cs +++ b/Dalamud/Game/ClientState/Party/PartyMember.cs @@ -1,5 +1,5 @@ -using System; using System.Numerics; +using System.Runtime.CompilerServices; using Dalamud.Game.ClientState.Objects; using Dalamud.Game.ClientState.Objects.Types; @@ -42,12 +42,12 @@ public unsafe class PartyMember /// /// Gets the content ID of the party member. /// - public long ContentId => this.Struct->ContentID; + public long ContentId => (long)this.Struct->ContentId; /// /// Gets the actor ID of this party member. /// - public uint ObjectId => this.Struct->ObjectID; + public uint ObjectId => this.Struct->EntityId; /// /// Gets the actor associated with this buddy. @@ -90,7 +90,7 @@ public unsafe class PartyMember /// /// Gets the displayname of this party member. /// - public SeString Name => MemoryHelper.ReadSeString((IntPtr)Struct->Name, 0x40); + public SeString Name => MemoryHelper.ReadSeString((nint)Unsafe.AsPointer(ref Struct->Name[0]), 0x40); /// /// Gets the sex of this party member. diff --git a/Dalamud/Game/ClientState/Resolvers/ExcelResolver{T}.cs b/Dalamud/Game/ClientState/Resolvers/ExcelResolver{T}.cs index 722c5a6bc..04003d9aa 100644 --- a/Dalamud/Game/ClientState/Resolvers/ExcelResolver{T}.cs +++ b/Dalamud/Game/ClientState/Resolvers/ExcelResolver{T}.cs @@ -1,4 +1,5 @@ using Dalamud.Data; + using Lumina.Excel; namespace Dalamud.Game.ClientState.Resolvers; diff --git a/Dalamud/Game/ClientState/Statuses/Status.cs b/Dalamud/Game/ClientState/Statuses/Status.cs index aa5759a03..3c405601e 100644 --- a/Dalamud/Game/ClientState/Statuses/Status.cs +++ b/Dalamud/Game/ClientState/Statuses/Status.cs @@ -1,5 +1,3 @@ -using System; - using Dalamud.Game.ClientState.Objects; using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Game.ClientState.Resolvers; @@ -28,12 +26,12 @@ public unsafe class Status /// /// Gets the status ID of this status. /// - public uint StatusId => this.Struct->StatusID; + public uint StatusId => this.Struct->StatusId; /// /// Gets the GameData associated with this status. /// - public Lumina.Excel.GeneratedSheets.Status GameData => new ExcelResolver(this.Struct->StatusID).GameData; + public Lumina.Excel.GeneratedSheets.Status GameData => new ExcelResolver(this.Struct->StatusId).GameData; /// /// Gets the parameter value of the status. @@ -53,7 +51,7 @@ public unsafe class Status /// /// Gets the source ID of this status. /// - public uint SourceId => this.Struct->SourceID; + public uint SourceId => this.Struct->SourceId; /// /// Gets the source actor associated with this status. diff --git a/Dalamud/Game/ClientState/Statuses/StatusList.cs b/Dalamud/Game/ClientState/Statuses/StatusList.cs index fce59e29b..a38e45ea3 100644 --- a/Dalamud/Game/ClientState/Statuses/StatusList.cs +++ b/Dalamud/Game/ClientState/Statuses/StatusList.cs @@ -1,6 +1,6 @@ -using System; using System.Collections; using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Dalamud.Game.ClientState.Statuses; @@ -99,16 +99,16 @@ public sealed unsafe partial class StatusList } /// - /// Gets the address of the party member at the specified index of the party list. + /// Gets the address of the status at the specific index in the status list. /// - /// The index of the party member. - /// The memory address of the party member. + /// The index of the status. + /// The memory address of the status. public IntPtr GetStatusAddress(int index) { if (index < 0 || index >= this.Length) return IntPtr.Zero; - return (IntPtr)(this.Struct->Status + (index * StatusSize)); + return (IntPtr)Unsafe.AsPointer(ref this.Struct->Status[index]); } } diff --git a/Dalamud/Game/Command/CommandInfo.cs b/Dalamud/Game/Command/CommandInfo.cs index bc0250a66..13987f8ae 100644 --- a/Dalamud/Game/Command/CommandInfo.cs +++ b/Dalamud/Game/Command/CommandInfo.cs @@ -1,5 +1,3 @@ -using System.Reflection; - namespace Dalamud.Game.Command; /// diff --git a/Dalamud/Game/Command/CommandManager.cs b/Dalamud/Game/Command/CommandManager.cs index 6a419a34a..571c5b385 100644 --- a/Dalamud/Game/Command/CommandManager.cs +++ b/Dalamud/Game/Command/CommandManager.cs @@ -135,9 +135,9 @@ internal sealed class CommandManager : IInternalDisposableService, ICommandManag this.chatGui.CheckMessageHandled -= this.OnCheckMessageHandled; } - private void OnCheckMessageHandled(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled) + private void OnCheckMessageHandled(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled) { - if (type == XivChatType.ErrorMessage && senderId == 0) + if (type == XivChatType.ErrorMessage && timestamp == 0) { var cmdMatch = this.currentLangCommandRegex.Match(message.TextValue).Groups["command"]; if (cmdMatch.Success) diff --git a/Dalamud/Game/Config/ConfigChangeEvent.cs b/Dalamud/Game/Config/ConfigChangeEvent.cs index 941033c61..ca898b6b3 100644 --- a/Dalamud/Game/Config/ConfigChangeEvent.cs +++ b/Dalamud/Game/Config/ConfigChangeEvent.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Game.Config; +namespace Dalamud.Game.Config; public abstract record ConfigChangeEvent(Enum Option); diff --git a/Dalamud/Game/Config/ConfigOptionNotFoundException.cs b/Dalamud/Game/Config/ConfigOptionNotFoundException.cs index e7f20f173..bc493d530 100644 --- a/Dalamud/Game/Config/ConfigOptionNotFoundException.cs +++ b/Dalamud/Game/Config/ConfigOptionNotFoundException.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.Config; /// diff --git a/Dalamud/Game/Config/GameConfig.cs b/Dalamud/Game/Config/GameConfig.cs index 7bcb8ba2b..b45a1ee7b 100644 --- a/Dalamud/Game/Config/GameConfig.cs +++ b/Dalamud/Game/Config/GameConfig.cs @@ -34,7 +34,7 @@ internal sealed class GameConfig : IInternalDisposableService, IGameConfig { Log.Verbose("[GameConfig] Initializing"); var csFramework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance(); - var commonConfig = &csFramework->SystemConfig.CommonSystemConfig; + var commonConfig = &csFramework->SystemConfig.SystemConfigBase; this.tcsSystem.SetResult(new("System", framework, &commonConfig->ConfigBase)); this.tcsUiConfig.SetResult(new("UiConfig", framework, &commonConfig->UiConfig)); this.tcsUiControl.SetResult( diff --git a/Dalamud/Game/Config/GameConfigOptionAttribute.cs b/Dalamud/Game/Config/GameConfigOptionAttribute.cs index 4ddc41abc..5ba18b37b 100644 --- a/Dalamud/Game/Config/GameConfigOptionAttribute.cs +++ b/Dalamud/Game/Config/GameConfigOptionAttribute.cs @@ -1,7 +1,3 @@ -using System; - -using FFXIVClientStructs.FFXIV.Common.Configuration; - namespace Dalamud.Game.Config; /// diff --git a/Dalamud/Game/Config/IncorrectConfigTypeException.cs b/Dalamud/Game/Config/IncorrectConfigTypeException.cs index e8f81df92..f067efcdc 100644 --- a/Dalamud/Game/Config/IncorrectConfigTypeException.cs +++ b/Dalamud/Game/Config/IncorrectConfigTypeException.cs @@ -1,7 +1,3 @@ -using System; - -using FFXIVClientStructs.FFXIV.Common.Configuration; - namespace Dalamud.Game.Config; /// diff --git a/Dalamud/Game/FrameworkAddressResolver.cs b/Dalamud/Game/FrameworkAddressResolver.cs index 39ae15155..e9c1dad80 100644 --- a/Dalamud/Game/FrameworkAddressResolver.cs +++ b/Dalamud/Game/FrameworkAddressResolver.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game; /// diff --git a/Dalamud/Game/Gui/ChatGui.cs b/Dalamud/Game/Gui/ChatGui.cs index 3c6ed2fc1..abb8bb5c2 100644 --- a/Dalamud/Game/Gui/ChatGui.cs +++ b/Dalamud/Game/Gui/ChatGui.cs @@ -12,7 +12,6 @@ using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Logging.Internal; using Dalamud.Memory; -using Dalamud.Plugin.Internal; using Dalamud.Plugin.Services; using Dalamud.Utility; using FFXIVClientStructs.FFXIV.Client.System.String; @@ -20,11 +19,6 @@ using FFXIVClientStructs.FFXIV.Client.UI.Misc; namespace Dalamud.Game.Gui; -// TODO(api10): Update IChatGui, ChatGui and XivChatEntry to use correct types and names: -// "uint SenderId" should be "int Timestamp". -// "IntPtr Parameters" should be something like "bool Silent". It suppresses new message sounds in certain channels. -// This has to be a 1 byte boolean, so only change it to bool if marshalling is disabled. - /// /// This class handles interacting with the native chat UI. /// @@ -179,7 +173,7 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui var sender = Utf8String.FromSequence(chat.Name.Encode()); var message = Utf8String.FromSequence(replacedMessage.BuiltString.Encode()); - this.HandlePrintMessageDetour(RaptureLogModule.Instance(), chat.Type, sender, message, (int)chat.SenderId, (byte)(chat.Parameters != 0 ? 1 : 0)); + this.HandlePrintMessageDetour(RaptureLogModule.Instance(), chat.Type, sender, message, chat.Timestamp, (byte)(chat.Silent ? 1 : 0)); sender->Dtor(true); message->Dtor(true); @@ -321,7 +315,7 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui try { var messageHandledDelegate = @delegate as IChatGui.OnCheckMessageHandledDelegate; - messageHandledDelegate!.Invoke(chatType, (uint)timestamp, ref parsedSender, ref parsedMessage, ref isHandled); + messageHandledDelegate!.Invoke(chatType, timestamp, ref parsedSender, ref parsedMessage, ref isHandled); } catch (Exception e) { @@ -337,7 +331,7 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui try { var messageHandledDelegate = @delegate as IChatGui.OnMessageDelegate; - messageHandledDelegate!.Invoke(chatType, (uint)timestamp, ref parsedSender, ref parsedMessage, ref isHandled); + messageHandledDelegate!.Invoke(chatType, timestamp, ref parsedSender, ref parsedMessage, ref isHandled); } catch (Exception e) { @@ -364,12 +358,12 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui // Print the original chat if it's handled. if (isHandled) { - this.ChatMessageHandled?.Invoke(chatType, (uint)timestamp, parsedSender, parsedMessage); + this.ChatMessageHandled?.Invoke(chatType, timestamp, parsedSender, parsedMessage); } else { messageId = this.printMessageHook.Original(manager, chatType, sender, message, timestamp, silent); - this.ChatMessageUnhandled?.Invoke(chatType, (uint)timestamp, parsedSender, parsedMessage); + this.ChatMessageUnhandled?.Invoke(chatType, timestamp, parsedSender, parsedMessage); } } catch (Exception ex) @@ -501,15 +495,15 @@ internal class ChatGuiPluginScoped : IInternalDisposableService, IChatGui public void PrintError(SeString message, string? messageTag = null, ushort? tagColor = null) => this.chatGuiService.PrintError(message, messageTag, tagColor); - private void OnMessageForward(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled) - => this.ChatMessage?.Invoke(type, senderId, ref sender, ref message, ref isHandled); + private void OnMessageForward(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled) + => this.ChatMessage?.Invoke(type, timestamp, ref sender, ref message, ref isHandled); - private void OnCheckMessageForward(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled) - => this.CheckMessageHandled?.Invoke(type, senderId, ref sender, ref message, ref isHandled); + private void OnCheckMessageForward(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled) + => this.CheckMessageHandled?.Invoke(type, timestamp, ref sender, ref message, ref isHandled); - private void OnMessageHandledForward(XivChatType type, uint senderId, SeString sender, SeString message) - => this.ChatMessageHandled?.Invoke(type, senderId, sender, message); + private void OnMessageHandledForward(XivChatType type, int timestamp, SeString sender, SeString message) + => this.ChatMessageHandled?.Invoke(type, timestamp, sender, message); - private void OnMessageUnhandledForward(XivChatType type, uint senderId, SeString sender, SeString message) - => this.ChatMessageUnhandled?.Invoke(type, senderId, sender, message); + private void OnMessageUnhandledForward(XivChatType type, int timestamp, SeString sender, SeString message) + => this.ChatMessageUnhandled?.Invoke(type, timestamp, sender, message); } diff --git a/Dalamud/Game/Gui/ContextMenu/ContextMenu.cs b/Dalamud/Game/Gui/ContextMenu/ContextMenu.cs index abbfc6a5b..1d8d3104f 100644 --- a/Dalamud/Game/Gui/ContextMenu/ContextMenu.cs +++ b/Dalamud/Game/Gui/ContextMenu/ContextMenu.cs @@ -17,6 +17,7 @@ using FFXIVClientStructs.FFXIV.Client.System.Memory; using FFXIVClientStructs.FFXIV.Client.UI; using FFXIVClientStructs.FFXIV.Client.UI.Agent; using FFXIVClientStructs.FFXIV.Component.GUI; +using FFXIVClientStructs.FFXIV.Component.GUI.AtkModuleInterface; using FFXIVClientStructs.Interop; using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType; @@ -40,7 +41,7 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM private ContextMenu() { this.raptureAtkModuleOpenAddonByAgentHook = Hook.FromAddress((nint)RaptureAtkModule.Addresses.OpenAddonByAgent.Value, this.RaptureAtkModuleOpenAddonByAgentDetour); - this.addonContextMenuOnMenuSelectedHook = Hook.FromAddress((nint)AddonContextMenu.StaticVTable.OnMenuSelected, this.AddonContextMenuOnMenuSelectedDetour); + this.addonContextMenuOnMenuSelectedHook = Hook.FromAddress((nint)AddonContextMenu.StaticVirtualTablePointer->OnMenuSelected, this.AddonContextMenuOnMenuSelectedDetour); this.raptureAtkModuleOpenAddon = Marshal.GetDelegateForFunctionPointer((nint)RaptureAtkModule.Addresses.OpenAddon.Value); this.raptureAtkModuleOpenAddonByAgentHook.Enable(); @@ -268,11 +269,15 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM foreach (var item in items) { - if (!item.Prefix.HasValue && !item.UseDefaultPrefix) + if (!item.Prefix.HasValue) { item.Prefix = MenuItem.DalamudDefaultPrefix; item.PrefixColor = MenuItem.DalamudDefaultPrefixColor; - Log.Warning($"Menu item \"{item.Name}\" has no prefix, defaulting to Dalamud's. Menu items outside of a submenu must have a prefix."); + + if (!item.UseDefaultPrefix) + { + Log.Warning($"Menu item \"{item.Name}\" has no prefix, defaulting to Dalamud's. Menu items outside of a submenu must have a prefix."); + } } } @@ -312,8 +317,8 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM this.SelectedMenuType = ContextMenuType.Default; var menu = AgentContext.Instance()->CurrentContextMenu; - var handlers = new Span>(menu->EventHandlerArray, 32); - var ids = new Span(menu->EventIdArray, 32); + var handlers = menu->EventHandlers; + var ids = menu->EventIds; var count = (int)values[0].UInt; handlers = handlers.Slice(7, count); ids = ids.Slice(7, count); diff --git a/Dalamud/Game/Gui/ContextMenu/MenuArgs.cs b/Dalamud/Game/Gui/ContextMenu/MenuArgs.cs index cc58a839b..4691f9dd2 100644 --- a/Dalamud/Game/Gui/ContextMenu/MenuArgs.cs +++ b/Dalamud/Game/Gui/ContextMenu/MenuArgs.cs @@ -24,7 +24,7 @@ public abstract unsafe class MenuArgs /// List of AtkEventInterfaces associated with the context menu. protected internal MenuArgs(AtkUnitBase* addon, AgentInterface* agent, ContextMenuType type, IReadOnlySet? eventInterfaces) { - this.AddonName = addon != null ? MemoryHelper.ReadString((nint)addon->Name, 32) : null; + this.AddonName = addon != null ? addon->NameString : null; this.AddonPtr = (nint)addon; this.AgentPtr = (nint)agent; this.MenuType = type; diff --git a/Dalamud/Game/Gui/ContextMenu/MenuItemClickedArgs.cs b/Dalamud/Game/Gui/ContextMenu/MenuItemClickedArgs.cs index bec16590d..ded1475f0 100644 --- a/Dalamud/Game/Gui/ContextMenu/MenuItemClickedArgs.cs +++ b/Dalamud/Game/Gui/ContextMenu/MenuItemClickedArgs.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using Dalamud.Game.Text.SeStringHandling; +using FFXIVClientStructs.FFXIV.Client.UI.Agent; using FFXIVClientStructs.FFXIV.Component.GUI; namespace Dalamud.Game.Gui.ContextMenu; diff --git a/Dalamud/Game/Gui/ContextMenu/MenuOpenedArgs.cs b/Dalamud/Game/Gui/ContextMenu/MenuOpenedArgs.cs index de3347f63..c5e6a7ade 100644 --- a/Dalamud/Game/Gui/ContextMenu/MenuOpenedArgs.cs +++ b/Dalamud/Game/Gui/ContextMenu/MenuOpenedArgs.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; +using FFXIVClientStructs.FFXIV.Client.UI.Agent; using FFXIVClientStructs.FFXIV.Component.GUI; namespace Dalamud.Game.Gui.ContextMenu; diff --git a/Dalamud/Game/Gui/Dtr/DtrBar.cs b/Dalamud/Game/Gui/Dtr/DtrBar.cs index b28c9a7d9..adf18adfd 100644 --- a/Dalamud/Game/Gui/Dtr/DtrBar.cs +++ b/Dalamud/Game/Gui/Dtr/DtrBar.cs @@ -11,6 +11,7 @@ using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Logging.Internal; using Dalamud.Plugin.Services; + using FFXIVClientStructs.FFXIV.Client.Graphics; using FFXIVClientStructs.FFXIV.Client.System.Memory; using FFXIVClientStructs.FFXIV.Component.GUI; @@ -73,13 +74,16 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar this.configuration.QueueSave(); } + /// + public IReadOnlyList Entries => this.entries; + /// public DtrBarEntry Get(string title, SeString? text = null) { if (this.entries.Any(x => x.Title == title) || this.newEntries.Any(x => x.Title == title)) throw new ArgumentException("An entry with the same title already exists."); - var entry = new DtrBarEntry(title, null); + var entry = new DtrBarEntry(this.configuration, title, null); entry.Text = text; // Add the entry to the end of the order list, if it's not there already. @@ -196,7 +200,7 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar foreach (var data in this.entries) { - var isHide = this.configuration.DtrIgnore!.Any(x => x == data.Title) || !data.Shown; + var isHide = data.UserHidden || !data.Shown; if (data is { Dirty: true, Added: true, Text: not null, TextNode: not null }) { @@ -272,7 +276,7 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar var node = addon->UldManager.NodeList[index]; if (node->IsVisible) { - var nodeId = node->NodeID; + var nodeId = node->NodeId; var nodeType = node->Type; if (nodeType == NodeType.Collision) @@ -326,7 +330,7 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar for (var i = 0; i < dtr->UldManager.NodeListCount; i++) { - if (dtr->UldManager.NodeList[i]->NodeID > 1000) + if (dtr->UldManager.NodeList[i]->NodeId > 1000) return true; } @@ -353,8 +357,8 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar var dtr = this.GetDtr(); if (dtr == null || dtr->RootNode == null || dtr->UldManager.NodeList == null || node == null) return false; - this.eventHandles.TryAdd(node->AtkResNode.NodeID, new List()); - this.eventHandles[node->AtkResNode.NodeID].AddRange(new List + this.eventHandles.TryAdd(node->AtkResNode.NodeId, new List()); + this.eventHandles[node->AtkResNode.NodeId].AddRange(new List { this.uiEventManager.AddEvent(AddonEventManager.DalamudInternalKey, (nint)dtr, (nint)node, AddonEventType.MouseOver, this.DtrEventHandler), this.uiEventManager.AddEvent(AddonEventManager.DalamudInternalKey, (nint)dtr, (nint)node, AddonEventType.MouseOut, this.DtrEventHandler), @@ -382,8 +386,8 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar var dtr = this.GetDtr(); if (dtr == null || dtr->RootNode == null || dtr->UldManager.NodeList == null || node == null) return; - this.eventHandles[node->AtkResNode.NodeID].ForEach(handle => this.uiEventManager.RemoveEvent(AddonEventManager.DalamudInternalKey, handle)); - this.eventHandles[node->AtkResNode.NodeID].Clear(); + this.eventHandles[node->AtkResNode.NodeId].ForEach(handle => this.uiEventManager.RemoveEvent(AddonEventManager.DalamudInternalKey, handle)); + this.eventHandles[node->AtkResNode.NodeId].Clear(); var tmpPrevNode = node->AtkResNode.PrevSiblingNode; var tmpNextNode = node->AtkResNode.NextSiblingNode; @@ -410,7 +414,7 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar return null; } - newTextNode->AtkResNode.NodeID = nodeId; + newTextNode->AtkResNode.NodeId = nodeId; newTextNode->AtkResNode.Type = NodeType.Text; newTextNode->AtkResNode.NodeFlags = NodeFlags.AnchorLeft | NodeFlags.AnchorTop | NodeFlags.Enabled | NodeFlags.RespondToMouse | NodeFlags.HasCollision | NodeFlags.EmitsEvents; newTextNode->AtkResNode.DrawFlags = 12; @@ -455,11 +459,11 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar switch (atkEventType) { case AddonEventType.MouseOver: - AtkStage.GetSingleton()->TooltipManager.ShowTooltip(addon->ID, node, dtrBarEntry.Tooltip.Encode()); + AtkStage.Instance()->TooltipManager.ShowTooltip(addon->Id, node, dtrBarEntry.Tooltip.Encode()); break; case AddonEventType.MouseOut: - AtkStage.GetSingleton()->TooltipManager.HideTooltip(addon->ID); + AtkStage.Instance()->TooltipManager.HideTooltip(addon->Id); break; } } @@ -499,6 +503,9 @@ internal class DtrBarPluginScoped : IInternalDisposableService, IDtrBar private readonly DtrBar dtrBarService = Service.Get(); private readonly Dictionary pluginEntries = new(); + + /// + public IReadOnlyList Entries => this.dtrBarService.Entries; /// void IInternalDisposableService.DisposeService() @@ -510,7 +517,7 @@ internal class DtrBarPluginScoped : IInternalDisposableService, IDtrBar this.pluginEntries.Clear(); } - + /// public DtrBarEntry Get(string title, SeString? text = null) { diff --git a/Dalamud/Game/Gui/Dtr/DtrBarEntry.cs b/Dalamud/Game/Gui/Dtr/DtrBarEntry.cs index f04e1427d..1cc51cfe4 100644 --- a/Dalamud/Game/Gui/Dtr/DtrBarEntry.cs +++ b/Dalamud/Game/Gui/Dtr/DtrBarEntry.cs @@ -1,37 +1,114 @@ -using System; +using System.Linq; +using Dalamud.Configuration.Internal; using Dalamud.Game.Text.SeStringHandling; +using Dalamud.Utility; + using FFXIVClientStructs.FFXIV.Component.GUI; namespace Dalamud.Game.Gui.Dtr; +/// +/// Interface representing a read-only entry in the server info bar. +/// +public interface IReadOnlyDtrBarEntry +{ + /// + /// Gets the title of this entry. + /// + public string Title { get; } + + /// + /// Gets a value indicating whether this entry has a click action. + /// + public bool HasClickAction { get; } + + /// + /// Gets the text of this entry. + /// + public SeString Text { get; } + + /// + /// Gets a tooltip to be shown when the user mouses over the dtr entry. + /// + public SeString Tooltip { get; } + + /// + /// Gets a value indicating whether this entry should be shown. + /// + public bool Shown { get; } + + /// + /// Gets a value indicating whether or not the user has hidden this entry from view through the Dalamud settings. + /// + public bool UserHidden { get; } + + /// + /// Triggers the click action of this entry. + /// + /// True, if a click action was registered and executed. + public bool TriggerClickAction(); +} + +/// +/// Interface representing an entry in the server info bar. +/// +public interface IDtrBarEntry : IReadOnlyDtrBarEntry +{ + /// + /// Gets or sets the text of this entry. + /// + public new SeString? Text { get; set; } + + /// + /// Gets or sets a tooltip to be shown when the user mouses over the dtr entry. + /// + public new SeString? Tooltip { get; set; } + + /// + /// Gets or sets a value indicating whether this entry is visible. + /// + public new bool Shown { get; set; } + + /// + /// Gets or sets a action to be invoked when the user clicks on the dtr entry. + /// + public Action? OnClick { get; set; } + + /// + /// Remove this entry from the bar. + /// You will need to re-acquire it from DtrBar to reuse it. + /// + public void Remove(); +} + /// /// Class representing an entry in the server info bar. /// -public sealed unsafe class DtrBarEntry : IDisposable +public sealed unsafe class DtrBarEntry : IDisposable, IDtrBarEntry { + private readonly DalamudConfiguration configuration; + private bool shownBacking = true; - private SeString? textBacking = null; + private SeString? textBacking; /// /// Initializes a new instance of the class. /// + /// Dalamud configuration, used to check if the entry is hidden by the user. /// The title of the bar entry. /// The corresponding text node. - internal DtrBarEntry(string title, AtkTextNode* textNode) + internal DtrBarEntry(DalamudConfiguration configuration, string title, AtkTextNode* textNode) { + this.configuration = configuration; this.Title = title; this.TextNode = textNode; } - /// - /// Gets the title of this entry. - /// + /// public string Title { get; init; } - /// - /// Gets or sets the text of this entry. - /// + /// public SeString? Text { get => this.textBacking; @@ -41,10 +118,8 @@ public sealed unsafe class DtrBarEntry : IDisposable this.Dirty = true; } } - - /// - /// Gets or sets a tooltip to be shown when the user mouses over the dtr entry. - /// + + /// public SeString? Tooltip { get; set; } /// @@ -52,9 +127,10 @@ public sealed unsafe class DtrBarEntry : IDisposable /// public Action? OnClick { get; set; } - /// - /// Gets or sets a value indicating whether this entry is visible. - /// + /// + public bool HasClickAction => this.OnClick != null; + + /// public bool Shown { get => this.shownBacking; @@ -65,6 +141,10 @@ public sealed unsafe class DtrBarEntry : IDisposable } } + /// + [Api10ToDo("Maybe make this config scoped to internalname?")] + public bool UserHidden => this.configuration.DtrIgnore?.Any(x => x == this.Title) ?? false; + /// /// Gets or sets the internal text node of this entry. /// @@ -73,17 +153,27 @@ public sealed unsafe class DtrBarEntry : IDisposable /// /// Gets a value indicating whether this entry should be removed. /// - internal bool ShouldBeRemoved { get; private set; } = false; + internal bool ShouldBeRemoved { get; private set; } /// /// Gets or sets a value indicating whether this entry is dirty. /// - internal bool Dirty { get; set; } = false; + internal bool Dirty { get; set; } /// /// Gets or sets a value indicating whether this entry has just been added. /// - internal bool Added { get; set; } = false; + internal bool Added { get; set; } + + /// + public bool TriggerClickAction() + { + if (this.OnClick == null) + return false; + + this.OnClick.Invoke(); + return true; + } /// /// Remove this entry from the bar. diff --git a/Dalamud/Game/Gui/FlyText/FlyTextGui.cs b/Dalamud/Game/Gui/FlyText/FlyTextGui.cs index 61bfc5d0a..6a9fd007f 100644 --- a/Dalamud/Game/Gui/FlyText/FlyTextGui.cs +++ b/Dalamud/Game/Gui/FlyText/FlyTextGui.cs @@ -7,6 +7,7 @@ using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Memory; using Dalamud.Plugin.Services; + using Serilog; namespace Dalamud.Game.Gui.FlyText; diff --git a/Dalamud/Game/Gui/GameGui.cs b/Dalamud/Game/Gui/GameGui.cs index bdc483655..88c8433a2 100644 --- a/Dalamud/Game/Gui/GameGui.cs +++ b/Dalamud/Game/Gui/GameGui.cs @@ -12,6 +12,7 @@ using Dalamud.Utility; using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel; using FFXIVClientStructs.FFXIV.Client.System.String; using FFXIVClientStructs.FFXIV.Client.UI; +using FFXIVClientStructs.FFXIV.Client.UI.Agent; using FFXIVClientStructs.FFXIV.Common.Component.BGCollision; using FFXIVClientStructs.FFXIV.Component.GUI; using ImGuiNET; @@ -272,7 +273,7 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui if (framework == null) return IntPtr.Zero; - var uiModule = framework->GetUiModule(); + var uiModule = framework->GetUIModule(); if (uiModule == null) return IntPtr.Zero; @@ -282,7 +283,7 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui /// public IntPtr GetAddonByName(string name, int index = 1) { - var atkStage = AtkStage.GetSingleton(); + var atkStage = AtkStage.Instance(); if (atkStage == null) return IntPtr.Zero; @@ -322,7 +323,7 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui return IntPtr.Zero; var addon = (AtkUnitBase*)addonPtr; - var addonId = addon->ParentID == 0 ? addon->ID : addon->ParentID; + var addonId = addon->ParentId == 0 ? addon->Id : addon->ParentId; if (addonId == 0) return IntPtr.Zero; @@ -330,7 +331,7 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui var index = 0; while (true) { - var agent = agentModule->GetAgentByInternalID((uint)index++); + var agent = agentModule->GetAgentByInternalId((AgentId)index++); if (agent == uiModule || agent == null) break; diff --git a/Dalamud/Game/Gui/GameGuiAddressResolver.cs b/Dalamud/Game/Gui/GameGuiAddressResolver.cs index cbed42a65..6928a037e 100644 --- a/Dalamud/Game/Gui/GameGuiAddressResolver.cs +++ b/Dalamud/Game/Gui/GameGuiAddressResolver.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.Gui; /// diff --git a/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs b/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs index beac09478..fb89e5497 100644 --- a/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs +++ b/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs @@ -6,6 +6,7 @@ using Dalamud.Hooking; using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Plugin.Services; + using Serilog; namespace Dalamud.Game.Gui.PartyFinder; diff --git a/Dalamud/Game/Gui/PartyFinder/Types/ConditionFlags.cs b/Dalamud/Game/Gui/PartyFinder/Types/ConditionFlags.cs index d9be66856..8c1ed6ba7 100644 --- a/Dalamud/Game/Gui/PartyFinder/Types/ConditionFlags.cs +++ b/Dalamud/Game/Gui/PartyFinder/Types/ConditionFlags.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.Gui.PartyFinder.Types; /// diff --git a/Dalamud/Game/Gui/PartyFinder/Types/DutyCategory.cs b/Dalamud/Game/Gui/PartyFinder/Types/DutyCategory.cs index c4a05704d..33010a379 100644 --- a/Dalamud/Game/Gui/PartyFinder/Types/DutyCategory.cs +++ b/Dalamud/Game/Gui/PartyFinder/Types/DutyCategory.cs @@ -11,9 +11,9 @@ public enum DutyCategory Duty = 0, /// - /// The quest battle category. + /// The gold saucer category. /// - QuestBattles = 1 << 0, + GoldSaucer = 1 << 0, /// /// The fate category. @@ -43,5 +43,16 @@ public enum DutyCategory /// /// The adventuring forays category. /// + [Obsolete("Adventuring Forays have been renamed to Field Operations")] AdventuringForays = 1 << 6, + + /// + /// The field operations category. + /// + FieldOperations = 1 << 6, + + /// + /// The variant and criterion dungeons category. + /// + VariantAndCriterionDungeons = 1 << 7, } diff --git a/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderSettingsFlags.cs b/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderSettingsFlags.cs index e3ab56ed3..e27e11df4 100644 --- a/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderSettingsFlags.cs +++ b/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderSettingsFlags.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.Gui.PartyFinder.Types; /// diff --git a/Dalamud/Game/Gui/PartyFinder/Types/JobFlags.cs b/Dalamud/Game/Gui/PartyFinder/Types/JobFlags.cs index 9d6c8820c..419a4a138 100644 --- a/Dalamud/Game/Gui/PartyFinder/Types/JobFlags.cs +++ b/Dalamud/Game/Gui/PartyFinder/Types/JobFlags.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.Gui.PartyFinder.Types; /// diff --git a/Dalamud/Game/Gui/PartyFinder/Types/LootRuleFlags.cs b/Dalamud/Game/Gui/PartyFinder/Types/LootRuleFlags.cs index 6e43ecf4c..6d6918c4e 100644 --- a/Dalamud/Game/Gui/PartyFinder/Types/LootRuleFlags.cs +++ b/Dalamud/Game/Gui/PartyFinder/Types/LootRuleFlags.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.Gui.PartyFinder.Types; /// diff --git a/Dalamud/Game/Gui/PartyFinder/Types/ObjectiveFlags.cs b/Dalamud/Game/Gui/PartyFinder/Types/ObjectiveFlags.cs index 19f56f84c..2ff3922b9 100644 --- a/Dalamud/Game/Gui/PartyFinder/Types/ObjectiveFlags.cs +++ b/Dalamud/Game/Gui/PartyFinder/Types/ObjectiveFlags.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.Gui.PartyFinder.Types; /// diff --git a/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderListing.cs b/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderListing.cs index 503b7d905..1a5b76f5b 100644 --- a/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderListing.cs +++ b/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderListing.cs @@ -1,10 +1,10 @@ -using System; using System.Collections.Generic; using System.Linq; using Dalamud.Data; using Dalamud.Game.Gui.PartyFinder.Internal; using Dalamud.Game.Text.SeStringHandling; + using Lumina.Excel.GeneratedSheets; namespace Dalamud.Game.Gui.PartyFinder.Types; diff --git a/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderSlot.cs b/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderSlot.cs index a0853adf1..631a89a41 100644 --- a/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderSlot.cs +++ b/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderSlot.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; diff --git a/Dalamud/Game/Gui/PartyFinder/Types/SearchAreaFlags.cs b/Dalamud/Game/Gui/PartyFinder/Types/SearchAreaFlags.cs index 27a3f5ee8..7d405cd09 100644 --- a/Dalamud/Game/Gui/PartyFinder/Types/SearchAreaFlags.cs +++ b/Dalamud/Game/Gui/PartyFinder/Types/SearchAreaFlags.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.Gui.PartyFinder.Types; /// diff --git a/Dalamud/Game/Internal/AntiDebug.cs b/Dalamud/Game/Internal/AntiDebug.cs index 5ab024012..a818d4d54 100644 --- a/Dalamud/Game/Internal/AntiDebug.cs +++ b/Dalamud/Game/Internal/AntiDebug.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; #if !DEBUG diff --git a/Dalamud/Game/Internal/DXGI/ISwapChainAddressResolver.cs b/Dalamud/Game/Internal/DXGI/ISwapChainAddressResolver.cs index 867119be5..daccb8d14 100644 --- a/Dalamud/Game/Internal/DXGI/ISwapChainAddressResolver.cs +++ b/Dalamud/Game/Internal/DXGI/ISwapChainAddressResolver.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.Internal.DXGI; /// diff --git a/Dalamud/Game/Internal/DalamudAtkTweaks.cs b/Dalamud/Game/Internal/DalamudAtkTweaks.cs index 9f9328de1..33fec85a0 100644 --- a/Dalamud/Game/Internal/DalamudAtkTweaks.cs +++ b/Dalamud/Game/Internal/DalamudAtkTweaks.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.InteropServices; using CheapLoc; @@ -9,6 +8,7 @@ using Dalamud.Game.Text.SeStringHandling.Payloads; using Dalamud.Hooking; using Dalamud.Interface.Internal; using Dalamud.Interface.Windowing; + using FFXIVClientStructs.FFXIV.Component.GUI; using Serilog; diff --git a/Dalamud/Game/Inventory/GameInventory.cs b/Dalamud/Game/Inventory/GameInventory.cs index dde0e3614..985104450 100644 --- a/Dalamud/Game/Inventory/GameInventory.cs +++ b/Dalamud/Game/Inventory/GameInventory.cs @@ -51,7 +51,7 @@ internal class GameInventory : IInternalDisposableService unsafe { this.raptureAtkModuleUpdateHook = Hook.FromFunctionPointerVariable( - new(&((RaptureAtkModule.RaptureAtkModuleVTable*)RaptureAtkModule.StaticAddressPointers.VTable)->Update), + new(&RaptureAtkModule.StaticVirtualTablePointer->Update), this.RaptureAtkModuleUpdateDetour); } diff --git a/Dalamud/Game/Inventory/GameInventoryItem.cs b/Dalamud/Game/Inventory/GameInventoryItem.cs index 877fd26c6..0ead24450 100644 --- a/Dalamud/Game/Inventory/GameInventoryItem.cs +++ b/Dalamud/Game/Inventory/GameInventoryItem.cs @@ -1,10 +1,7 @@ using System.Diagnostics; -using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using Dalamud.Utility; - using FFXIVClientStructs.FFXIV.Client.Game; namespace Dalamud.Game.Inventory; @@ -46,7 +43,7 @@ public unsafe struct GameInventoryItem : IEquatable /// /// Gets a value indicating whether the this is empty. /// - public bool IsEmpty => this.InternalItem.ItemID == 0; + public bool IsEmpty => this.InternalItem.ItemId == 0; /// /// Gets the container inventory type. @@ -61,7 +58,7 @@ public unsafe struct GameInventoryItem : IEquatable /// /// Gets the item id. /// - public uint ItemId => this.InternalItem.ItemID; + public uint ItemId => this.InternalItem.ItemId; /// /// Gets the quantity of items in this item stack. @@ -81,7 +78,7 @@ public unsafe struct GameInventoryItem : IEquatable /// /// Gets a value indicating whether the item is High Quality. /// - public bool IsHq => (this.InternalItem.Flags & InventoryItem.ItemFlags.HQ) != 0; + public bool IsHq => (this.InternalItem.Flags & InventoryItem.ItemFlags.HighQuality) != 0; /// /// Gets a value indicating whether the item has a company crest applied. @@ -101,13 +98,12 @@ public unsafe struct GameInventoryItem : IEquatable /// /// Gets the array of materia types. /// - public ReadOnlySpan Materia => new(Unsafe.AsPointer(ref Unsafe.AsRef(in this.InternalItem.Materia[0])), 5); + public ReadOnlySpan Materia => new(Unsafe.AsPointer(ref this.InternalItem.Materia[0]), 5); /// /// Gets the array of materia grades. /// - public ReadOnlySpan MateriaGrade => - new(Unsafe.AsPointer(ref Unsafe.AsRef(in this.InternalItem.MateriaGrade[0])), 5); + public ReadOnlySpan MateriaGrade => new(Unsafe.AsPointer(ref this.InternalItem.MateriaGrades[0]), 5); /// /// Gets the address of native inventory item in the game.
@@ -141,13 +137,13 @@ public unsafe struct GameInventoryItem : IEquatable /// /// Gets the glamour id for this item. /// - public uint GlamourId => this.InternalItem.GlamourID; + public uint GlamourId => this.InternalItem.GlamourId; /// /// Gets the items crafter's content id. /// NOTE: I'm not sure if this is a good idea to include or not in the dalamud api. Marked internal for now. /// - internal ulong CrafterContentId => this.InternalItem.CrafterContentID; + internal ulong CrafterContentId => this.InternalItem.CrafterContentId; public static bool operator ==(in GameInventoryItem l, in GameInventoryItem r) => l.Equals(r); diff --git a/Dalamud/Game/Network/Internal/MarketBoardUploaders/MarketBoardItemRequest.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/MarketBoardItemRequest.cs index bc8043732..eb4ed7ece 100644 --- a/Dalamud/Game/Network/Internal/MarketBoardUploaders/MarketBoardItemRequest.cs +++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/MarketBoardItemRequest.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; diff --git a/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs index 34a255e19..4fe701c48 100644 --- a/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs +++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types; using Dalamud.Game.Network.Structures; using Dalamud.Networking.Http; + using Newtonsoft.Json; using Serilog; diff --git a/Dalamud/Game/Network/Internal/NetworkHandlers.cs b/Dalamud/Game/Network/Internal/NetworkHandlers.cs index 167a3fcaa..f7091817c 100644 --- a/Dalamud/Game/Network/Internal/NetworkHandlers.cs +++ b/Dalamud/Game/Network/Internal/NetworkHandlers.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; using System.Linq; diff --git a/Dalamud/Game/Network/Internal/WinSockHandlers.cs b/Dalamud/Game/Network/Internal/WinSockHandlers.cs index 619c458c4..384858cfe 100644 --- a/Dalamud/Game/Network/Internal/WinSockHandlers.cs +++ b/Dalamud/Game/Network/Internal/WinSockHandlers.cs @@ -1,4 +1,3 @@ -using System; using System.Net.Sockets; using System.Runtime.InteropServices; diff --git a/Dalamud/Game/Network/Structures/InfoProxy/CharacterData.cs b/Dalamud/Game/Network/Structures/InfoProxy/CharacterData.cs index 0ca35d672..25952db35 100644 --- a/Dalamud/Game/Network/Structures/InfoProxy/CharacterData.cs +++ b/Dalamud/Game/Network/Structures/InfoProxy/CharacterData.cs @@ -132,12 +132,12 @@ public unsafe class CharacterData /// /// Gets the name of the character. /// - public string Name => MemoryHelper.ReadString((nint)this.Struct->Name, 32); + public string Name => this.Struct->NameString; /// /// Gets the free company tag of the character. /// - public string FCTag => MemoryHelper.ReadString((nint)this.Struct->Name, 6); + public string FCTag => this.Struct->FCTagString; /// /// Gets the underlying struct. diff --git a/Dalamud/Game/Network/Structures/MarketBoardCurrentOfferings.cs b/Dalamud/Game/Network/Structures/MarketBoardCurrentOfferings.cs index 4d57a0fbd..fc782cd51 100644 --- a/Dalamud/Game/Network/Structures/MarketBoardCurrentOfferings.cs +++ b/Dalamud/Game/Network/Structures/MarketBoardCurrentOfferings.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; using System.Text; diff --git a/Dalamud/Game/Network/Structures/MarketBoardHistory.cs b/Dalamud/Game/Network/Structures/MarketBoardHistory.cs index 9a61b814e..148c321db 100644 --- a/Dalamud/Game/Network/Structures/MarketBoardHistory.cs +++ b/Dalamud/Game/Network/Structures/MarketBoardHistory.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; using System.Text; diff --git a/Dalamud/Game/Network/Structures/MarketBoardPurchase.cs b/Dalamud/Game/Network/Structures/MarketBoardPurchase.cs index 4e9b67a74..62d104cff 100644 --- a/Dalamud/Game/Network/Structures/MarketBoardPurchase.cs +++ b/Dalamud/Game/Network/Structures/MarketBoardPurchase.cs @@ -1,4 +1,3 @@ -using System; using System.IO; namespace Dalamud.Game.Network.Structures; diff --git a/Dalamud/Game/Network/Structures/MarketBoardPurchaseHandler.cs b/Dalamud/Game/Network/Structures/MarketBoardPurchaseHandler.cs index 0d0c18329..783e62cda 100644 --- a/Dalamud/Game/Network/Structures/MarketBoardPurchaseHandler.cs +++ b/Dalamud/Game/Network/Structures/MarketBoardPurchaseHandler.cs @@ -1,4 +1,3 @@ -using System; using System.IO; namespace Dalamud.Game.Network.Structures; diff --git a/Dalamud/Game/SigScanner.cs b/Dalamud/Game/SigScanner.cs index 5e49052ae..ff6a9e327 100644 --- a/Dalamud/Game/SigScanner.cs +++ b/Dalamud/Game/SigScanner.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; @@ -7,8 +6,6 @@ using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using Dalamud.IoC; -using Dalamud.IoC.Internal; using Iced.Intel; using Newtonsoft.Json; using Serilog; diff --git a/Dalamud/Game/Text/Sanitizer/Sanitizer.cs b/Dalamud/Game/Text/Sanitizer/Sanitizer.cs index 0647f5d28..3966d3b89 100644 --- a/Dalamud/Game/Text/Sanitizer/Sanitizer.cs +++ b/Dalamud/Game/Text/Sanitizer/Sanitizer.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; diff --git a/Dalamud/Game/Text/SeStringHandling/Payload.cs b/Dalamud/Game/Text/SeStringHandling/Payload.cs index ff7332f12..b876598de 100644 --- a/Dalamud/Game/Text/SeStringHandling/Payload.cs +++ b/Dalamud/Game/Text/SeStringHandling/Payload.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; @@ -6,6 +5,7 @@ using System.IO; using Dalamud.Data; using Dalamud.Game.Text.SeStringHandling.Payloads; using Dalamud.Plugin.Services; + using Newtonsoft.Json; using Serilog; diff --git a/Dalamud/Game/Text/SeStringHandling/Payloads/AutoTranslatePayload.cs b/Dalamud/Game/Text/SeStringHandling/Payloads/AutoTranslatePayload.cs index 7b8ffd146..5c87ad43b 100644 --- a/Dalamud/Game/Text/SeStringHandling/Payloads/AutoTranslatePayload.cs +++ b/Dalamud/Game/Text/SeStringHandling/Payloads/AutoTranslatePayload.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -16,11 +15,11 @@ public class AutoTranslatePayload : Payload, ITextProvider { private string text; - [JsonProperty] - private uint group; + [JsonProperty("group")] + public uint Group { get; private set; } - [JsonProperty] - private uint key; + [JsonProperty("key")] + public uint Key { get; private set; } /// /// Initializes a new instance of the class. @@ -35,8 +34,8 @@ public class AutoTranslatePayload : Payload, ITextProvider public AutoTranslatePayload(uint group, uint key) { // TODO: friendlier ctor? not sure how to handle that given how weird the tables are - this.group = group; - this.key = key; + this.Group = group; + this.Key = key; } /// @@ -70,20 +69,20 @@ public class AutoTranslatePayload : Payload, ITextProvider /// A string that represents the current object. public override string ToString() { - return $"{this.Type} - Group: {this.group}, Key: {this.key}, Text: {this.Text}"; + return $"{this.Type} - Group: {this.Group}, Key: {this.Key}, Text: {this.Text}"; } /// protected override byte[] EncodeImpl() { - var keyBytes = MakeInteger(this.key); + var keyBytes = MakeInteger(this.Key); var chunkLen = keyBytes.Length + 2; var bytes = new List() { START_BYTE, (byte)SeStringChunkType.AutoTranslateKey, (byte)chunkLen, - (byte)this.group, + (byte)this.Group, }; bytes.AddRange(keyBytes); bytes.Add(END_BYTE); @@ -96,9 +95,9 @@ public class AutoTranslatePayload : Payload, ITextProvider { // this seems to always be a bare byte, and not following normal integer encoding // the values in the table are all <70 so this is presumably ok - this.group = reader.ReadByte(); + this.Group = reader.ReadByte(); - this.key = GetInteger(reader); + this.Key = GetInteger(reader); } private string Resolve() @@ -113,13 +112,13 @@ public class AutoTranslatePayload : Payload, ITextProvider // try to get the row in the Completion table itself, because this is 'easiest' // The row may not exist at all (if the Key is for another table), or it could be the wrong row // (again, if it's meant for another table) - row = sheet.GetRow(this.key); + row = sheet.GetRow(this.Key); } catch { } // don't care, row will be null - if (row?.Group == this.group) + if (row?.Group == this.Group) { // if the row exists in this table and the group matches, this is actually the correct data value = row.Text; @@ -130,30 +129,30 @@ public class AutoTranslatePayload : Payload, ITextProvider { // we need to get the linked table and do the lookup there instead // in this case, there will only be one entry for this group id - row = sheet.First(r => r.Group == this.group); + row = sheet.First(r => r.Group == this.Group); // many of the names contain valid id ranges after the table name, but we don't need those var actualTableName = row.LookupTable.RawString.Split('[')[0]; var name = actualTableName switch { - "Action" => this.DataResolver.GetExcelSheet().GetRow(this.key).Name, - "ActionComboRoute" => this.DataResolver.GetExcelSheet().GetRow(this.key).Name, - "BuddyAction" => this.DataResolver.GetExcelSheet().GetRow(this.key).Name, - "ClassJob" => this.DataResolver.GetExcelSheet().GetRow(this.key).Name, - "Companion" => this.DataResolver.GetExcelSheet().GetRow(this.key).Singular, - "CraftAction" => this.DataResolver.GetExcelSheet().GetRow(this.key).Name, - "GeneralAction" => this.DataResolver.GetExcelSheet().GetRow(this.key).Name, - "GuardianDeity" => this.DataResolver.GetExcelSheet().GetRow(this.key).Name, - "MainCommand" => this.DataResolver.GetExcelSheet().GetRow(this.key).Name, - "Mount" => this.DataResolver.GetExcelSheet().GetRow(this.key).Singular, - "Pet" => this.DataResolver.GetExcelSheet().GetRow(this.key).Name, - "PetAction" => this.DataResolver.GetExcelSheet().GetRow(this.key).Name, - "PetMirage" => this.DataResolver.GetExcelSheet().GetRow(this.key).Name, - "PlaceName" => this.DataResolver.GetExcelSheet().GetRow(this.key).Name, - "Race" => this.DataResolver.GetExcelSheet().GetRow(this.key).Masculine, - "TextCommand" => this.DataResolver.GetExcelSheet().GetRow(this.key).Command, - "Tribe" => this.DataResolver.GetExcelSheet().GetRow(this.key).Masculine, - "Weather" => this.DataResolver.GetExcelSheet().GetRow(this.key).Name, + "Action" => this.DataResolver.GetExcelSheet().GetRow(this.Key).Name, + "ActionComboRoute" => this.DataResolver.GetExcelSheet().GetRow(this.Key).Name, + "BuddyAction" => this.DataResolver.GetExcelSheet().GetRow(this.Key).Name, + "ClassJob" => this.DataResolver.GetExcelSheet().GetRow(this.Key).Name, + "Companion" => this.DataResolver.GetExcelSheet().GetRow(this.Key).Singular, + "CraftAction" => this.DataResolver.GetExcelSheet().GetRow(this.Key).Name, + "GeneralAction" => this.DataResolver.GetExcelSheet().GetRow(this.Key).Name, + "GuardianDeity" => this.DataResolver.GetExcelSheet().GetRow(this.Key).Name, + "MainCommand" => this.DataResolver.GetExcelSheet().GetRow(this.Key).Name, + "Mount" => this.DataResolver.GetExcelSheet().GetRow(this.Key).Singular, + "Pet" => this.DataResolver.GetExcelSheet().GetRow(this.Key).Name, + "PetAction" => this.DataResolver.GetExcelSheet().GetRow(this.Key).Name, + "PetMirage" => this.DataResolver.GetExcelSheet().GetRow(this.Key).Name, + "PlaceName" => this.DataResolver.GetExcelSheet().GetRow(this.Key).Name, + "Race" => this.DataResolver.GetExcelSheet().GetRow(this.Key).Masculine, + "TextCommand" => this.ResolveTextCommand(), + "Tribe" => this.DataResolver.GetExcelSheet().GetRow(this.Key).Masculine, + "Weather" => this.DataResolver.GetExcelSheet().GetRow(this.Key).Name, _ => throw new Exception(actualTableName), }; @@ -161,10 +160,18 @@ public class AutoTranslatePayload : Payload, ITextProvider } catch (Exception e) { - Log.Error(e, $"AutoTranslatePayload - failed to resolve: {this.Type} - Group: {this.group}, Key: {this.key}"); + Log.Error(e, $"AutoTranslatePayload - failed to resolve: {this.Type} - Group: {this.Group}, Key: {this.Key}"); } } return value; } + + private Lumina.Text.SeString ResolveTextCommand() + { + // TextCommands prioritize the `Alias` field, if it not empty + // Example for this is /rangerpose2l which becomes /blackrangerposeb in chat + var result = this.DataResolver.GetExcelSheet().GetRow(this.Key); + return result.Alias.Payloads.Count > 0 ? result.Alias : result.Command; + } } diff --git a/Dalamud/Game/Text/SeStringHandling/Payloads/DalamudLinkPayload.cs b/Dalamud/Game/Text/SeStringHandling/Payloads/DalamudLinkPayload.cs index 7a1ed417c..0310372bb 100644 --- a/Dalamud/Game/Text/SeStringHandling/Payloads/DalamudLinkPayload.cs +++ b/Dalamud/Game/Text/SeStringHandling/Payloads/DalamudLinkPayload.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; using System.Text; diff --git a/Dalamud/Game/Text/SeStringHandling/Payloads/MapLinkPayload.cs b/Dalamud/Game/Text/SeStringHandling/Payloads/MapLinkPayload.cs index 667b52e36..7d975b347 100644 --- a/Dalamud/Game/Text/SeStringHandling/Payloads/MapLinkPayload.cs +++ b/Dalamud/Game/Text/SeStringHandling/Payloads/MapLinkPayload.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; diff --git a/Dalamud/Game/Text/SeStringHandling/Payloads/NewLinePayload.cs b/Dalamud/Game/Text/SeStringHandling/Payloads/NewLinePayload.cs index 3df724e75..0b090b3d6 100644 --- a/Dalamud/Game/Text/SeStringHandling/Payloads/NewLinePayload.cs +++ b/Dalamud/Game/Text/SeStringHandling/Payloads/NewLinePayload.cs @@ -1,4 +1,3 @@ -using System; using System.IO; namespace Dalamud.Game.Text.SeStringHandling.Payloads; diff --git a/Dalamud/Game/Text/SeStringHandling/Payloads/RawPayload.cs b/Dalamud/Game/Text/SeStringHandling/Payloads/RawPayload.cs index c42805b92..a7e41cbc6 100644 --- a/Dalamud/Game/Text/SeStringHandling/Payloads/RawPayload.cs +++ b/Dalamud/Game/Text/SeStringHandling/Payloads/RawPayload.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; using System.Linq; diff --git a/Dalamud/Game/Text/SeStringHandling/Payloads/TextPayload.cs b/Dalamud/Game/Text/SeStringHandling/Payloads/TextPayload.cs index 1cb27f4ea..7c1ce1a3c 100644 --- a/Dalamud/Game/Text/SeStringHandling/Payloads/TextPayload.cs +++ b/Dalamud/Game/Text/SeStringHandling/Payloads/TextPayload.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; using System.Text; diff --git a/Dalamud/Game/Text/SeStringHandling/Payloads/UIForegroundPayload.cs b/Dalamud/Game/Text/SeStringHandling/Payloads/UIForegroundPayload.cs index 0586089f8..1cd96a81a 100644 --- a/Dalamud/Game/Text/SeStringHandling/Payloads/UIForegroundPayload.cs +++ b/Dalamud/Game/Text/SeStringHandling/Payloads/UIForegroundPayload.cs @@ -77,15 +77,21 @@ public class UIForegroundPayload : Payload } /// - /// Gets the Red/Green/Blue values for this foreground color, encoded as a typical hex color. + /// Gets the Red/Green/Blue/Alpha values for this foreground color, encoded as a typical hex color. /// [JsonIgnore] - public uint RGB => this.UIColor.UIForeground & 0xFFFFFF; + public uint RGBA => this.UIColor.UIForeground; + + /// + /// Gets the ABGR value for this foreground color, as ImGui requires it in PushColor. + /// + [JsonIgnore] + public uint ABGR => Interface.ColorHelpers.SwapEndianness(this.UIColor.UIForeground); /// public override string ToString() { - return $"{this.Type} - UIColor: {this.colorKey} color: {(this.IsEnabled ? this.RGB : 0)}"; + return $"{this.Type} - UIColor: {this.colorKey} color: {(this.IsEnabled ? this.RGBA : 0)}"; } /// diff --git a/Dalamud/Game/Text/SeStringHandling/Payloads/UIGlowPayload.cs b/Dalamud/Game/Text/SeStringHandling/Payloads/UIGlowPayload.cs index 0d9081c08..68ed983ff 100644 --- a/Dalamud/Game/Text/SeStringHandling/Payloads/UIGlowPayload.cs +++ b/Dalamud/Game/Text/SeStringHandling/Payloads/UIGlowPayload.cs @@ -68,10 +68,16 @@ public class UIGlowPayload : Payload public bool IsEnabled => this.ColorKey != 0; /// - /// Gets the Red/Green/Blue values for this glow color, encoded as a typical hex color. + /// Gets the Red/Green/Blue/Alpha values for this glow color, encoded as a typical hex color. /// [JsonIgnore] - public uint RGB => this.UIColor.UIGlow & 0xFFFFFF; + public uint RGBA => this.UIColor.UIGlow; + + /// + /// Gets the ABGR value for this glow color, as ImGui requires it in PushColor. + /// + [JsonIgnore] + public uint ABGR => Interface.ColorHelpers.SwapEndianness(this.UIColor.UIGlow); /// /// Gets a Lumina UIColor object representing this payload. The actual color data is at UIColor.UIGlow. @@ -85,7 +91,7 @@ public class UIGlowPayload : Payload /// public override string ToString() { - return $"{this.Type} - UIColor: {this.colorKey} color: {(this.IsEnabled ? this.RGB : 0)}"; + return $"{this.Type} - UIColor: {this.colorKey} color: {(this.IsEnabled ? this.RGBA : 0)}"; } /// diff --git a/Dalamud/Game/Text/SeStringHandling/SeString.cs b/Dalamud/Game/Text/SeStringHandling/SeString.cs index 91dceb5d1..4a04f0326 100644 --- a/Dalamud/Game/Text/SeStringHandling/SeString.cs +++ b/Dalamud/Game/Text/SeStringHandling/SeString.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; using System.Linq; diff --git a/Dalamud/Game/Text/SeStringHandling/SeStringBuilder.cs b/Dalamud/Game/Text/SeStringHandling/SeStringBuilder.cs index dae9e11a9..e78ac2de8 100644 --- a/Dalamud/Game/Text/SeStringHandling/SeStringBuilder.cs +++ b/Dalamud/Game/Text/SeStringHandling/SeStringBuilder.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Linq; using Dalamud.Game.Text.SeStringHandling.Payloads; diff --git a/Dalamud/Game/Text/XivChatEntry.cs b/Dalamud/Game/Text/XivChatEntry.cs index afc89b906..25f752054 100644 --- a/Dalamud/Game/Text/XivChatEntry.cs +++ b/Dalamud/Game/Text/XivChatEntry.cs @@ -1,5 +1,3 @@ -using System; - using Dalamud.Game.Text.SeStringHandling; namespace Dalamud.Game.Text; @@ -15,9 +13,9 @@ public sealed class XivChatEntry public XivChatType Type { get; set; } = XivChatType.Debug; /// - /// Gets or sets the sender ID. + /// Gets or sets the message timestamp. /// - public uint SenderId { get; set; } + public int Timestamp { get; set; } /// /// Gets or sets the sender name. @@ -30,7 +28,7 @@ public sealed class XivChatEntry public SeString Message { get; set; } = string.Empty; /// - /// Gets or sets the message parameters. + /// Gets or sets a value indicating whether new message sounds should be silenced or not. /// - public IntPtr Parameters { get; set; } + public bool Silent { get; set; } } diff --git a/Dalamud/Game/Text/XivChatType.cs b/Dalamud/Game/Text/XivChatType.cs index be9fb8e91..1a41a5eff 100644 --- a/Dalamud/Game/Text/XivChatType.cs +++ b/Dalamud/Game/Text/XivChatType.cs @@ -1,9 +1,9 @@ namespace Dalamud.Game.Text; /// -/// The FFXIV chat types as seen in the LogKind ex table. +/// The FFXIV chat types as seen in the LogKind excel sheet. /// -public enum XivChatType : ushort // FIXME: this is a single byte +public enum XivChatType : ushort { /// /// No chat type. diff --git a/Dalamud/Game/Text/XivChatTypeInfoAttribute.cs b/Dalamud/Game/Text/XivChatTypeInfoAttribute.cs index 91bdeef40..32ff89e32 100644 --- a/Dalamud/Game/Text/XivChatTypeInfoAttribute.cs +++ b/Dalamud/Game/Text/XivChatTypeInfoAttribute.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Game.Text; /// diff --git a/Dalamud/Hooking/AsmHook.cs b/Dalamud/Hooking/AsmHook.cs index b05347a0a..4ee96bb15 100644 --- a/Dalamud/Hooking/AsmHook.cs +++ b/Dalamud/Hooking/AsmHook.cs @@ -1,9 +1,8 @@ -using System; using System.Reflection; using System.Reflection.Emit; using Dalamud.Hooking.Internal; -using Dalamud.Memory; + using Reloaded.Hooks; namespace Dalamud.Hooking; diff --git a/Dalamud/Hooking/IDalamudHook.cs b/Dalamud/Hooking/IDalamudHook.cs index bd7084d86..bffca242e 100644 --- a/Dalamud/Hooking/IDalamudHook.cs +++ b/Dalamud/Hooking/IDalamudHook.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Hooking; /// diff --git a/Dalamud/Hooking/Internal/CallHook.cs b/Dalamud/Hooking/Internal/CallHook.cs index 2bef59c86..c9b5562ba 100644 --- a/Dalamud/Hooking/Internal/CallHook.cs +++ b/Dalamud/Hooking/Internal/CallHook.cs @@ -1,5 +1,4 @@ -using System; -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; using Reloaded.Hooks.Definitions; diff --git a/Dalamud/Hooking/Internal/FunctionPointerVariableHook.cs b/Dalamud/Hooking/Internal/FunctionPointerVariableHook.cs index e1900a903..7a177206f 100644 --- a/Dalamud/Hooking/Internal/FunctionPointerVariableHook.cs +++ b/Dalamud/Hooking/Internal/FunctionPointerVariableHook.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.ComponentModel; using System.Reflection; diff --git a/Dalamud/Hooking/Internal/GameInteropProviderPluginScoped.cs b/Dalamud/Hooking/Internal/GameInteropProviderPluginScoped.cs index 1138d4e07..eb096a771 100644 --- a/Dalamud/Hooking/Internal/GameInteropProviderPluginScoped.cs +++ b/Dalamud/Hooking/Internal/GameInteropProviderPluginScoped.cs @@ -47,7 +47,7 @@ internal class GameInteropProviderPluginScoped : IGameInteropProvider, IInternal } /// - public Hook HookFromFunctionPointerVariable(IntPtr address, T detour) where T : Delegate + public Hook HookFromFunctionPointerVariable(nint address, T detour) where T : Delegate { var hook = Hook.FromFunctionPointerVariable(address, detour); this.trackedHooks.Add(hook); @@ -71,13 +71,21 @@ internal class GameInteropProviderPluginScoped : IGameInteropProvider, IInternal } /// - public Hook HookFromAddress(IntPtr procAddress, T detour, IGameInteropProvider.HookBackend backend = IGameInteropProvider.HookBackend.Automatic) where T : Delegate + public Hook HookFromAddress(nint procAddress, T detour, IGameInteropProvider.HookBackend backend = IGameInteropProvider.HookBackend.Automatic) where T : Delegate { var hook = Hook.FromAddress(procAddress, detour, backend == IGameInteropProvider.HookBackend.MinHook); this.trackedHooks.Add(hook); return hook; } + /// + public Hook HookFromAddress(UIntPtr procAddress, T detour, IGameInteropProvider.HookBackend backend = IGameInteropProvider.HookBackend.Automatic) where T : Delegate + => this.HookFromAddress((nint)procAddress, detour, backend); + + /// + public unsafe Hook HookFromAddress(void* procAddress, T detour, IGameInteropProvider.HookBackend backend = IGameInteropProvider.HookBackend.Automatic) where T : Delegate + => this.HookFromAddress((nint)procAddress, detour, backend); + /// public Hook HookFromSignature(string signature, T detour, IGameInteropProvider.HookBackend backend = IGameInteropProvider.HookBackend.Automatic) where T : Delegate => this.HookFromAddress(this.scanner.ScanText(signature), detour, backend); diff --git a/Dalamud/Hooking/Internal/HookInfo.cs b/Dalamud/Hooking/Internal/HookInfo.cs index 0ab05c314..3672e8e01 100644 --- a/Dalamud/Hooking/Internal/HookInfo.cs +++ b/Dalamud/Hooking/Internal/HookInfo.cs @@ -1,4 +1,3 @@ -using System; using System.Diagnostics; using System.Reflection; diff --git a/Dalamud/Hooking/Internal/HookManager.cs b/Dalamud/Hooking/Internal/HookManager.cs index c8cdf3a46..44c1e6735 100644 --- a/Dalamud/Hooking/Internal/HookManager.cs +++ b/Dalamud/Hooking/Internal/HookManager.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; @@ -6,6 +5,7 @@ using System.Runtime.InteropServices; using Dalamud.Logging.Internal; using Dalamud.Memory; + using Iced.Intel; namespace Dalamud.Hooking.Internal; diff --git a/Dalamud/Hooking/Internal/MinHookHook.cs b/Dalamud/Hooking/Internal/MinHookHook.cs index 89a7d9206..4cebca0d0 100644 --- a/Dalamud/Hooking/Internal/MinHookHook.cs +++ b/Dalamud/Hooking/Internal/MinHookHook.cs @@ -1,4 +1,3 @@ -using System; using System.Reflection; namespace Dalamud.Hooking.Internal; diff --git a/Dalamud/Hooking/Internal/PeHeader.cs b/Dalamud/Hooking/Internal/PeHeader.cs index b0e1770f5..51df4a174 100644 --- a/Dalamud/Hooking/Internal/PeHeader.cs +++ b/Dalamud/Hooking/Internal/PeHeader.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.InteropServices; #pragma warning disable diff --git a/Dalamud/Hooking/Internal/ReloadedHook.cs b/Dalamud/Hooking/Internal/ReloadedHook.cs index 172bd9671..bf441a86d 100644 --- a/Dalamud/Hooking/Internal/ReloadedHook.cs +++ b/Dalamud/Hooking/Internal/ReloadedHook.cs @@ -1,4 +1,3 @@ -using System; using System.Reflection; using Reloaded.Hooks; diff --git a/Dalamud/Hooking/Internal/Unhooker.cs b/Dalamud/Hooking/Internal/Unhooker.cs index 09b071ee9..79ee59b66 100644 --- a/Dalamud/Hooking/Internal/Unhooker.cs +++ b/Dalamud/Hooking/Internal/Unhooker.cs @@ -1,6 +1,4 @@ -using System; - -using Dalamud.Memory; +using Dalamud.Memory; namespace Dalamud.Hooking.Internal; diff --git a/Dalamud/Interface/Animation/Easing.cs b/Dalamud/Interface/Animation/Easing.cs index 54c41c16d..edab25149 100644 --- a/Dalamud/Interface/Animation/Easing.cs +++ b/Dalamud/Interface/Animation/Easing.cs @@ -1,5 +1,4 @@ -using System; -using System.Diagnostics; +using System.Diagnostics; using System.Numerics; namespace Dalamud.Interface.Animation; diff --git a/Dalamud/Interface/Animation/EasingFunctions/InCirc.cs b/Dalamud/Interface/Animation/EasingFunctions/InCirc.cs index ebfc1341c..c467104c5 100644 --- a/Dalamud/Interface/Animation/EasingFunctions/InCirc.cs +++ b/Dalamud/Interface/Animation/EasingFunctions/InCirc.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface.Animation.EasingFunctions; +namespace Dalamud.Interface.Animation.EasingFunctions; /// /// Class providing an "InCirc" easing animation. diff --git a/Dalamud/Interface/Animation/EasingFunctions/InCubic.cs b/Dalamud/Interface/Animation/EasingFunctions/InCubic.cs index d49715893..78f6774ac 100644 --- a/Dalamud/Interface/Animation/EasingFunctions/InCubic.cs +++ b/Dalamud/Interface/Animation/EasingFunctions/InCubic.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface.Animation.EasingFunctions; +namespace Dalamud.Interface.Animation.EasingFunctions; /// /// Class providing an "InCubic" easing animation. diff --git a/Dalamud/Interface/Animation/EasingFunctions/InElastic.cs b/Dalamud/Interface/Animation/EasingFunctions/InElastic.cs index 30e21cca8..c53c3d587 100644 --- a/Dalamud/Interface/Animation/EasingFunctions/InElastic.cs +++ b/Dalamud/Interface/Animation/EasingFunctions/InElastic.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface.Animation.EasingFunctions; +namespace Dalamud.Interface.Animation.EasingFunctions; /// /// Class providing an "InElastic" easing animation. diff --git a/Dalamud/Interface/Animation/EasingFunctions/InOutCirc.cs b/Dalamud/Interface/Animation/EasingFunctions/InOutCirc.cs index fa90c9fd3..71a598dfb 100644 --- a/Dalamud/Interface/Animation/EasingFunctions/InOutCirc.cs +++ b/Dalamud/Interface/Animation/EasingFunctions/InOutCirc.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface.Animation.EasingFunctions; +namespace Dalamud.Interface.Animation.EasingFunctions; /// /// Class providing an "InOutCirc" easing animation. diff --git a/Dalamud/Interface/Animation/EasingFunctions/InOutCubic.cs b/Dalamud/Interface/Animation/EasingFunctions/InOutCubic.cs index bc55bff70..07bcfa28d 100644 --- a/Dalamud/Interface/Animation/EasingFunctions/InOutCubic.cs +++ b/Dalamud/Interface/Animation/EasingFunctions/InOutCubic.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface.Animation.EasingFunctions; +namespace Dalamud.Interface.Animation.EasingFunctions; /// /// Class providing an "InOutCubic" easing animation. diff --git a/Dalamud/Interface/Animation/EasingFunctions/InOutElastic.cs b/Dalamud/Interface/Animation/EasingFunctions/InOutElastic.cs index b0c76b725..f78f9f336 100644 --- a/Dalamud/Interface/Animation/EasingFunctions/InOutElastic.cs +++ b/Dalamud/Interface/Animation/EasingFunctions/InOutElastic.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface.Animation.EasingFunctions; +namespace Dalamud.Interface.Animation.EasingFunctions; /// /// Class providing an "InOutCirc" easing animation. diff --git a/Dalamud/Interface/Animation/EasingFunctions/InOutQuint.cs b/Dalamud/Interface/Animation/EasingFunctions/InOutQuint.cs index a4d427710..64ab98b16 100644 --- a/Dalamud/Interface/Animation/EasingFunctions/InOutQuint.cs +++ b/Dalamud/Interface/Animation/EasingFunctions/InOutQuint.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface.Animation.EasingFunctions; +namespace Dalamud.Interface.Animation.EasingFunctions; /// /// Class providing an "InOutQuint" easing animation. diff --git a/Dalamud/Interface/Animation/EasingFunctions/InOutSine.cs b/Dalamud/Interface/Animation/EasingFunctions/InOutSine.cs index a3700d6c5..2f347ff80 100644 --- a/Dalamud/Interface/Animation/EasingFunctions/InOutSine.cs +++ b/Dalamud/Interface/Animation/EasingFunctions/InOutSine.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface.Animation.EasingFunctions; +namespace Dalamud.Interface.Animation.EasingFunctions; /// /// Class providing an "InOutSine" easing animation. diff --git a/Dalamud/Interface/Animation/EasingFunctions/InQuint.cs b/Dalamud/Interface/Animation/EasingFunctions/InQuint.cs index 20122efc6..a5ab5a22c 100644 --- a/Dalamud/Interface/Animation/EasingFunctions/InQuint.cs +++ b/Dalamud/Interface/Animation/EasingFunctions/InQuint.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface.Animation.EasingFunctions; +namespace Dalamud.Interface.Animation.EasingFunctions; /// /// Class providing an "InQuint" easing animation. diff --git a/Dalamud/Interface/Animation/EasingFunctions/InSine.cs b/Dalamud/Interface/Animation/EasingFunctions/InSine.cs index 553996303..fa079baad 100644 --- a/Dalamud/Interface/Animation/EasingFunctions/InSine.cs +++ b/Dalamud/Interface/Animation/EasingFunctions/InSine.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface.Animation.EasingFunctions; +namespace Dalamud.Interface.Animation.EasingFunctions; /// /// Class providing an "InSine" easing animation. diff --git a/Dalamud/Interface/Animation/EasingFunctions/OutCirc.cs b/Dalamud/Interface/Animation/EasingFunctions/OutCirc.cs index 356beb13d..b0d3b895a 100644 --- a/Dalamud/Interface/Animation/EasingFunctions/OutCirc.cs +++ b/Dalamud/Interface/Animation/EasingFunctions/OutCirc.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface.Animation.EasingFunctions; +namespace Dalamud.Interface.Animation.EasingFunctions; /// /// Class providing an "OutCirc" easing animation. diff --git a/Dalamud/Interface/Animation/EasingFunctions/OutCubic.cs b/Dalamud/Interface/Animation/EasingFunctions/OutCubic.cs index 9fbe48b26..9c1bb57dc 100644 --- a/Dalamud/Interface/Animation/EasingFunctions/OutCubic.cs +++ b/Dalamud/Interface/Animation/EasingFunctions/OutCubic.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface.Animation.EasingFunctions; +namespace Dalamud.Interface.Animation.EasingFunctions; /// /// Class providing an "OutCubic" easing animation. diff --git a/Dalamud/Interface/Animation/EasingFunctions/OutElastic.cs b/Dalamud/Interface/Animation/EasingFunctions/OutElastic.cs index d73fca30e..6a4fcd6dc 100644 --- a/Dalamud/Interface/Animation/EasingFunctions/OutElastic.cs +++ b/Dalamud/Interface/Animation/EasingFunctions/OutElastic.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface.Animation.EasingFunctions; +namespace Dalamud.Interface.Animation.EasingFunctions; /// /// Class providing an "OutElastic" easing animation. diff --git a/Dalamud/Interface/Animation/EasingFunctions/OutQuint.cs b/Dalamud/Interface/Animation/EasingFunctions/OutQuint.cs index f83a4eb47..a3174e762 100644 --- a/Dalamud/Interface/Animation/EasingFunctions/OutQuint.cs +++ b/Dalamud/Interface/Animation/EasingFunctions/OutQuint.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface.Animation.EasingFunctions; +namespace Dalamud.Interface.Animation.EasingFunctions; /// /// Class providing an "OutQuint" easing animation. diff --git a/Dalamud/Interface/Animation/EasingFunctions/OutSine.cs b/Dalamud/Interface/Animation/EasingFunctions/OutSine.cs index 1576f697b..ba82232b3 100644 --- a/Dalamud/Interface/Animation/EasingFunctions/OutSine.cs +++ b/Dalamud/Interface/Animation/EasingFunctions/OutSine.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface.Animation.EasingFunctions; +namespace Dalamud.Interface.Animation.EasingFunctions; /// /// Class providing an "OutSine" easing animation. diff --git a/Dalamud/Interface/ColorHelpers.cs b/Dalamud/Interface/ColorHelpers.cs index 74561f9ef..971e546bc 100644 --- a/Dalamud/Interface/ColorHelpers.cs +++ b/Dalamud/Interface/ColorHelpers.cs @@ -1,3 +1,4 @@ +using System.Buffers.Binary; using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Numerics; @@ -159,6 +160,16 @@ public static class ColorHelpers return new Vector4(r, g, b, hsv.A); } + /// + /// Performs a swap of endianness + /// Exmaple: + /// (FFXIV) RGBA to ABGR (ImGui) + /// + /// Color value in byte order X Y Z W. + /// Endian swapped color value with new byte order W Z Y X. + public static uint SwapEndianness(uint rgba) + => BinaryPrimitives.ReverseEndianness(rgba); + /// /// Lighten a color. /// @@ -259,7 +270,7 @@ public static class ColorHelpers hsv.A -= amount; return HsvToRgb(hsv); } - + /// /// Set alpha of a color. /// @@ -299,10 +310,10 @@ public static class ColorHelpers { // If any components are out of range, return original value. { W: > 255.0f or < 0.0f } or { X: > 255.0f or < 0.0f } or { Y: > 255.0f or < 0.0f } or { Z: > 255.0f or < 0.0f } => color, - + // If all components are already unit range, return original value. { W: >= 0.0f and <= 1.0f, X: >= 0.0f and <= 1.0f, Y: >= 0.0f and <= 1.0f, Z: >= 0.0f and <= 1.0f } => color, - + _ => color / 255.0f, }; } diff --git a/Dalamud/Interface/Components/ImGuiComponents.IconButton.cs b/Dalamud/Interface/Components/ImGuiComponents.IconButton.cs index 719f470b8..dc2c99608 100644 --- a/Dalamud/Interface/Components/ImGuiComponents.IconButton.cs +++ b/Dalamud/Interface/Components/ImGuiComponents.IconButton.cs @@ -1,4 +1,3 @@ -using System; using System.Numerics; using Dalamud.Interface.Utility; diff --git a/Dalamud/Interface/DalamudWindowOpenKinds.cs b/Dalamud/Interface/DalamudWindowOpenKinds.cs new file mode 100644 index 000000000..18ecf5386 --- /dev/null +++ b/Dalamud/Interface/DalamudWindowOpenKinds.cs @@ -0,0 +1,53 @@ +namespace Dalamud.Interface; + +/// +/// Enum describing pages the plugin installer can be opened to. +/// +public enum PluginInstallerOpenKind +{ + /// + /// Open to the "All Plugins" page. + /// + AllPlugins, + + /// + /// Open to the "Installed Plugins" page. + /// + InstalledPlugins, + + /// + /// Open to the "Changelogs" page. + /// + Changelogs, +} + +/// +/// Enum describing tabs the settings window can be opened to. +/// +public enum SettingsOpenKind +{ + /// + /// Open to the "General" page. + /// + General, + + /// + /// Open to the "Look & Feel" page. + /// + LookAndFeel, + + /// + /// Open to the "Server Info Bar" page. + /// + ServerInfoBar, + + /// + /// Open to the "Experimental" page. + /// + Experimental, + + /// + /// Open to the "About" page. + /// + About, +} diff --git a/Dalamud/Interface/DragDrop/DragDropInterop.cs b/Dalamud/Interface/DragDrop/DragDropInterop.cs index 6a7043861..c2cbffb68 100644 --- a/Dalamud/Interface/DragDrop/DragDropInterop.cs +++ b/Dalamud/Interface/DragDrop/DragDropInterop.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; diff --git a/Dalamud/Interface/DragDrop/DragDropManager.cs b/Dalamud/Interface/DragDrop/DragDropManager.cs index be1865415..c9f0f9b80 100644 --- a/Dalamud/Interface/DragDrop/DragDropManager.cs +++ b/Dalamud/Interface/DragDrop/DragDropManager.cs @@ -1,10 +1,10 @@ -using System; using System.Collections.Generic; using System.Runtime.InteropServices; using Dalamud.Interface.Internal; using Dalamud.IoC; using Dalamud.IoC.Internal; + using ImGuiNET; using Serilog; diff --git a/Dalamud/Interface/DragDrop/DragDropTarget.cs b/Dalamud/Interface/DragDrop/DragDropTarget.cs index bbd7a5061..8115e7353 100644 --- a/Dalamud/Interface/DragDrop/DragDropTarget.cs +++ b/Dalamud/Interface/DragDrop/DragDropTarget.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; using System.Linq; diff --git a/Dalamud/Interface/FontAwesome/FontAwesomeCategoriesAttribute.cs b/Dalamud/Interface/FontAwesome/FontAwesomeCategoriesAttribute.cs index 62572057d..624208c3d 100644 --- a/Dalamud/Interface/FontAwesome/FontAwesomeCategoriesAttribute.cs +++ b/Dalamud/Interface/FontAwesome/FontAwesomeCategoriesAttribute.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface; +namespace Dalamud.Interface; /// /// Set categories associated with a font awesome icon. diff --git a/Dalamud/Interface/FontAwesome/FontAwesomeHelpers.cs b/Dalamud/Interface/FontAwesome/FontAwesomeHelpers.cs index 2259db148..14a7072b9 100644 --- a/Dalamud/Interface/FontAwesome/FontAwesomeHelpers.cs +++ b/Dalamud/Interface/FontAwesome/FontAwesomeHelpers.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; diff --git a/Dalamud/Interface/FontAwesome/FontAwesomeSearchTermsAttribute.cs b/Dalamud/Interface/FontAwesome/FontAwesomeSearchTermsAttribute.cs index 6ee1c75cd..fd4c90fa1 100644 --- a/Dalamud/Interface/FontAwesome/FontAwesomeSearchTermsAttribute.cs +++ b/Dalamud/Interface/FontAwesome/FontAwesomeSearchTermsAttribute.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface; +namespace Dalamud.Interface; /// /// Set search terms associated with a font awesome icon. diff --git a/Dalamud/Interface/GameFonts/GameFontLayoutPlan.cs b/Dalamud/Interface/GameFonts/GameFontLayoutPlan.cs index 587c0dbe3..6b602d911 100644 --- a/Dalamud/Interface/GameFonts/GameFontLayoutPlan.cs +++ b/Dalamud/Interface/GameFonts/GameFontLayoutPlan.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Numerics; diff --git a/Dalamud/Interface/ImGuiFileDialog/DriveListLoader.cs b/Dalamud/Interface/ImGuiFileDialog/DriveListLoader.cs index 5898fefdf..487a08132 100644 --- a/Dalamud/Interface/ImGuiFileDialog/DriveListLoader.cs +++ b/Dalamud/Interface/ImGuiFileDialog/DriveListLoader.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Threading.Tasks; diff --git a/Dalamud/Interface/ImGuiFileDialog/FileDialog.Files.cs b/Dalamud/Interface/ImGuiFileDialog/FileDialog.Files.cs index ba71c8cfa..121ec8890 100644 --- a/Dalamud/Interface/ImGuiFileDialog/FileDialog.Files.cs +++ b/Dalamud/Interface/ImGuiFileDialog/FileDialog.Files.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; using System.Linq; diff --git a/Dalamud/Interface/ImGuiFileDialog/FileDialog.Helpers.cs b/Dalamud/Interface/ImGuiFileDialog/FileDialog.Helpers.cs index 96bdb3172..57844c48b 100644 --- a/Dalamud/Interface/ImGuiFileDialog/FileDialog.Helpers.cs +++ b/Dalamud/Interface/ImGuiFileDialog/FileDialog.Helpers.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Interface.ImGuiFileDialog; /// diff --git a/Dalamud/Interface/ImGuiFileDialog/FileDialog.Structs.cs b/Dalamud/Interface/ImGuiFileDialog/FileDialog.Structs.cs index 07e3bc20f..2a5d1b607 100644 --- a/Dalamud/Interface/ImGuiFileDialog/FileDialog.Structs.cs +++ b/Dalamud/Interface/ImGuiFileDialog/FileDialog.Structs.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; using System.Linq; diff --git a/Dalamud/Interface/ImGuiFileDialog/FileDialog.cs b/Dalamud/Interface/ImGuiFileDialog/FileDialog.cs index 411f203cc..1d31642d3 100644 --- a/Dalamud/Interface/ImGuiFileDialog/FileDialog.cs +++ b/Dalamud/Interface/ImGuiFileDialog/FileDialog.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; using System.Linq; diff --git a/Dalamud/Interface/ImGuiFileDialog/FileDialogManager.cs b/Dalamud/Interface/ImGuiFileDialog/FileDialogManager.cs index 7970279af..ae9c8ef38 100644 --- a/Dalamud/Interface/ImGuiFileDialog/FileDialogManager.cs +++ b/Dalamud/Interface/ImGuiFileDialog/FileDialogManager.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using ImGuiNET; diff --git a/Dalamud/Interface/ImGuiFileDialog/ImGuiFileDialogFlags.cs b/Dalamud/Interface/ImGuiFileDialog/ImGuiFileDialogFlags.cs index ea35f4c65..510348710 100644 --- a/Dalamud/Interface/ImGuiFileDialog/ImGuiFileDialogFlags.cs +++ b/Dalamud/Interface/ImGuiFileDialog/ImGuiFileDialogFlags.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Interface.ImGuiFileDialog; /// diff --git a/Dalamud/Interface/Internal/DalamudCommands.cs b/Dalamud/Interface/Internal/DalamudCommands.cs index b64df8f19..9e6f7cf32 100644 --- a/Dalamud/Interface/Internal/DalamudCommands.cs +++ b/Dalamud/Interface/Internal/DalamudCommands.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; diff --git a/Dalamud/Interface/Internal/DalamudIme.cs b/Dalamud/Interface/Internal/DalamudIme.cs index 35e33fbfb..c061ec12d 100644 --- a/Dalamud/Interface/Internal/DalamudIme.cs +++ b/Dalamud/Interface/Internal/DalamudIme.cs @@ -11,7 +11,7 @@ using System.Runtime.InteropServices; using System.Text; using System.Text.Unicode; -using Dalamud.Game; +using Dalamud.Configuration.Internal; using Dalamud.Game.Text; using Dalamud.Hooking.WndProcHook; using Dalamud.Interface.Colors; @@ -75,6 +75,9 @@ internal sealed unsafe class DalamudIme : IInternalDisposableService private static readonly delegate* unmanaged StbTextUndo; + [ServiceManager.ServiceDependency] + private readonly DalamudConfiguration dalamudConfiguration = Service.Get(); + [ServiceManager.ServiceDependency] private readonly WndProcHookManager wndProcHookManager = Service.Get(); @@ -775,30 +778,42 @@ internal sealed unsafe class DalamudIme : IInternalDisposableService ImGui.GetStyle().WindowRounding); } + var stateOpacity = Math.Clamp(this.dalamudConfiguration.ImeStateIndicatorOpacity, 0, 1); + var stateBg = ImGui.GetColorU32( + new Vector4(1, 1, 1, MathF.Pow(stateOpacity, 2)) * *ImGui.GetStyleColorVec4(ImGuiCol.WindowBg)); + var stateFg = + ImGui.GetColorU32(new Vector4(1, 1, 1, stateOpacity) * *ImGui.GetStyleColorVec4(ImGuiCol.Text)); if (!expandUpward && drawIme) { - for (var dx = -2; dx <= 2; dx++) + if (stateBg >= 0x1000000) { - for (var dy = -2; dy <= 2; dy++) + for (var dx = -2; dx <= 2; dx++) { - if (dx != 0 || dy != 0) + for (var dy = -2; dy <= 2; dy++) { - imeIconFont.RenderChar( - drawList, - imeIconFont.FontSize, - cursor + new Vector2(dx, dy), - ImGui.GetColorU32(ImGuiCol.WindowBg), - ime.inputModeIcon); + if (dx != 0 || dy != 0) + { + imeIconFont.RenderChar( + drawList, + imeIconFont.FontSize, + cursor + new Vector2(dx, dy), + stateBg, + ime.inputModeIcon); + } } } } - imeIconFont.RenderChar( - drawList, - imeIconFont.FontSize, - cursor, - ImGui.GetColorU32(ImGuiCol.Text), - ime.inputModeIcon); + if (stateFg >= 0x1000000) + { + imeIconFont.RenderChar( + drawList, + imeIconFont.FontSize, + cursor, + stateFg, + ime.inputModeIcon); + } + cursor.Y += candTextSize.Y + spaceY; } @@ -852,28 +867,34 @@ internal sealed unsafe class DalamudIme : IInternalDisposableService if (expandUpward && drawIme) { - for (var dx = -2; dx <= 2; dx++) + if (stateBg >= 0x1000000) { - for (var dy = -2; dy <= 2; dy++) + for (var dx = -2; dx <= 2; dx++) { - if (dx != 0 || dy != 0) + for (var dy = -2; dy <= 2; dy++) { - imeIconFont.RenderChar( - drawList, - imeIconFont.FontSize, - cursor + new Vector2(dx, dy), - ImGui.GetColorU32(ImGuiCol.WindowBg), - ime.inputModeIcon); + if (dx != 0 || dy != 0) + { + imeIconFont.RenderChar( + drawList, + imeIconFont.FontSize, + cursor + new Vector2(dx, dy), + ImGui.GetColorU32(ImGuiCol.WindowBg), + ime.inputModeIcon); + } } } } - imeIconFont.RenderChar( - drawList, - imeIconFont.FontSize, - cursor, - ImGui.GetColorU32(ImGuiCol.Text), - ime.inputModeIcon); + if (stateFg >= 0x1000000) + { + imeIconFont.RenderChar( + drawList, + imeIconFont.FontSize, + cursor, + ImGui.GetColorU32(ImGuiCol.Text), + ime.inputModeIcon); + } } return; diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs index da5570848..5f5a0b71b 100644 --- a/Dalamud/Interface/Internal/DalamudInterface.cs +++ b/Dalamud/Interface/Internal/DalamudInterface.cs @@ -304,10 +304,10 @@ internal class DalamudInterface : IInternalDisposableService } /// - /// Opens the on the plugin installed. + /// Opens the on the specified page. /// /// The page of the installer to open. - public void OpenPluginInstallerTo(PluginInstallerWindow.PluginInstallerOpenKind kind) + public void OpenPluginInstallerTo(PluginInstallerOpenKind kind) { this.pluginWindow.OpenTo(kind); this.pluginWindow.BringToFront(); @@ -322,6 +322,16 @@ internal class DalamudInterface : IInternalDisposableService this.settingsWindow.BringToFront(); } + /// + /// Opens the on the specified tab. + /// + /// The tab of the settings to open. + public void OpenSettingsTo(SettingsOpenKind kind) + { + this.settingsWindow.OpenTo(kind); + this.settingsWindow.BringToFront(); + } + /// /// Opens the . /// @@ -432,7 +442,7 @@ internal class DalamudInterface : IInternalDisposableService /// Toggles the . /// /// The page of the installer to open. - public void TogglePluginInstallerWindowTo(PluginInstallerWindow.PluginInstallerOpenKind kind) => this.pluginWindow.ToggleTo(kind); + public void TogglePluginInstallerWindowTo(PluginInstallerOpenKind kind) => this.pluginWindow.ToggleTo(kind); /// /// Toggles the . @@ -470,6 +480,15 @@ internal class DalamudInterface : IInternalDisposableService this.pluginWindow.SetSearchText(text); } + /// + /// Sets the current search text for the settings window. + /// + /// The search term. + public void SetSettingsSearchText(string text) + { + this.settingsWindow.SetSearchText(text); + } + /// /// Toggle the screen darkening effect used for the credits. /// @@ -889,7 +908,7 @@ internal class DalamudInterface : IInternalDisposableService unsafe { var hook = Hook.FromAddress( - (nint)UIModule.StaticVTable.GetUIInputData, + (nint)UIModule.StaticVirtualTablePointer->GetUIInputData, self => { _ = *(byte*)0; diff --git a/Dalamud/Interface/Internal/PluginCategoryManager.cs b/Dalamud/Interface/Internal/PluginCategoryManager.cs index ddfcff6bc..3f94b2d2e 100644 --- a/Dalamud/Interface/Internal/PluginCategoryManager.cs +++ b/Dalamud/Interface/Internal/PluginCategoryManager.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; diff --git a/Dalamud/Interface/Internal/UiDebug.cs b/Dalamud/Interface/Internal/UiDebug.cs index d93b90799..6409021de 100644 --- a/Dalamud/Interface/Internal/UiDebug.cs +++ b/Dalamud/Interface/Internal/UiDebug.cs @@ -1,9 +1,6 @@ -using System; using System.Numerics; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Dalamud.Game; using Dalamud.Game.Gui; using Dalamud.Interface.Utility; using Dalamud.Memory; @@ -83,7 +80,7 @@ internal unsafe class UiDebug private void DrawUnitBase(AtkUnitBase* atkUnitBase) { var isVisible = (atkUnitBase->Flags & 0x20) == 0x20; - var addonName = MemoryHelper.ReadSeStringAsString(out _, new IntPtr(atkUnitBase->Name)); + var addonName = atkUnitBase->NameString; var agent = Service.Get().FindAgentInterface(atkUnitBase); ImGui.Text($"{addonName}"); @@ -355,11 +352,11 @@ internal unsafe class UiDebug var textInputComponent = (AtkComponentTextInput*)compNode->Component; ImGui.Text($"InputBase Text1: {MemoryHelper.ReadSeStringAsString(out _, new IntPtr(textInputComponent->AtkComponentInputBase.UnkText1.StringPtr))}"); ImGui.Text($"InputBase Text2: {MemoryHelper.ReadSeStringAsString(out _, new IntPtr(textInputComponent->AtkComponentInputBase.UnkText2.StringPtr))}"); - ImGui.Text($"Text1: {MemoryHelper.ReadSeStringAsString(out _, new IntPtr(textInputComponent->UnkText1.StringPtr))}"); - ImGui.Text($"Text2: {MemoryHelper.ReadSeStringAsString(out _, new IntPtr(textInputComponent->UnkText2.StringPtr))}"); - ImGui.Text($"Text3: {MemoryHelper.ReadSeStringAsString(out _, new IntPtr(textInputComponent->UnkText3.StringPtr))}"); - ImGui.Text($"Text4: {MemoryHelper.ReadSeStringAsString(out _, new IntPtr(textInputComponent->UnkText4.StringPtr))}"); - ImGui.Text($"Text5: {MemoryHelper.ReadSeStringAsString(out _, new IntPtr(textInputComponent->UnkText5.StringPtr))}"); + ImGui.Text($"Text1: {MemoryHelper.ReadSeStringAsString(out _, new IntPtr(textInputComponent->UnkText01.StringPtr))}"); + ImGui.Text($"Text2: {MemoryHelper.ReadSeStringAsString(out _, new IntPtr(textInputComponent->UnkText02.StringPtr))}"); + ImGui.Text($"Text3: {MemoryHelper.ReadSeStringAsString(out _, new IntPtr(textInputComponent->UnkText03.StringPtr))}"); + ImGui.Text($"Text4: {MemoryHelper.ReadSeStringAsString(out _, new IntPtr(textInputComponent->UnkText04.StringPtr))}"); + ImGui.Text($"Text5: {MemoryHelper.ReadSeStringAsString(out _, new IntPtr(textInputComponent->UnkText05.StringPtr))}"); break; } @@ -393,7 +390,7 @@ internal unsafe class UiDebug private void PrintResNode(AtkResNode* node) { - ImGui.Text($"NodeID: {node->NodeID}"); + ImGui.Text($"NodeID: {node->NodeId}"); ImGui.SameLine(); if (ImGui.SmallButton($"T:Visible##{(ulong)node:X}")) { @@ -442,7 +439,7 @@ internal unsafe class UiDebug { var foundSelected = false; var noResults = true; - var stage = AtkStage.GetSingleton(); + var stage = AtkStage.Instance(); var unitManagers = &stage->RaptureAtkUnitManager->AtkUnitManager.DepthLayerOneList; @@ -468,14 +465,14 @@ internal unsafe class UiDebug for (var j = 0; j < unitManager->Count && headerOpen; j++) { - var unitBase = *(AtkUnitBase**)Unsafe.AsPointer(ref unitManager->EntriesSpan[j]); + AtkUnitBase* unitBase = unitManager->Entries[j]; if (this.selectedUnitBase != null && unitBase == this.selectedUnitBase) { this.selectedInList[i] = true; foundSelected = true; } - var name = MemoryHelper.ReadSeStringAsString(out _, new IntPtr(unitBase->Name)); + var name = unitBase->NameString; if (searching) { if (name == null || !name.ToLower().Contains(searchStr.ToLower())) continue; @@ -513,7 +510,7 @@ internal unsafe class UiDebug { for (var j = 0; j < unitManager->Count; j++) { - var unitBase = *(AtkUnitBase**)Unsafe.AsPointer(ref unitManager->EntriesSpan[j]); + AtkUnitBase* unitBase = unitManager->Entries[j]; if (this.selectedUnitBase == null || unitBase != this.selectedUnitBase) continue; this.selectedInList[i] = true; foundSelected = true; diff --git a/Dalamud/Interface/Internal/Windows/BranchSwitcherWindow.cs b/Dalamud/Interface/Internal/Windows/BranchSwitcherWindow.cs index dcde7d008..055cb9f49 100644 --- a/Dalamud/Interface/Internal/Windows/BranchSwitcherWindow.cs +++ b/Dalamud/Interface/Internal/Windows/BranchSwitcherWindow.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -11,6 +10,7 @@ using Dalamud.Interface.Colors; using Dalamud.Interface.Utility; using Dalamud.Interface.Windowing; using Dalamud.Networking.Http; + using ImGuiNET; using Newtonsoft.Json; diff --git a/Dalamud/Interface/Internal/Windows/ComponentDemoWindow.cs b/Dalamud/Interface/Internal/Windows/ComponentDemoWindow.cs index 8c5458557..0b704990b 100644 --- a/Dalamud/Interface/Internal/Windows/ComponentDemoWindow.cs +++ b/Dalamud/Interface/Internal/Windows/ComponentDemoWindow.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Numerics; diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/AddonLifecycleWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/AddonLifecycleWidget.cs index 26af2a8b2..0ac83c126 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/AddonLifecycleWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/AddonLifecycleWidget.cs @@ -1,10 +1,10 @@ using System.Diagnostics.CodeAnalysis; -using System.Drawing; using System.Linq; using Dalamud.Game.Addon.Lifecycle; using Dalamud.Interface.Colors; using Dalamud.Interface.Utility; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.Data.Widgets; diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/AddonWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/AddonWidget.cs index 1056b434e..cf4979368 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/AddonWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/AddonWidget.cs @@ -49,7 +49,7 @@ internal unsafe class AddonWidget : IDataWindowWidget } var addon = (FFXIVClientStructs.FFXIV.Component.GUI.AtkUnitBase*)address; - var name = MemoryHelper.ReadStringNullTerminated((nint)addon->Name); + var name = addon->NameString; 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")) diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/AddressesWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/AddressesWidget.cs index dfa6f173d..eb1164eb2 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/AddressesWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/AddressesWidget.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using Dalamud.Game; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.Data.Widgets; diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/AetherytesWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/AetherytesWidget.cs index fbb945368..606c49c49 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/AetherytesWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/AetherytesWidget.cs @@ -1,4 +1,5 @@ using Dalamud.Game.ClientState.Aetherytes; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.Data.Widgets; @@ -82,7 +83,7 @@ internal class AetherytesWidget : IDataWindowWidget ImGui.TextUnformatted($"{info.IsSharedHouse}"); ImGui.TableNextColumn(); // Apartment - ImGui.TextUnformatted($"{info.IsAppartment}"); + ImGui.TextUnformatted($"{info.IsApartment}"); } ImGui.EndTable(); diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/AtkArrayDataBrowserWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/AtkArrayDataBrowserWidget.cs index 4da2011a6..ee79764de 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/AtkArrayDataBrowserWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/AtkArrayDataBrowserWidget.cs @@ -30,7 +30,7 @@ internal unsafe class AtkArrayDataBrowserWidget : IDataWindowWidget { var fontWidth = ImGui.CalcTextSize("A").X; var fontHeight = ImGui.GetTextLineHeightWithSpacing(); - var uiModule = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance()->GetUiModule(); + var uiModule = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance()->GetUIModule(); if (uiModule == null) { diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/ConditionWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/ConditionWidget.cs index 7725df5bf..c3305c168 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/ConditionWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/ConditionWidget.cs @@ -1,4 +1,5 @@ using Dalamud.Game.ClientState.Conditions; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.Data.Widgets; diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/DtrBarWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/DtrBarWidget.cs index cc4e97779..dca5862c3 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/DtrBarWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/DtrBarWidget.cs @@ -1,5 +1,6 @@ using Dalamud.Configuration.Internal; using Dalamud.Game.Gui.Dtr; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.Data.Widgets; diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/FateTableWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/FateTableWidget.cs index de9af9aa2..b36a7836c 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/FateTableWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/FateTableWidget.cs @@ -1,4 +1,5 @@ using Dalamud.Game.ClientState.Fates; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.Data.Widgets; diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/FlyTextWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/FlyTextWidget.cs index ddbf61342..40275645f 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/FlyTextWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/FlyTextWidget.cs @@ -1,6 +1,7 @@ using System.Numerics; using Dalamud.Game.Gui.FlyText; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.Data.Widgets; diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/GamepadWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/GamepadWidget.cs index 0a8a15580..3e87540c3 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/GamepadWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/GamepadWidget.cs @@ -1,4 +1,5 @@ using Dalamud.Game.ClientState.GamePad; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.Data.Widgets; diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/KeyStateWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/KeyStateWidget.cs index 14fb7a5f2..ce56052b1 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/KeyStateWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/KeyStateWidget.cs @@ -1,5 +1,6 @@ using Dalamud.Game.ClientState.Keys; using Dalamud.Interface.Colors; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.Data.Widgets; diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/NetworkMonitorWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/NetworkMonitorWidget.cs index eab1ab781..41b0904df 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/NetworkMonitorWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/NetworkMonitorWidget.cs @@ -1,14 +1,13 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Numerics; using System.Text.RegularExpressions; -using Dalamud.Data; using Dalamud.Game.Network; using Dalamud.Interface.Utility; using Dalamud.Interface.Utility.Raii; using Dalamud.Memory; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.Data.Widgets; diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/ObjectTableWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/ObjectTableWidget.cs index b34eef6c8..963138bec 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/ObjectTableWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/ObjectTableWidget.cs @@ -81,7 +81,7 @@ internal class ObjectTableWidget : IDataWindowWidget // 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 objectText = $"{obj.Address.ToInt64():X}:{obj.GameObjectId:X}[{i}] - {obj.ObjectKind} - {obj.Name}"; var screenPos = ImGui.GetMainViewport().Pos; var screenSize = ImGui.GetMainViewport().Size; diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/PartyListWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/PartyListWidget.cs index 01c0b74b3..6e4cbcb16 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/PartyListWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/PartyListWidget.cs @@ -48,7 +48,7 @@ internal class PartyListWidget : IDataWindowWidget continue; } - ImGui.Text($"[{i}] {member.Address.ToInt64():X} - {member.Name} - {member.GameObject?.ObjectId}"); + ImGui.Text($"[{i}] {member.Address.ToInt64():X} - {member.Name} - {member.GameObject?.GameObjectId}"); if (this.resolveGameData) { var actor = member.GameObject; diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/ServicesWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/ServicesWidget.cs index 3a6145030..d1e6bc58a 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/ServicesWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/ServicesWidget.cs @@ -7,6 +7,7 @@ using Dalamud.Interface.Colors; using Dalamud.Interface.Utility; using Dalamud.Interface.Utility.Raii; using Dalamud.IoC.Internal; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.Data.Widgets; diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/ToastWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/ToastWidget.cs index 4bca6a839..e101fbd0b 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/ToastWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/ToastWidget.cs @@ -2,6 +2,7 @@ using Dalamud.Game.Gui.Toast; using Dalamud.Interface.Utility; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.Data.Widgets; diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/UIColorWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/UIColorWidget.cs index 3308325bc..1f8b4c62c 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/UIColorWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/UIColorWidget.cs @@ -1,6 +1,7 @@ using System.Numerics; using Dalamud.Data; + using ImGuiNET; using Lumina.Excel.GeneratedSheets; diff --git a/Dalamud/Interface/Internal/Windows/HitchSettingsWindow.cs b/Dalamud/Interface/Internal/Windows/HitchSettingsWindow.cs index f229b1de3..1f633934f 100644 --- a/Dalamud/Interface/Internal/Windows/HitchSettingsWindow.cs +++ b/Dalamud/Interface/Internal/Windows/HitchSettingsWindow.cs @@ -1,5 +1,6 @@ using Dalamud.Configuration.Internal; using Dalamud.Interface.Windowing; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows; diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelog.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelog.cs index 4f2c70a25..cc3a3ca25 100644 --- a/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelog.cs +++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelog.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; namespace Dalamud.Interface.Internal.Windows.PluginInstaller; diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelogEntry.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelogEntry.cs index 5108a535e..d643f4230 100644 --- a/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelogEntry.cs +++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelogEntry.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface.Internal.Windows.PluginInstaller; +namespace Dalamud.Interface.Internal.Windows.PluginInstaller; /// /// Class representing a Dalamud changelog. diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelogManager.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelogManager.cs index a9ad0c21a..f6171e192 100644 --- a/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelogManager.cs +++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelogManager.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Net.Http.Json; using System.Threading.Tasks; diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/IChangelogEntry.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/IChangelogEntry.cs index 1f5baa1be..97e615081 100644 --- a/Dalamud/Interface/Internal/Windows/PluginInstaller/IChangelogEntry.cs +++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/IChangelogEntry.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface.Internal.Windows.PluginInstaller; +namespace Dalamud.Interface.Internal.Windows.PluginInstaller; /// /// Class representing a changelog entry. diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs index c7456db2d..e404f805c 100644 --- a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs +++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs @@ -10,6 +10,7 @@ using System.Threading; using System.Threading.Tasks; using CheapLoc; + using Dalamud.Configuration.Internal; using Dalamud.Game.Command; using Dalamud.Interface.Animation.EasingFunctions; @@ -30,6 +31,7 @@ using Dalamud.Plugin.Internal.Types; using Dalamud.Plugin.Internal.Types.Manifest; using Dalamud.Support; using Dalamud.Utility; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.PluginInstaller; @@ -176,27 +178,6 @@ internal class PluginInstallerWindow : Window, IDisposable this.profileManagerWidget = new(this); } - /// - /// Enum describing pages the plugin installer can be opened to. - /// - public enum PluginInstallerOpenKind - { - /// - /// Open to the "All Plugins" page. - /// - AllPlugins, - - /// - /// Open to the "Installed Plugins" page. - /// - InstalledPlugins, - - /// - /// Open to the "Changelogs" page. - /// - Changelogs, - } - private enum OperationStatus { Idle, @@ -330,8 +311,16 @@ internal class PluginInstallerWindow : Window, IDisposable /// The search term. public void SetSearchText(string text) { - this.isSearchTextPrefilled = true; - this.searchText = text; + if (string.IsNullOrEmpty(text)) + { + this.isSearchTextPrefilled = false; + this.searchText = string.Empty; + } + else + { + this.isSearchTextPrefilled = true; + this.searchText = text; + } } /// @@ -592,7 +581,7 @@ internal class PluginInstallerWindow : Window, IDisposable var isProfileManager = this.categoryManager.CurrentGroupIdx == 1 && this.categoryManager.CurrentCategoryIdx == 2; - + // Disable search if profile editor using (ImRaii.Disabled(isProfileManager)) { @@ -638,7 +627,7 @@ internal class PluginInstallerWindow : Window, IDisposable lock (this.listLock) { this.ResortPlugins(); - + // Positions of plugins within the list is likely to change this.openPluginCollapsibles.Clear(); } @@ -743,7 +732,7 @@ internal class PluginInstallerWindow : Window, IDisposable var errorMessage = this.updatePluginCount > 0 ? Locs.ErrorModal_UpdaterFailPartial(this.updatePluginCount, errorPluginCount) : Locs.ErrorModal_UpdaterFail(errorPluginCount); - + var hintInsert = errorPlugins .Aggregate(string.Empty, (current, pluginUpdateStatus) => $"{current}* {pluginUpdateStatus.InternalName} ({PluginUpdateStatus.LocalizeUpdateStatusKind(pluginUpdateStatus.Status)})\n") .TrimEnd(); @@ -888,7 +877,7 @@ internal class PluginInstallerWindow : Window, IDisposable this.deletePluginConfigWarningModalTaskCompletionSource = new TaskCompletionSource(); return this.deletePluginConfigWarningModalTaskCompletionSource.Task; } - + private void DrawDeletePluginConfigWarningModal() { var modalTitle = Locs.DeletePluginConfigWarningModal_Title; @@ -914,7 +903,7 @@ internal class PluginInstallerWindow : Window, IDisposable ImGui.CloseCurrentPopup(); this.deletePluginConfigWarningModalTaskCompletionSource?.SetResult(false); } - + ImGui.EndPopup(); } @@ -1136,7 +1125,7 @@ internal class PluginInstallerWindow : Window, IDisposable private IEnumerable GatherProxies() { var proxies = new List(); - + var availableManifests = this.pluginListAvailable; var installedPlugins = this.pluginListInstalled.ToList(); // Copy intended @@ -1163,27 +1152,27 @@ internal class PluginInstallerWindow : Window, IDisposable .FirstOrDefault(plugin => plugin.Manifest.InternalName == availableManifest.InternalName && plugin.Manifest.RepoUrl == availableManifest.RepoUrl && !plugin.IsDev); - + // We "consumed" this plugin from the pile and remove it. if (plugin != null) { installedPlugins.Remove(plugin); proxies.Add(new PluginInstallerAvailablePluginProxy(availableManifest, plugin)); - + continue; } - + proxies.Add(new PluginInstallerAvailablePluginProxy(availableManifest, null)); } - + // Now, add all applicable local plugins that haven't been "used up", in most cases either dev or orphaned plugins. foreach (var installedPlugin in installedPlugins) { if (this.IsManifestFiltered(installedPlugin.Manifest)) continue; - + // TODO: We should also check categories here, for good measure - + proxies.Add(new PluginInstallerAvailablePluginProxy(null, installedPlugin)); } @@ -1200,7 +1189,7 @@ internal class PluginInstallerWindow : Window, IDisposable if (applicableManifest == null) throw new Exception("Could not determine manifest for available plugin"); - + ImGui.PushID($"{applicableManifest.InternalName}{applicableManifest.AssemblyVersion}"); if (proxy.LocalPlugin != null) @@ -1247,7 +1236,7 @@ internal class PluginInstallerWindow : Window, IDisposable var remoteManifest = this.pluginListAvailable .FirstOrDefault(rm => rm.InternalName == plugin.Manifest.InternalName && rm.RepoUrl == plugin.Manifest.RepoUrl); - + this.DrawInstalledPlugin(plugin, i++, remoteManifest); } } @@ -1292,7 +1281,7 @@ internal class PluginInstallerWindow : Window, IDisposable if (installerMainChild) { using var style = ImRaii.PushStyle(ImGuiStyleVar.CellPadding, ImGuiHelpers.ScaledVector2(5, 0)); - + try { using (var categoriesChild = ImRaii.Child("InstallerCategoriesSelector", new Vector2(useMenuWidth * ImGuiHelpers.GlobalScale, -1), false)) @@ -1865,17 +1854,17 @@ internal class PluginInstallerWindow : Window, IDisposable { iconTex = cachedIconTex; } - + const float fadeTime = 0.3f; var iconAlpha = 1f; if (loadedSince.HasValue) { float EaseOutCubic(float t) => 1 - MathF.Pow(1 - t, 3); - + var secondsSinceLoad = (float)DateTime.Now.Subtract(loadedSince.Value).TotalSeconds; var fadeTo = pluginDisabled || installableOutdated ? 0.4f : 1f; - + float Interp(float to) => Math.Clamp(EaseOutCubic(Math.Min(secondsSinceLoad, fadeTime) / fadeTime) * to, 0, 1); iconAlpha = Interp(fadeTo); overlayAlpha = Interp(1f); @@ -1911,7 +1900,7 @@ internal class PluginInstallerWindow : Window, IDisposable else ImGui.Dummy(iconSize); ImGui.PopStyleVar(); - + ImGui.SameLine(); ImGuiHelpers.ScaledDummy(5); @@ -1921,7 +1910,7 @@ internal class PluginInstallerWindow : Window, IDisposable // Name ImGui.TextUnformatted(label); - + // Verified Checkmark or dev plugin wrench { ImGui.SameLine(); @@ -1979,7 +1968,7 @@ internal class PluginInstallerWindow : Window, IDisposable bodyText += Locs.PluginBody_Outdated_CanNowUpdate; else bodyText += Locs.PluginBody_Outdated_WaitForUpdate; - + ImGui.TextWrapped(bodyText); ImGui.PopStyleColor(); } @@ -1987,17 +1976,17 @@ internal class PluginInstallerWindow : Window, IDisposable { // Banned warning ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed); - + var bodyText = plugin.BanReason.IsNullOrEmpty() ? Locs.PluginBody_Banned : Locs.PluginBody_BannedReason(plugin.BanReason); bodyText += " "; - + if (updateAvailable) bodyText += Locs.PluginBody_Outdated_CanNowUpdate; else bodyText += Locs.PluginBody_Outdated_WaitForUpdate; - + ImGuiHelpers.SafeTextWrapped(bodyText); ImGui.PopStyleColor(); @@ -2132,7 +2121,8 @@ internal class PluginInstallerWindow : Window, IDisposable var useTesting = pluginManager.UseTesting(manifest); var wasSeen = this.WasPluginSeen(manifest.InternalName); - var isOutdated = manifest.DalamudApiLevel < PluginManager.DalamudApiLevel; + var effectiveApiLevel = useTesting && manifest.TestingDalamudApiLevel != null ? manifest.TestingDalamudApiLevel.Value : manifest.DalamudApiLevel; + var isOutdated = effectiveApiLevel < PluginManager.DalamudApiLevel; // Check for valid versions if ((useTesting && manifest.TestingAssemblyVersion == null) || manifest.AssemblyVersion == null) @@ -2221,13 +2211,13 @@ internal class PluginInstallerWindow : Window, IDisposable ImGui.SameLine(); ImGuiHelpers.ScaledDummy(3); } - + if (!manifest.SourceRepo.IsThirdParty && manifest.AcceptsFeedback) { ImGui.SameLine(); this.DrawSendFeedbackButton(manifest, false, true); } - + ImGuiHelpers.ScaledDummy(5); if (this.DrawPluginImages(null, manifest, isThirdParty, index)) @@ -2355,11 +2345,11 @@ internal class PluginInstallerWindow : Window, IDisposable } var availablePluginUpdate = this.pluginListUpdatable.FirstOrDefault(up => up.InstalledPlugin == plugin); - + // Dev plugins can never update if (plugin.IsDev) availablePluginUpdate = null; - + // Update available if (availablePluginUpdate != default) { @@ -2420,7 +2410,7 @@ internal class PluginInstallerWindow : Window, IDisposable } ImGui.PushID($"installed{index}{plugin.Manifest.InternalName}"); - + var applicableChangelog = plugin.IsTesting ? remoteManifest?.Changelog : remoteManifest?.TestingChangelog; var hasChangelog = !applicableChangelog.IsNullOrWhitespace(); var didDrawChangelogInsideCollapsible = false; @@ -2454,7 +2444,8 @@ internal class PluginInstallerWindow : Window, IDisposable var canFeedback = !isThirdParty && !plugin.IsDev && !plugin.IsOrphaned && - plugin.Manifest.DalamudApiLevel == PluginManager.DalamudApiLevel && + (plugin.Manifest.DalamudApiLevel == PluginManager.DalamudApiLevel + || plugin.Manifest.TestingDalamudApiLevel == PluginManager.DalamudApiLevel) && acceptsFeedback && availablePluginUpdate == default; @@ -2480,7 +2471,7 @@ internal class PluginInstallerWindow : Window, IDisposable if (this.hasDevPlugins) { ImGuiHelpers.ScaledDummy(3); - ImGui.TextColored(ImGuiColors.DalamudGrey, $"WorkingPluginId: {manifest.WorkingPluginId}"); + ImGui.TextColored(ImGuiColors.DalamudGrey, $"WorkingPluginId: {plugin.EffectiveWorkingPluginId}"); ImGuiHelpers.ScaledDummy(3); } @@ -2488,7 +2479,7 @@ internal class PluginInstallerWindow : Window, IDisposable if (plugin.IsLoaded) { var commands = commandManager.Commands - .Where(cInfo => + .Where(cInfo => cInfo.Value is { ShowInHelp: true } && cInfo.Value.LoaderAssemblyName == plugin.Manifest.InternalName) .ToArray(); @@ -2500,7 +2491,7 @@ internal class PluginInstallerWindow : Window, IDisposable { ImGuiHelpers.SafeTextWrapped($"{command.Key} → {command.Value.HelpMessage}"); } - + ImGuiHelpers.ScaledDummy(3); } } @@ -2663,10 +2654,10 @@ internal class PluginInstallerWindow : Window, IDisposable var applicableForProfiles = plugin.Manifest.SupportsProfiles /*&& !plugin.IsDev*/; var profilesThatWantThisPlugin = profileManager.Profiles - .Where(x => x.WantsPlugin(plugin.Manifest.WorkingPluginId) != null) + .Where(x => x.WantsPlugin(plugin.EffectiveWorkingPluginId) != null) .ToArray(); var isInSingleProfile = profilesThatWantThisPlugin.Length == 1; - var isDefaultPlugin = profileManager.IsInDefaultProfile(plugin.Manifest.WorkingPluginId); + var isDefaultPlugin = profileManager.IsInDefaultProfile(plugin.EffectiveWorkingPluginId); // Disable everything if the updater is running or another plugin is operating var disabled = this.updateStatus == OperationStatus.InProgress || this.installStatus == OperationStatus.InProgress; @@ -2701,17 +2692,17 @@ internal class PluginInstallerWindow : Window, IDisposable foreach (var profile in profileManager.Profiles.Where(x => !x.IsDefaultProfile)) { - var inProfile = profile.WantsPlugin(plugin.Manifest.WorkingPluginId) != null; + var inProfile = profile.WantsPlugin(plugin.EffectiveWorkingPluginId) != null; if (ImGui.Checkbox($"###profilePick{profile.Guid}{plugin.Manifest.InternalName}", ref inProfile)) { if (inProfile) { - Task.Run(() => profile.AddOrUpdateAsync(plugin.Manifest.WorkingPluginId, plugin.Manifest.InternalName, true)) + Task.Run(() => profile.AddOrUpdateAsync(plugin.EffectiveWorkingPluginId, plugin.Manifest.InternalName, true)) .ContinueWith(this.DisplayErrorContinuation, Locs.Profiles_CouldNotAdd); } else { - Task.Run(() => profile.RemoveAsync(plugin.Manifest.WorkingPluginId)) + Task.Run(() => profile.RemoveAsync(plugin.EffectiveWorkingPluginId)) .ContinueWith(this.DisplayErrorContinuation, Locs.Profiles_CouldNotRemove); } } @@ -2731,11 +2722,11 @@ internal class PluginInstallerWindow : Window, IDisposable if (ImGuiComponents.IconButton(FontAwesomeIcon.Times)) { // TODO: Work this out - Task.Run(() => profileManager.DefaultProfile.AddOrUpdateAsync(plugin.Manifest.WorkingPluginId, plugin.Manifest.InternalName, plugin.IsLoaded, false)) + Task.Run(() => profileManager.DefaultProfile.AddOrUpdateAsync(plugin.EffectiveWorkingPluginId, plugin.Manifest.InternalName, plugin.IsLoaded, false)) .GetAwaiter().GetResult(); foreach (var profile in profileManager.Profiles.Where(x => !x.IsDefaultProfile && x.Plugins.Any(y => y.InternalName == plugin.Manifest.InternalName))) { - Task.Run(() => profile.RemoveAsync(plugin.Manifest.WorkingPluginId, false)) + Task.Run(() => profile.RemoveAsync(plugin.EffectiveWorkingPluginId, false)) .GetAwaiter().GetResult(); } @@ -2760,7 +2751,7 @@ internal class PluginInstallerWindow : Window, IDisposable if (ImGui.IsItemHovered()) ImGui.SetTooltip(Locs.PluginButtonToolTip_UnloadFailed); } - else if (this.enableDisableStatus == OperationStatus.InProgress && this.enableDisableWorkingPluginId == plugin.Manifest.WorkingPluginId) + else if (this.enableDisableStatus == OperationStatus.InProgress && this.enableDisableWorkingPluginId == plugin.EffectiveWorkingPluginId) { ImGuiComponents.DisabledToggleButton(toggleId, this.loadingIndicatorKind == LoadingIndicatorKind.EnablingSingle); } @@ -2780,21 +2771,21 @@ internal class PluginInstallerWindow : Window, IDisposable var applicableProfile = profilesThatWantThisPlugin.First(); Log.Verbose("Switching {InternalName} in {Profile} to {State}", plugin.InternalName, applicableProfile, isLoadedAndUnloadable); - + try { // Reload the devPlugin manifest if it's a dev plugin // The plugin might rely on changed values in the manifest - if (plugin.IsDev) + if (plugin is LocalDevPlugin devPlugin) { - plugin.ReloadManifest(); + devPlugin.ReloadManifest(); } } catch (Exception ex) { Log.Error(ex, "Could not reload DevPlugin manifest"); } - + // NOTE: We don't use the profile manager to actually handle loading/unloading here, // because that might cause us to show an error if a plugin we don't actually care about // fails to load/unload. Instead, we just do it ourselves and then update the profile. @@ -2803,13 +2794,13 @@ internal class PluginInstallerWindow : Window, IDisposable { this.enableDisableStatus = OperationStatus.InProgress; this.loadingIndicatorKind = LoadingIndicatorKind.DisablingSingle; - this.enableDisableWorkingPluginId = plugin.Manifest.WorkingPluginId; + this.enableDisableWorkingPluginId = plugin.EffectiveWorkingPluginId; Task.Run(async () => { await plugin.UnloadAsync(); await applicableProfile.AddOrUpdateAsync( - plugin.Manifest.WorkingPluginId, plugin.Manifest.InternalName, false, false); + plugin.EffectiveWorkingPluginId, plugin.Manifest.InternalName, false, false); notifications.AddNotification(Locs.Notifications_PluginDisabled(plugin.Manifest.Name), Locs.Notifications_PluginDisabledTitle, NotificationType.Success); }).ContinueWith(t => @@ -2824,9 +2815,9 @@ internal class PluginInstallerWindow : Window, IDisposable { this.enableDisableStatus = OperationStatus.InProgress; this.loadingIndicatorKind = LoadingIndicatorKind.EnablingSingle; - this.enableDisableWorkingPluginId = plugin.Manifest.WorkingPluginId; + this.enableDisableWorkingPluginId = plugin.EffectiveWorkingPluginId; - await applicableProfile.AddOrUpdateAsync(plugin.Manifest.WorkingPluginId, plugin.Manifest.InternalName, true, false); + await applicableProfile.AddOrUpdateAsync(plugin.EffectiveWorkingPluginId, plugin.Manifest.InternalName, true, false); await plugin.LoadAsync(PluginLoadReason.Installer); notifications.AddNotification(Locs.Notifications_PluginEnabled(plugin.Manifest.Name), Locs.Notifications_PluginEnabledTitle, NotificationType.Success); @@ -2847,7 +2838,7 @@ internal class PluginInstallerWindow : Window, IDisposable if (shouldUpdate) { // We need to update the profile right here, because PM will not enable the plugin otherwise - await applicableProfile.AddOrUpdateAsync(plugin.Manifest.WorkingPluginId, plugin.Manifest.InternalName, true, false); + await applicableProfile.AddOrUpdateAsync(plugin.EffectiveWorkingPluginId, plugin.Manifest.InternalName, true, false); await this.UpdateSinglePlugin(availableUpdate); } else @@ -2873,7 +2864,7 @@ internal class PluginInstallerWindow : Window, IDisposable { // Only if the plugin isn't broken. this.DrawOpenPluginSettingsButton(plugin); - + ImGui.SameLine(); ImGuiHelpers.ScaledDummy(5, 0); } @@ -2922,7 +2913,7 @@ internal class PluginInstallerWindow : Window, IDisposable Locs.ErrorModal_SingleUpdateFail(update.UpdateManifest.Name, PluginUpdateStatus.LocalizeUpdateStatusKind(task.Result.Status))); return false; } - + return this.DisplayErrorContinuation(task, Locs.ErrorModal_SingleUpdateFail(update.UpdateManifest.Name, "Exception")); }); } @@ -2975,7 +2966,7 @@ internal class PluginInstallerWindow : Window, IDisposable ImGui.SameLine(); ImGuiHelpers.ScaledDummy(5, 0); } - + ImGui.SameLine(); if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Cog, Locs.PluginButton_OpenSettings)) { @@ -2998,10 +2989,10 @@ internal class PluginInstallerWindow : Window, IDisposable private void DrawSendFeedbackButton(IPluginManifest manifest, bool isTesting, bool big) { - var clicked = big ? + var clicked = big ? ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Comment, Locs.FeedbackModal_Title) : ImGuiComponents.IconButton(FontAwesomeIcon.Comment); - + if (clicked) { this.feedbackPlugin = manifest; @@ -3040,7 +3031,7 @@ internal class PluginInstallerWindow : Window, IDisposable var validationIssuesText = shouldBother ? $"Found {problems.Count} validation issue{(problems.Count > 1 ? "s" : string.Empty)} in this plugin!" : $"{problems.Count} dismissed validation issue{(problems.Count > 1 ? "s" : string.Empty)} in this plugin."; - + using var col = ImRaii.PushColor(ImGuiCol.Text, shouldBother ? ImGuiColors.DalamudOrange : ImGuiColors.DalamudGrey); using var tree = ImRaii.TreeNode($"{validationIssuesText}###validationIssueCollapsible"); if (tree.Success) @@ -3060,7 +3051,7 @@ internal class PluginInstallerWindow : Window, IDisposable devPlugin.DismissedValidationProblems.Add(problem.GetType().Name); Service.Get().QueueSave(); } - + if (ImGui.IsItemHovered()) { ImGui.SetTooltip("Dismiss this issue"); @@ -3096,7 +3087,7 @@ internal class PluginInstallerWindow : Window, IDisposable throw new ArgumentOutOfRangeException(); } } - + ImGui.SameLine(); using (ImRaii.PushColor(ImGuiCol.Text, thisProblemIsDismissed ? ImGuiColors.DalamudGrey : ImGuiColors.DalamudWhite)) @@ -3118,7 +3109,7 @@ internal class PluginInstallerWindow : Window, IDisposable if (localPlugin is LocalDevPlugin plugin) { var isInDefaultProfile = - Service.Get().IsInDefaultProfile(localPlugin.Manifest.WorkingPluginId); + Service.Get().IsInDefaultProfile(localPlugin.EffectiveWorkingPluginId); // https://colorswall.com/palette/2868/ var greenColor = new Vector4(0x5C, 0xB8, 0x5C, 0xFF) / 0xFF; @@ -3247,7 +3238,7 @@ internal class PluginInstallerWindow : Window, IDisposable if (!string.IsNullOrEmpty(repoUrl) && repoUrl.StartsWith("https://")) { ImGui.SameLine(); - + var clicked = big ? ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Globe, "Open website") : ImGuiComponents.IconButton(FontAwesomeIcon.Globe); @@ -3356,7 +3347,9 @@ internal class PluginInstallerWindow : Window, IDisposable var searchString = this.searchText.ToLowerInvariant(); var matcher = new FuzzyMatcher(searchString, MatchMode.FuzzyParts); var hasSearchString = !string.IsNullOrWhiteSpace(this.searchText); - var oldApi = manifest.DalamudApiLevel < PluginManager.DalamudApiLevel; + var oldApi = (manifest.TestingDalamudApiLevel == null + || manifest.TestingDalamudApiLevel < PluginManager.DalamudApiLevel) + && manifest.DalamudApiLevel < PluginManager.DalamudApiLevel; var installed = this.IsManifestInstalled(manifest).IsInstalled; if (oldApi && !hasSearchString && !installed) @@ -3432,7 +3425,7 @@ internal class PluginInstallerWindow : Window, IDisposable // not the actual time of the last update, as the plugin may be pending an update IPluginManifest? p2Considered = this.pluginListAvailable.FirstOrDefault(x => x.InternalName == p2.InternalName); p2Considered ??= p2.Manifest; - + IPluginManifest? p1Considered = this.pluginListAvailable.FirstOrDefault(x => x.InternalName == p1.InternalName); p1Considered ??= p1.Manifest; @@ -3464,9 +3457,9 @@ internal class PluginInstallerWindow : Window, IDisposable break; case PluginSortKind.ProfileOrNot: this.pluginListAvailable.Sort((p1, p2) => p1.Name.CompareTo(p2.Name)); - + var profman = Service.Get(); - this.pluginListInstalled.Sort((p1, p2) => profman.IsInDefaultProfile(p1.Manifest.WorkingPluginId).CompareTo(profman.IsInDefaultProfile(p2.Manifest.WorkingPluginId))); + this.pluginListInstalled.Sort((p1, p2) => profman.IsInDefaultProfile(p1.EffectiveWorkingPluginId).CompareTo(profman.IsInDefaultProfile(p2.EffectiveWorkingPluginId))); break; default: throw new InvalidEnumArgumentException("Unknown plugin sort type."); @@ -3498,14 +3491,14 @@ internal class PluginInstallerWindow : Window, IDisposable if (string.IsNullOrEmpty(this.searchText)) { this.categoryManager.SetCategoryHighlightsForPlugins(null); - + // Reset here for good measure, as we're returning from a search this.openPluginCollapsibles.Clear(); } else { var pluginsMatchingSearch = this.pluginListAvailable.Where(rm => !this.IsManifestFiltered(rm)).ToArray(); - + // Check if the search results are different, and clear the open collapsibles if they are if (previousSearchText != null) { @@ -3513,7 +3506,7 @@ internal class PluginInstallerWindow : Window, IDisposable if (!previousSearchResults.SequenceEqual(pluginsMatchingSearch)) this.openPluginCollapsibles.Clear(); } - + this.categoryManager.SetCategoryHighlightsForPlugins(pluginsMatchingSearch); } } @@ -3536,38 +3529,38 @@ internal class PluginInstallerWindow : Window, IDisposable foreach (var y in Enumerable.Range(-1, 3)) { if (x is 0 && y is 0) continue; - + ImGui.SetCursorPos(cursorStart + new Vector2(x, y)); ImGui.Text(icon.ToIconString()); } } - + ImGui.PopStyleColor(); - + ImGui.PushStyleColor(ImGuiCol.Text, iconColor); ImGui.SetCursorPos(cursorStart); ImGui.Text(icon.ToIconString()); ImGui.PopStyleColor(); - + ImGui.PopFont(); - + ImGui.SetCursorPos(ImGui.GetCursorPos() - positionOffset); } - + // Animates a tooltip when hovering over the ImGui Item before this call. private void VerifiedCheckmarkFadeTooltip(string source, string tooltip) { const float fadeInStartDelay = 250.0f; - + var isHoveringSameItem = this.verifiedCheckmarkHoveredPlugin == source; - + // If we just started a hover, start the timer if (ImGui.IsItemHovered() && !this.tooltipFadeInStopwatch.IsRunning) { this.verifiedCheckmarkHoveredPlugin = source; this.tooltipFadeInStopwatch.Restart(); } - + // If we were last hovering this plugins item and are no longer hovered over that item, reset the timer if (!ImGui.IsItemHovered() && isHoveringSameItem) { @@ -3575,13 +3568,13 @@ internal class PluginInstallerWindow : Window, IDisposable this.tooltipFadeInStopwatch.Stop(); this.tooltipFadeEasing.Reset(); } - + // If we have been hovering this item for > fadeInStartDelay milliseconds, fade in tooltip over fadeInTime milliseconds if (ImGui.IsItemHovered() && isHoveringSameItem && this.tooltipFadeInStopwatch.ElapsedMilliseconds >= fadeInStartDelay) { if (!this.tooltipFadeEasing.IsRunning) this.tooltipFadeEasing.Start(); - + this.tooltipFadeEasing.Update(); var fadePercent = this.tooltipFadeEasing.EasedPoint.X; ImGui.PushStyleColor(ImGuiCol.Text, ImGui.GetStyle().Colors[(int)ImGuiCol.Text] with { W = fadePercent }); @@ -3726,9 +3719,9 @@ internal class PluginInstallerWindow : Window, IDisposable public static string PluginBody_Plugin3rdPartyRepo(string url) => Loc.Localize("InstallerPlugin3rdPartyRepo", "From custom plugin repository {0}").Format(url); public static string PluginBody_Outdated => Loc.Localize("InstallerOutdatedPluginBody ", "This plugin is outdated and incompatible."); - + public static string PluginBody_Outdated_WaitForUpdate => Loc.Localize("InstallerOutdatedWaitForUpdate", "Please wait for it to be updated by its author."); - + public static string PluginBody_Outdated_CanNowUpdate => Loc.Localize("InstallerOutdatedCanNowUpdate", "An update is available for installation."); public static string PluginBody_Orphaned => Loc.Localize("InstallerOrphanedPluginBody ", "This plugin's source repository is no longer available. You may need to reinstall it from its repository, or re-add the repository."); @@ -3761,15 +3754,15 @@ internal class PluginInstallerWindow : Window, IDisposable public static string PluginButton_Unload => Loc.Localize("InstallerUnload", "Unload"); public static string PluginButton_SafeMode => Loc.Localize("InstallerSafeModeButton", "Can't change in safe mode"); - + public static string PluginButton_OpenUi => Loc.Localize("InstallerOpenPluginUi", "Open"); - + public static string PluginButton_OpenSettings => Loc.Localize("InstallerOpenPluginSettings", "Settings"); #endregion #region Plugin button tooltips - + public static string PluginButtonToolTip_OpenUi => Loc.Localize("InstallerTooltipOpenUi", "Open this plugin's interface"); public static string PluginButtonToolTip_OpenConfiguration => Loc.Localize("InstallerTooltipOpenConfig", "Open this plugin's settings"); @@ -3799,9 +3792,9 @@ internal class PluginInstallerWindow : Window, IDisposable public static string PluginButtonToolTip_UnloadFailed => Loc.Localize("InstallerLoadUnloadFailedTooltip", "Plugin load/unload failed, please restart your game and try again."); public static string PluginButtonToolTip_NeedsToBeInDefault => Loc.Localize("InstallerUnloadNeedsToBeInDefault", "This plugin is in one or more collections. If you want to enable or disable it, please do so by enabling or disabling the collections it is in.\nIf you want to manage it manually, remove it from all collections."); - + public static string PluginButtonToolTip_NeedsToBeInSingleProfile => Loc.Localize("InstallerUnloadNeedsToBeInSingleProfile", "This plugin is in more than one collection. If you want to enable or disable it, please do so by enabling or disabling the collections it is in.\nIf you want to manage it here, make sure it is only in a single collection."); - + public static string PluginButtonToolTip_SingleProfileDisabled(string name) => Loc.Localize("InstallerSingleProfileDisabled", "The collection '{0}' which contains this plugin is disabled.\nPlease enable it in the collections manager to toggle the plugin individually.").Format(name); #endregion @@ -3959,7 +3952,7 @@ internal class PluginInstallerWindow : Window, IDisposable public static string DeletePluginConfirmWarningModal_No => Loc.Localize("InstallerDeletePluginConfigWarningNo", "No"); #endregion - + #region Plugin Update chatbox public static string PluginUpdateHeader_Chatbox => Loc.Localize("DalamudPluginUpdates", "Updates:"); @@ -3992,7 +3985,7 @@ internal class PluginInstallerWindow : Window, IDisposable Loc.Localize("InstallerProfilesRemoveFromAll", "Remove from all collections"); #endregion - + #region VerifiedCheckmark public static string VerifiedCheckmark_VerifiedTooltip => diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/ProfileManagerWidget.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/ProfileManagerWidget.cs index 81df0cd03..a5081bdb7 100644 --- a/Dalamud/Interface/Internal/Windows/PluginInstaller/ProfileManagerWidget.cs +++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/ProfileManagerWidget.cs @@ -1,5 +1,4 @@ -using System; -using System.Linq; +using System.Linq; using System.Numerics; using System.Threading.Tasks; @@ -325,7 +324,7 @@ internal class ProfileManagerWidget if (ImGui.Selectable($"{plugin.Manifest.Name}{(plugin is LocalDevPlugin ? "(dev plugin)" : string.Empty)}###selector{plugin.Manifest.InternalName}")) { - Task.Run(() => profile.AddOrUpdateAsync(plugin.Manifest.WorkingPluginId, plugin.Manifest.InternalName, true, false)) + Task.Run(() => profile.AddOrUpdateAsync(plugin.EffectiveWorkingPluginId, plugin.Manifest.InternalName, true, false)) .ContinueWith(this.installer.DisplayErrorContinuation, Locs.ErrorCouldNotChangeState); } } @@ -431,7 +430,7 @@ internal class ProfileManagerWidget foreach (var profileEntry in profile.Plugins.ToArray()) { didAny = true; - var pmPlugin = pm.InstalledPlugins.FirstOrDefault(x => x.Manifest.WorkingPluginId == profileEntry.WorkingPluginId); + var pmPlugin = pm.InstalledPlugins.FirstOrDefault(x => x.EffectiveWorkingPluginId == profileEntry.WorkingPluginId); var btnOffset = 2; if (pmPlugin != null) @@ -486,7 +485,7 @@ internal class ProfileManagerWidget FontAwesomeIcon.Check, "Yes, use this one")) { - profileEntry.WorkingPluginId = firstAvailableInstalled.Manifest.WorkingPluginId; + profileEntry.WorkingPluginId = firstAvailableInstalled.EffectiveWorkingPluginId; Task.Run(async () => { await profman.ApplyAllWantStatesAsync(); diff --git a/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs b/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs index b3b5dfc8f..0df456dfb 100644 --- a/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs +++ b/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using System.Numerics; diff --git a/Dalamud/Interface/Internal/Windows/ProfilerWindow.cs b/Dalamud/Interface/Internal/Windows/ProfilerWindow.cs index 93b75976a..28dcdb117 100644 --- a/Dalamud/Interface/Internal/Windows/ProfilerWindow.cs +++ b/Dalamud/Interface/Internal/Windows/ProfilerWindow.cs @@ -190,6 +190,9 @@ public class ProfilerWindow : Window uint eventTextDepth = maxRectDept + 2; + var eventsXPos = new List(); + const float eventsXPosFudge = 5f; + foreach (var timingEvent in Timings.Events) { var startX = (timingEvent.StartTime - this.min) / (this.max - this.min) * width; @@ -214,11 +217,19 @@ public class ProfilerWindow : Window { textPos.X = pos.X + (uint)startX - textSize.X - padding; } + + var numClashes = eventsXPos.Count(x => Math.Abs(x - textPos.X) < textSize.X + eventsXPosFudge); + if (numClashes > 0) + { + textPos.Y -= numClashes * textSize.Y; + } ImGui.GetWindowDrawList().AddText( textPos, ImGui.GetColorU32(ImGuiColors.DalamudWhite), timingEvent.Name); + + eventsXPos.Add(textPos.X); } } diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/AddonLifecycleAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/AddonLifecycleAgingStep.cs index b2229e4e4..28edab88a 100644 --- a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/AddonLifecycleAgingStep.cs +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/AddonLifecycleAgingStep.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using Dalamud.Game.Addon; using Dalamud.Game.Addon.Lifecycle; using Dalamud.Game.Addon.Lifecycle.AddonArgTypes; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps; diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ChatAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ChatAgingStep.cs index c7b6213d4..2fdd8c060 100644 --- a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ChatAgingStep.cs +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ChatAgingStep.cs @@ -1,6 +1,7 @@ using Dalamud.Game.Gui; using Dalamud.Game.Text; using Dalamud.Game.Text.SeStringHandling; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps; @@ -62,7 +63,7 @@ internal class ChatAgingStep : IAgingStep } private void ChatOnOnChatMessage( - XivChatType type, uint senderid, ref SeString sender, ref SeString message, ref bool ishandled) + XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool ishandled) { if (type == XivChatType.Echo && message.TextValue == "DALAMUD") { diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ConditionAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ConditionAgingStep.cs index fee692ab8..8ce2111c9 100644 --- a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ConditionAgingStep.cs +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ConditionAgingStep.cs @@ -1,4 +1,5 @@ using Dalamud.Game.ClientState.Conditions; + using ImGuiNET; using Serilog; diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/DutyStateAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/DutyStateAgingStep.cs index 2a92d7bd3..19e218ecb 100644 --- a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/DutyStateAgingStep.cs +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/DutyStateAgingStep.cs @@ -1,4 +1,5 @@ using Dalamud.Game.DutyState; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps; diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/EnterTerritoryAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/EnterTerritoryAgingStep.cs index 4f5c758d6..a61af7f94 100644 --- a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/EnterTerritoryAgingStep.cs +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/EnterTerritoryAgingStep.cs @@ -1,4 +1,5 @@ using Dalamud.Game.ClientState; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps; diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/GameConfigAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/GameConfigAgingStep.cs index 7c3145bbc..97c163590 100644 --- a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/GameConfigAgingStep.cs +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/GameConfigAgingStep.cs @@ -1,4 +1,5 @@ using Dalamud.Game.Config; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps; diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/GamepadStateAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/GamepadStateAgingStep.cs index 55e836dfb..ccee570c7 100644 --- a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/GamepadStateAgingStep.cs +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/GamepadStateAgingStep.cs @@ -1,4 +1,5 @@ using Dalamud.Game.ClientState.GamePad; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps; diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/HandledExceptionAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/HandledExceptionAgingStep.cs index 43798968e..5d2173ad5 100644 --- a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/HandledExceptionAgingStep.cs +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/HandledExceptionAgingStep.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.InteropServices; namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps; diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/HoverAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/HoverAgingStep.cs index b4b069487..8f509b8e7 100644 --- a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/HoverAgingStep.cs +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/HoverAgingStep.cs @@ -1,4 +1,5 @@ using Dalamud.Game.Gui; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps; diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ItemPayloadAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ItemPayloadAgingStep.cs index 3c7282188..1ccb5934f 100644 --- a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ItemPayloadAgingStep.cs +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ItemPayloadAgingStep.cs @@ -1,8 +1,7 @@ -using System; - -using Dalamud.Game.Gui; +using Dalamud.Game.Gui; using Dalamud.Game.Text.SeStringHandling; using Dalamud.Game.Text.SeStringHandling.Payloads; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps; diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/KeyStateAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/KeyStateAgingStep.cs index c1ae9289a..522943e87 100644 --- a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/KeyStateAgingStep.cs +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/KeyStateAgingStep.cs @@ -1,4 +1,5 @@ using Dalamud.Game.ClientState.Keys; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps; diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/LoginEventAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/LoginEventAgingStep.cs index 23b0b903a..d755e95ef 100644 --- a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/LoginEventAgingStep.cs +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/LoginEventAgingStep.cs @@ -1,6 +1,5 @@ -using System; - using Dalamud.Game.ClientState; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps; diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/LogoutEventAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/LogoutEventAgingStep.cs index c4c6ebfce..1869dd108 100644 --- a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/LogoutEventAgingStep.cs +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/LogoutEventAgingStep.cs @@ -1,6 +1,5 @@ -using System; - using Dalamud.Game.ClientState; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps; diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/PartyFinderAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/PartyFinderAgingStep.cs index eea015ad8..f4236c4b6 100644 --- a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/PartyFinderAgingStep.cs +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/PartyFinderAgingStep.cs @@ -1,5 +1,6 @@ using Dalamud.Game.Gui.PartyFinder; using Dalamud.Game.Gui.PartyFinder.Types; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps; diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/TargetAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/TargetAgingStep.cs index 0a1b4d91d..f8767ad53 100644 --- a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/TargetAgingStep.cs +++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/TargetAgingStep.cs @@ -1,6 +1,7 @@ using Dalamud.Game.ClientState.Objects; using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Game.ClientState.Objects.Types; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps; diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/SelfTestWindow.cs b/Dalamud/Interface/Internal/Windows/SelfTest/SelfTestWindow.cs index 8e43d30a6..8f4a59843 100644 --- a/Dalamud/Interface/Internal/Windows/SelfTest/SelfTestWindow.cs +++ b/Dalamud/Interface/Internal/Windows/SelfTest/SelfTestWindow.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using System.Numerics; diff --git a/Dalamud/Interface/Internal/Windows/Settings/SettingsEntry.cs b/Dalamud/Interface/Internal/Windows/Settings/SettingsEntry.cs index 1e57d716e..a72cae024 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/SettingsEntry.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/SettingsEntry.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Interface.Internal.Windows.Settings; +namespace Dalamud.Interface.Internal.Windows.Settings; /// /// Basic, drawable settings entry. diff --git a/Dalamud/Interface/Internal/Windows/Settings/SettingsWindow.cs b/Dalamud/Interface/Internal/Windows/Settings/SettingsWindow.cs index 4c67afce4..fd4949533 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/SettingsWindow.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/SettingsWindow.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Numerics; using CheapLoc; + using Dalamud.Configuration.Internal; using Dalamud.Interface.Colors; using Dalamud.Interface.Internal.Windows.Settings.Tabs; @@ -10,6 +11,7 @@ using Dalamud.Interface.Utility; using Dalamud.Interface.Utility.Raii; using Dalamud.Interface.Windowing; using Dalamud.Utility; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.Settings; @@ -22,6 +24,9 @@ internal class SettingsWindow : Window private SettingsTab[]? tabs; private string searchInput = string.Empty; + private bool isSearchInputPrefilled = false; + + private SettingsTab setActiveTab = null!; /// /// Initializes a new instance of the class. @@ -39,6 +44,34 @@ internal class SettingsWindow : Window this.SizeCondition = ImGuiCond.FirstUseEver; } + /// + /// Open the settings window to the tab specified by . + /// + /// The tab of the settings window to open. + public void OpenTo(SettingsOpenKind kind) + { + this.IsOpen = true; + this.SetOpenTab(kind); + } + + /// + /// Sets the current search text and marks it as prefilled. + /// + /// The search term. + public void SetSearchText(string text) + { + if (string.IsNullOrEmpty(text)) + { + this.isSearchInputPrefilled = false; + this.searchInput = string.Empty; + } + else + { + this.isSearchInputPrefilled = true; + this.searchInput = text; + } + } + /// public override void OnOpen() { @@ -56,7 +89,7 @@ internal class SettingsWindow : Window settingsTab.Load(); } - this.searchInput = string.Empty; + if (!this.isSearchInputPrefilled) this.searchInput = string.Empty; base.OnOpen(); } @@ -84,6 +117,12 @@ internal class SettingsWindow : Window settingsTab.IsOpen = false; } + + if (this.isSearchInputPrefilled) + { + this.isSearchInputPrefilled = false; + this.searchInput = string.Empty; + } } /// @@ -97,7 +136,15 @@ internal class SettingsWindow : Window { foreach (var settingsTab in this.tabs.Where(x => x.IsVisible)) { - if (ImGui.BeginTabItem(settingsTab.Title)) + var flags = ImGuiTabItemFlags.NoCloseWithMiddleMouseButton; + if (this.setActiveTab == settingsTab) + { + flags |= ImGuiTabItemFlags.SetSelected; + this.setActiveTab = null; + } + + using var tab = ImRaii.TabItem(settingsTab.Title, flags); + if (tab) { if (!settingsTab.IsOpen) { @@ -105,13 +152,12 @@ internal class SettingsWindow : Window settingsTab.OnOpen(); } - if (ImGui.BeginChild($"###settings_scrolling_{settingsTab.Title}", new Vector2(-1, -1), false)) - { + using var tabChild = ImRaii.Child( + $"###settings_scrolling_{settingsTab.Title}", + new Vector2(-1, -1), + false); + if (tabChild) settingsTab.Draw(); - } - - ImGui.EndChild(); - ImGui.EndTabItem(); } else if (settingsTab.IsOpen) { @@ -161,33 +207,34 @@ internal class SettingsWindow : Window ImGui.SetCursorPos(windowSize - ImGuiHelpers.ScaledVector2(70)); - if (ImGui.BeginChild("###settingsFinishButton")) + using (var buttonChild = ImRaii.Child("###settingsFinishButton")) { - using var disabled = ImRaii.Disabled(this.tabs.Any(x => x.Entries.Any(y => !y.IsValid))); - - using (ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, 100f)) + if (buttonChild) { - using var font = ImRaii.PushFont(InterfaceManager.IconFont); + using var disabled = ImRaii.Disabled(this.tabs.Any(x => x.Entries.Any(y => !y.IsValid))); - if (ImGui.Button(FontAwesomeIcon.Save.ToIconString(), new Vector2(40))) + using (ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, 100f)) { - this.Save(); + using var font = ImRaii.PushFont(InterfaceManager.IconFont); - if (!ImGui.IsKeyDown(ImGuiKey.ModShift)) - this.IsOpen = false; + if (ImGui.Button(FontAwesomeIcon.Save.ToIconString(), new Vector2(40))) + { + this.Save(); + + if (!ImGui.IsKeyDown(ImGuiKey.ModShift)) + this.IsOpen = false; + } + } + + if (ImGui.IsItemHovered()) + { + ImGui.SetTooltip(!ImGui.IsKeyDown(ImGuiKey.ModShift) + ? Loc.Localize("DalamudSettingsSaveAndExit", "Save changes and close") + : Loc.Localize("DalamudSettingsSave", "Save changes")); } } - - if (ImGui.IsItemHovered()) - { - ImGui.SetTooltip(!ImGui.IsKeyDown(ImGuiKey.ModShift) - ? Loc.Localize("DalamudSettingsSaveAndExit", "Save changes and close") - : Loc.Localize("DalamudSettingsSave", "Save changes")); - } } - ImGui.EndChild(); - ImGui.SetCursorPos(new Vector2(windowSize.X - 250, ImGui.GetTextLineHeightWithSpacing() + (ImGui.GetStyle().FramePadding.Y * 2))); ImGui.SetNextItemWidth(240); ImGui.InputTextWithHint("###searchInput", "Search for settings...", ref this.searchInput, 100); @@ -231,4 +278,28 @@ internal class SettingsWindow : Window Service.Get().RebuildFonts(); } + + private void SetOpenTab(SettingsOpenKind kind) + { + switch (kind) + { + case SettingsOpenKind.General: + this.setActiveTab = this.tabs[0]; + break; + case SettingsOpenKind.LookAndFeel: + this.setActiveTab = this.tabs[1]; + break; + case SettingsOpenKind.ServerInfoBar: + this.setActiveTab = this.tabs[2]; + break; + case SettingsOpenKind.Experimental: + this.setActiveTab = this.tabs[3]; + break; + case SettingsOpenKind.About: + this.setActiveTab = this.tabs[4]; + break; + default: + throw new ArgumentOutOfRangeException(nameof(kind), kind, null); + } + } } diff --git a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabAbout.cs b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabAbout.cs index 8714fd666..d38f9219d 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabAbout.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabAbout.cs @@ -234,7 +234,9 @@ Contribute at: https://github.com/goatcorp/Dalamud { var windowSize = ImGui.GetWindowSize(); - ImGui.BeginChild("scrolling", Vector2.Zero, false, ImGuiWindowFlags.NoScrollbar); + using var child = ImRaii.Child("scrolling", new Vector2(-1, -10 * ImGuiHelpers.GlobalScale), false, ImGuiWindowFlags.NoScrollbar); + if (!child) + return; if (this.resetNow) { @@ -295,8 +297,6 @@ Contribute at: https://github.com/goatcorp/Dalamud } } - ImGui.EndChild(); - base.Draw(); } diff --git a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabDtr.cs b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabDtr.cs index 7dd0fa5d1..2559911cf 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabDtr.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabDtr.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; @@ -9,6 +8,7 @@ using Dalamud.Game.Gui.Dtr; using Dalamud.Interface.Colors; using Dalamud.Interface.Components; using Dalamud.Interface.Utility; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.Settings.Tabs; diff --git a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabExperimental.cs b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabExperimental.cs index c706a42c1..2707f67df 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabExperimental.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabExperimental.cs @@ -1,5 +1,4 @@ -using System; -using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.CodeAnalysis; using CheapLoc; using Dalamud.Configuration.Internal; diff --git a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabLook.cs b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabLook.cs index 1c446f26b..a582761ba 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabLook.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabLook.cs @@ -6,6 +6,7 @@ using System.Text; using CheapLoc; using Dalamud.Configuration.Internal; using Dalamud.Game; +using Dalamud.Game.Text; using Dalamud.Interface.Colors; using Dalamud.Interface.FontIdentifier; using Dalamud.Interface.GameFonts; @@ -128,14 +129,35 @@ public class SettingsTabLook : SettingsTab new SettingsEntry( Loc.Localize("DalamudSettingInstallerOpenDefault", "Open the Plugin Installer to the \"Installed Plugins\" tab by default"), Loc.Localize("DalamudSettingInstallerOpenDefaultHint", "This will allow you to open the Plugin Installer to the \"Installed Plugins\" tab by default, instead of the \"Available Plugins\" tab."), - c => c.PluginInstallerOpen == PluginInstallerWindow.PluginInstallerOpenKind.InstalledPlugins, - (v, c) => c.PluginInstallerOpen = v ? PluginInstallerWindow.PluginInstallerOpenKind.InstalledPlugins : PluginInstallerWindow.PluginInstallerOpenKind.AllPlugins), + c => c.PluginInstallerOpen == PluginInstallerOpenKind.InstalledPlugins, + (v, c) => c.PluginInstallerOpen = v ? PluginInstallerOpenKind.InstalledPlugins : PluginInstallerOpenKind.AllPlugins), new SettingsEntry( Loc.Localize("DalamudSettingReducedMotion", "Reduce motions"), Loc.Localize("DalamudSettingReducedMotionHint", "This will suppress certain animations from Dalamud, such as the notification popup."), c => c.ReduceMotions ?? false, (v, c) => c.ReduceMotions = v), + + new SettingsEntry( + Loc.Localize("DalamudSettingImeStateIndicatorOpacity", "IME State Indicator Opacity (CJK only)"), + Loc.Localize("DalamudSettingImeStateIndicatorOpacityHint", "When any of CJK IMEs is in use, the state of IME will be shown with the opacity specified here."), + c => c.ImeStateIndicatorOpacity, + (v, c) => c.ImeStateIndicatorOpacity = v) + { + CustomDraw = static e => + { + ImGuiHelpers.SafeTextWrapped(e.Name!); + + var v = e.Value * 100f; + if (ImGui.SliderFloat($"###{e}", ref v, 0f, 100f, "%.1f%%")) + e.Value = v / 100f; + ImGui.SameLine(); + + ImGui.PushStyleVar(ImGuiStyleVar.Alpha, v / 100); + ImGui.TextUnformatted("\uE020\uE021\uE022\uE023\uE024\uE025\uE026\uE027"); + ImGui.PopStyleVar(1); + }, + }, }; public override string Title => Loc.Localize("DalamudSettingsVisual", "Look & Feel"); diff --git a/Dalamud/Interface/Internal/Windows/Settings/Widgets/ButtonSettingsEntry.cs b/Dalamud/Interface/Internal/Windows/Settings/Widgets/ButtonSettingsEntry.cs index 6adddbc82..6bce2a451 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/Widgets/ButtonSettingsEntry.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/Widgets/ButtonSettingsEntry.cs @@ -1,5 +1,4 @@ -using System; -using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.CodeAnalysis; using Dalamud.Interface.Colors; using Dalamud.Interface.Utility; diff --git a/Dalamud/Interface/Internal/Windows/Settings/Widgets/DevPluginsSettingsEntry.cs b/Dalamud/Interface/Internal/Windows/Settings/Widgets/DevPluginsSettingsEntry.cs index 55deb61bc..cfb1ff39f 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/Widgets/DevPluginsSettingsEntry.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/Widgets/DevPluginsSettingsEntry.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; @@ -14,6 +13,7 @@ using Dalamud.Interface.Components; using Dalamud.Interface.Utility; using Dalamud.Interface.Utility.Raii; using Dalamud.Plugin.Internal; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.Settings.Widgets; diff --git a/Dalamud/Interface/Internal/Windows/Settings/Widgets/LanguageChooserSettingsEntry.cs b/Dalamud/Interface/Internal/Windows/Settings/Widgets/LanguageChooserSettingsEntry.cs index 2dd7cc6d0..cb79000d2 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/Widgets/LanguageChooserSettingsEntry.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/Widgets/LanguageChooserSettingsEntry.cs @@ -1,13 +1,12 @@ -using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Globalization; using System.Linq; using CheapLoc; using Dalamud.Configuration.Internal; using Dalamud.Interface.Colors; using Dalamud.Interface.Utility; + using ImGuiNET; namespace Dalamud.Interface.Internal.Windows.Settings.Widgets; diff --git a/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs b/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs index dcbb42089..2ac4187cf 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs @@ -1,8 +1,8 @@ -using System; -using System.Diagnostics; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; +using System.Numerics; using Dalamud.Configuration.Internal; @@ -51,10 +51,22 @@ internal sealed class SettingsEntry : SettingsEntry public delegate void SaveSettingDelegate(T? value, DalamudConfiguration config); - public T? Value => this.valueBacking == default ? default : (T)this.valueBacking; + public T? Value + { + get => this.valueBacking == default ? default : (T)this.valueBacking; + set + { + if (Equals(value, this.valueBacking)) + return; + this.valueBacking = value; + this.change?.Invoke(value); + } + } public string Description { get; } + public Action>? CustomDraw { get; init; } + public Func? CheckValidity { get; init; } public Func? CheckWarning { get; init; } @@ -69,7 +81,11 @@ internal sealed class SettingsEntry : SettingsEntry var type = typeof(T); - if (type == typeof(DirectoryInfo)) + if (this.CustomDraw is not null) + { + this.CustomDraw.Invoke(this); + } + else if (type == typeof(DirectoryInfo)) { ImGuiHelpers.SafeTextWrapped(this.Name); diff --git a/Dalamud/Interface/Internal/Windows/StyleEditor/StyleEditorWindow.cs b/Dalamud/Interface/Internal/Windows/StyleEditor/StyleEditorWindow.cs index fb556ba45..ceb009139 100644 --- a/Dalamud/Interface/Internal/Windows/StyleEditor/StyleEditorWindow.cs +++ b/Dalamud/Interface/Internal/Windows/StyleEditor/StyleEditorWindow.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using System.Numerics; @@ -6,7 +5,6 @@ using System.Reflection; using CheapLoc; using Dalamud.Configuration.Internal; -using Dalamud.Data; using Dalamud.Interface.Colors; using Dalamud.Interface.Components; using Dalamud.Interface.Style; @@ -14,7 +12,7 @@ using Dalamud.Interface.Utility; using Dalamud.Interface.Windowing; using Dalamud.Utility; using ImGuiNET; -using Lumina.Excel.GeneratedSheets; + using Serilog; namespace Dalamud.Interface.Internal.Windows.StyleEditor; diff --git a/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs b/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs index 9c385a99c..0600ec001 100644 --- a/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs +++ b/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs @@ -142,6 +142,12 @@ internal class TitleScreenMenuWindow : Window, IDisposable var scale = ImGui.GetIO().FontGlobalScale; var entries = this.titleScreenMenu.Entries; + var hovered = ImGui.IsWindowHovered( + ImGuiHoveredFlags.RootAndChildWindows | + ImGuiHoveredFlags.AllowWhenBlockedByActiveItem); + + Service.Get().OverrideGameCursor = !hovered; + switch (this.state) { case State.Show: @@ -187,8 +193,11 @@ internal class TitleScreenMenuWindow : Window, IDisposable i++; } - if (!ImGui.IsWindowHovered(ImGuiHoveredFlags.RootAndChildWindows | - ImGuiHoveredFlags.AllowWhenBlockedByActiveItem)) + // Don't check for hover if we're in the middle of an animation, as it will cause flickering. + if (this.moveEasings.Any(x => !x.Value.IsDone)) + break; + + if (!hovered) { this.state = State.FadeOut; } diff --git a/Dalamud/Interface/Style/StyleModel.cs b/Dalamud/Interface/Style/StyleModel.cs index 172c105b0..643fe463d 100644 --- a/Dalamud/Interface/Style/StyleModel.cs +++ b/Dalamud/Interface/Style/StyleModel.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Numerics; diff --git a/Dalamud/Interface/Style/StyleModelV1.cs b/Dalamud/Interface/Style/StyleModelV1.cs index ee6bb06a4..43341126e 100644 --- a/Dalamud/Interface/Style/StyleModelV1.cs +++ b/Dalamud/Interface/Style/StyleModelV1.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Numerics; diff --git a/Dalamud/Interface/Utility/ImGuiHelpers.cs b/Dalamud/Interface/Utility/ImGuiHelpers.cs index 639b0315d..885f73067 100644 --- a/Dalamud/Interface/Utility/ImGuiHelpers.cs +++ b/Dalamud/Interface/Utility/ImGuiHelpers.cs @@ -12,6 +12,7 @@ using Dalamud.Game.ClientState.Keys; using Dalamud.Interface.ManagedFontAtlas; using Dalamud.Interface.ManagedFontAtlas.Internals; using Dalamud.Interface.Utility.Raii; + using ImGuiNET; using ImGuiScene; diff --git a/Dalamud/Interface/Utility/Raii/EndObjects.cs b/Dalamud/Interface/Utility/Raii/EndObjects.cs index 3f2a016b3..401af5415 100644 --- a/Dalamud/Interface/Utility/Raii/EndObjects.cs +++ b/Dalamud/Interface/Utility/Raii/EndObjects.cs @@ -1,4 +1,5 @@ using System.Numerics; +using System.Text; using ImGuiNET; @@ -36,7 +37,7 @@ public static partial class ImRaii public static IEndObject Popup(string id, ImGuiWindowFlags flags) => new EndConditionally(ImGui.EndPopup, ImGui.BeginPopup(id, flags)); - + public static IEndObject PopupModal(string id) => new EndConditionally(ImGui.EndPopup, ImGui.BeginPopupModal(id)); @@ -106,6 +107,35 @@ public static partial class ImRaii public static unsafe IEndObject TabItem(byte* label, ImGuiTabItemFlags flags) => new EndConditionally(ImGuiNative.igEndTabItem, ImGuiNative.igBeginTabItem(label, null, flags) != 0); + public static unsafe IEndObject TabItem(string label, ImGuiTabItemFlags flags) + { + ArgumentNullException.ThrowIfNull(label); + + // One-off for now, we should make this into a generic solution if we need it more often + const int labelMaxAlloc = 2048; + + var labelByteCount = Encoding.UTF8.GetByteCount(label); + + if (labelByteCount > labelMaxAlloc) + { + throw new ArgumentOutOfRangeException(nameof(label), $"Label is too long. (Longer than {labelMaxAlloc} bytes)"); + } + + var nativeLabelStackBytes = stackalloc byte[labelByteCount + 1]; + + int nativeLabelOffset; + fixed (char* utf16Ptr = label) + { + nativeLabelOffset = Encoding.UTF8.GetBytes(utf16Ptr, label.Length, nativeLabelStackBytes, labelByteCount); + } + + nativeLabelStackBytes[nativeLabelOffset] = 0; + + var ret = ImGuiNative.igBeginTabItem(nativeLabelStackBytes, null, flags); + + return new EndConditionally(ImGuiNative.igEndTabItem, ret != 0); + } + public static IEndObject TabItem(string label, ref bool open) => new EndConditionally(ImGui.EndTabItem, ImGui.BeginTabItem(label, ref open)); @@ -174,7 +204,7 @@ public static partial class ImRaii return new EndUnconditionally(Widget.EndFramedGroup, true); } */ - + // Used to avoid tree pops when flag for no push is set. private static void Nop() { @@ -210,15 +240,15 @@ public static partial class ImRaii { private Action EndAction { get; } - public bool Success { get; } + public bool Success { get; } - public bool Disposed { get; private set; } + public bool Disposed { get; private set; } public EndUnconditionally(Action endAction, bool success) { this.EndAction = endAction; - this.Success = success; - this.Disposed = false; + this.Success = success; + this.Disposed = false; } public void Dispose() @@ -240,11 +270,11 @@ public static partial class ImRaii this.Success = success; this.Disposed = false; } - + public bool Success { get; } public bool Disposed { get; private set; } - + private Action EndAction { get; } public void Dispose() diff --git a/Dalamud/Interface/Windowing/Window.cs b/Dalamud/Interface/Windowing/Window.cs index a7565c294..7bf5a0363 100644 --- a/Dalamud/Interface/Windowing/Window.cs +++ b/Dalamud/Interface/Windowing/Window.cs @@ -11,6 +11,7 @@ using Dalamud.Interface.Colors; using Dalamud.Interface.Internal; using Dalamud.Interface.Utility; using Dalamud.Logging.Internal; + using FFXIVClientStructs.FFXIV.Client.UI; using ImGuiNET; using PInvoke; diff --git a/Dalamud/Interface/Windowing/WindowSystem.cs b/Dalamud/Interface/Windowing/WindowSystem.cs index 3e2a95a8d..dc4d6aca1 100644 --- a/Dalamud/Interface/Windowing/WindowSystem.cs +++ b/Dalamud/Interface/Windowing/WindowSystem.cs @@ -1,9 +1,9 @@ -using System; using System.Collections.Generic; using System.Linq; using Dalamud.Configuration.Internal; using Dalamud.Interface.Internal.ManagedAsserts; + using ImGuiNET; using Serilog; diff --git a/Dalamud/IoC/Internal/InherentDependencyAttribute.cs b/Dalamud/IoC/Internal/InherentDependencyAttribute.cs index 612a2dda6..069af38cb 100644 --- a/Dalamud/IoC/Internal/InherentDependencyAttribute.cs +++ b/Dalamud/IoC/Internal/InherentDependencyAttribute.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.IoC.Internal; +namespace Dalamud.IoC.Internal; /// /// Mark a class as being dependent on a service, without actually injecting it. diff --git a/Dalamud/IoC/Internal/InterfaceVersionAttribute.cs b/Dalamud/IoC/Internal/InterfaceVersionAttribute.cs index db69e17aa..64870e724 100644 --- a/Dalamud/IoC/Internal/InterfaceVersionAttribute.cs +++ b/Dalamud/IoC/Internal/InterfaceVersionAttribute.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.IoC.Internal; /// diff --git a/Dalamud/IoC/Internal/ObjectInstance.cs b/Dalamud/IoC/Internal/ObjectInstance.cs index 857a5b682..f636c2243 100644 --- a/Dalamud/IoC/Internal/ObjectInstance.cs +++ b/Dalamud/IoC/Internal/ObjectInstance.cs @@ -1,4 +1,3 @@ -using System; using System.Reflection; using System.Threading.Tasks; diff --git a/Dalamud/IoC/Internal/ResolveViaAttribute.cs b/Dalamud/IoC/Internal/ResolveViaAttribute.cs index 002878525..ffd6a36e0 100644 --- a/Dalamud/IoC/Internal/ResolveViaAttribute.cs +++ b/Dalamud/IoC/Internal/ResolveViaAttribute.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.IoC.Internal; +namespace Dalamud.IoC.Internal; /// /// Indicates that an interface a service can implement can be used to resolve that service. diff --git a/Dalamud/IoC/Internal/ServiceContainer.cs b/Dalamud/IoC/Internal/ServiceContainer.cs index 9adf37f85..73b1c2667 100644 --- a/Dalamud/IoC/Internal/ServiceContainer.cs +++ b/Dalamud/IoC/Internal/ServiceContainer.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; -using System.Runtime.Serialization; using System.Threading.Tasks; using Dalamud.Logging.Internal; diff --git a/Dalamud/IoC/Internal/ServiceScope.cs b/Dalamud/IoC/Internal/ServiceScope.cs index 9fcf1af3c..759819fe9 100644 --- a/Dalamud/IoC/Internal/ServiceScope.cs +++ b/Dalamud/IoC/Internal/ServiceScope.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; diff --git a/Dalamud/IoC/PluginInterfaceAttribute.cs b/Dalamud/IoC/PluginInterfaceAttribute.cs index 1711a5e84..1a5189950 100644 --- a/Dalamud/IoC/PluginInterfaceAttribute.cs +++ b/Dalamud/IoC/PluginInterfaceAttribute.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.IoC; /// diff --git a/Dalamud/IoC/PluginServiceAttribute.cs b/Dalamud/IoC/PluginServiceAttribute.cs index 84d500cb3..8a27de512 100644 --- a/Dalamud/IoC/PluginServiceAttribute.cs +++ b/Dalamud/IoC/PluginServiceAttribute.cs @@ -1,6 +1,4 @@ -using System; - -using JetBrains.Annotations; +using JetBrains.Annotations; namespace Dalamud.IoC; diff --git a/Dalamud/IoC/RequiredVersionAttribute.cs b/Dalamud/IoC/RequiredVersionAttribute.cs index 97aca56bb..b1b573b2a 100644 --- a/Dalamud/IoC/RequiredVersionAttribute.cs +++ b/Dalamud/IoC/RequiredVersionAttribute.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.IoC; /// diff --git a/Dalamud/Localization.cs b/Dalamud/Localization.cs index 7b2ac62e7..a50b6081f 100644 --- a/Dalamud/Localization.cs +++ b/Dalamud/Localization.cs @@ -1,4 +1,3 @@ -using System; using System.Globalization; using System.IO; using System.Linq; @@ -6,6 +5,7 @@ using System.Reflection; using CheapLoc; using Dalamud.Configuration.Internal; + using Serilog; namespace Dalamud; diff --git a/Dalamud/Logging/Internal/SerilogEventSink.cs b/Dalamud/Logging/Internal/SerilogEventSink.cs index 14baca456..fd0c57892 100644 --- a/Dalamud/Logging/Internal/SerilogEventSink.cs +++ b/Dalamud/Logging/Internal/SerilogEventSink.cs @@ -1,5 +1,3 @@ -using System; - using Serilog.Core; using Serilog.Events; diff --git a/Dalamud/Logging/Retention/RetentionBehaviour.cs b/Dalamud/Logging/Retention/RetentionBehaviour.cs index 66c4c5f97..e0d332355 100644 --- a/Dalamud/Logging/Retention/RetentionBehaviour.cs +++ b/Dalamud/Logging/Retention/RetentionBehaviour.cs @@ -1,5 +1,4 @@ -using System; -using System.IO; +using System.IO; using Serilog; diff --git a/Dalamud/Logging/ScopedPluginLogService.cs b/Dalamud/Logging/ScopedPluginLogService.cs index 0c044f2c2..b7930fb58 100644 --- a/Dalamud/Logging/ScopedPluginLogService.cs +++ b/Dalamud/Logging/ScopedPluginLogService.cs @@ -2,6 +2,7 @@ using Dalamud.IoC.Internal; using Dalamud.Plugin.Internal.Types; using Dalamud.Plugin.Services; + using Serilog; using Serilog.Core; using Serilog.Events; diff --git a/Dalamud/Memory/Exceptions/MemoryAllocationException.cs b/Dalamud/Memory/Exceptions/MemoryAllocationException.cs index efa875def..3f3a1b997 100644 --- a/Dalamud/Memory/Exceptions/MemoryAllocationException.cs +++ b/Dalamud/Memory/Exceptions/MemoryAllocationException.cs @@ -1,6 +1,3 @@ -using System; -using System.Runtime.Serialization; - namespace Dalamud.Memory.Exceptions; /// diff --git a/Dalamud/Memory/Exceptions/MemoryException.cs b/Dalamud/Memory/Exceptions/MemoryException.cs index 117a13c6b..aefc6bd63 100644 --- a/Dalamud/Memory/Exceptions/MemoryException.cs +++ b/Dalamud/Memory/Exceptions/MemoryException.cs @@ -1,6 +1,3 @@ -using System; -using System.Runtime.Serialization; - namespace Dalamud.Memory.Exceptions; /// diff --git a/Dalamud/Memory/Exceptions/MemoryPermissionException.cs b/Dalamud/Memory/Exceptions/MemoryPermissionException.cs index abc749740..5224bb844 100644 --- a/Dalamud/Memory/Exceptions/MemoryPermissionException.cs +++ b/Dalamud/Memory/Exceptions/MemoryPermissionException.cs @@ -1,6 +1,3 @@ -using System; -using System.Runtime.Serialization; - namespace Dalamud.Memory.Exceptions; /// diff --git a/Dalamud/Memory/Exceptions/MemoryReadException.cs b/Dalamud/Memory/Exceptions/MemoryReadException.cs index f0b79075d..66eb19551 100644 --- a/Dalamud/Memory/Exceptions/MemoryReadException.cs +++ b/Dalamud/Memory/Exceptions/MemoryReadException.cs @@ -1,6 +1,3 @@ -using System; -using System.Runtime.Serialization; - namespace Dalamud.Memory.Exceptions; /// diff --git a/Dalamud/Memory/Exceptions/MemoryWriteException.cs b/Dalamud/Memory/Exceptions/MemoryWriteException.cs index 87011edd3..4b2fa7728 100644 --- a/Dalamud/Memory/Exceptions/MemoryWriteException.cs +++ b/Dalamud/Memory/Exceptions/MemoryWriteException.cs @@ -1,6 +1,3 @@ -using System; -using System.Runtime.Serialization; - namespace Dalamud.Memory.Exceptions; /// diff --git a/Dalamud/Memory/MemoryProtection.cs b/Dalamud/Memory/MemoryProtection.cs index 019b656e8..ba196b2e6 100644 --- a/Dalamud/Memory/MemoryProtection.cs +++ b/Dalamud/Memory/MemoryProtection.cs @@ -1,5 +1,3 @@ -using System; - // This is a copy from NativeFunctions.MemoryProtection namespace Dalamud.Memory; diff --git a/Dalamud/NativeFunctions.cs b/Dalamud/NativeFunctions.cs index 14a39a6be..32ab99372 100644 --- a/Dalamud/NativeFunctions.cs +++ b/Dalamud/NativeFunctions.cs @@ -1,4 +1,3 @@ -using System; using System.Diagnostics.CodeAnalysis; using System.Net.Sockets; using System.Runtime.InteropServices; diff --git a/Dalamud/NativeMethods.txt b/Dalamud/NativeMethods.txt index 18143e1af..c42e76c1c 100644 --- a/Dalamud/NativeMethods.txt +++ b/Dalamud/NativeMethods.txt @@ -3,3 +3,11 @@ FILE_ACCESS_RIGHTS MoveFileEx FlushFileBuffers WriteFile + +SetWindowPos +SetForegroundWindow +SetFocus +SetActiveWindow +HWND_TOPMOST +HWND_NOTOPMOST +SET_WINDOW_POS_FLAGS diff --git a/Dalamud/Networking/Http/HappyEyeballsCallback.cs b/Dalamud/Networking/Http/HappyEyeballsCallback.cs index 7ca77576c..4e3ee61f6 100644 --- a/Dalamud/Networking/Http/HappyEyeballsCallback.cs +++ b/Dalamud/Networking/Http/HappyEyeballsCallback.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; diff --git a/Dalamud/Networking/Http/HappyHttpClient.cs b/Dalamud/Networking/Http/HappyHttpClient.cs index 37e327e84..aeed98695 100644 --- a/Dalamud/Networking/Http/HappyHttpClient.cs +++ b/Dalamud/Networking/Http/HappyHttpClient.cs @@ -1,5 +1,4 @@ -using System; -using System.Net; +using System.Net; using System.Net.Http; using System.Net.Http.Headers; diff --git a/Dalamud/Plugin/DalamudPluginInterface.cs b/Dalamud/Plugin/DalamudPluginInterface.cs index ced40ee2e..915d6a392 100644 --- a/Dalamud/Plugin/DalamudPluginInterface.cs +++ b/Dalamud/Plugin/DalamudPluginInterface.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; @@ -19,6 +18,7 @@ using Dalamud.Game.Text.SeStringHandling.Payloads; using Dalamud.Interface; using Dalamud.Interface.Internal; using Dalamud.Interface.Internal.Windows.PluginInstaller; +using Dalamud.Interface.Internal.Windows.Settings; using Dalamud.Plugin.Internal; using Dalamud.Plugin.Internal.Types; using Dalamud.Plugin.Internal.Types.Manifest; @@ -27,6 +27,8 @@ using Dalamud.Plugin.Ipc.Exceptions; using Dalamud.Plugin.Ipc.Internal; using Dalamud.Utility; +using static Dalamud.Interface.Internal.Windows.PluginInstaller.PluginInstallerWindow; + namespace Dalamud.Plugin; /// @@ -220,7 +222,19 @@ public sealed class DalamudPluginInterface : IDisposable /// Opens the with the plugin name set as search target. /// /// Returns false if the DalamudInterface was null. + [Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)] public bool OpenPluginInstaller() + { + return this.OpenPluginInstallerTo(PluginInstallerOpenKind.InstalledPlugins, this.plugin.InternalName); + } + + /// + /// Opens the , with an optional search term. + /// + /// The page to open the installer to. Defaults to the "All Plugins" page. + /// An optional search text to input in the search box. + /// Returns false if the DalamudInterface was null. + public bool OpenPluginInstallerTo(PluginInstallerOpenKind openTo = PluginInstallerOpenKind.AllPlugins, string searchText = null) { var dalamudInterface = Service.GetNullable(); // Can be null during boot if (dalamudInterface == null) @@ -228,12 +242,48 @@ public sealed class DalamudPluginInterface : IDisposable return false; } - dalamudInterface.OpenPluginInstallerTo(PluginInstallerWindow.PluginInstallerOpenKind.InstalledPlugins); - dalamudInterface.SetPluginInstallerSearchText(this.plugin.InternalName); + dalamudInterface.OpenPluginInstallerTo(openTo); + dalamudInterface.SetPluginInstallerSearchText(searchText); return true; } + /// + /// Opens the , with an optional search term. + /// + /// The tab to open the settings to. Defaults to the "General" tab. + /// An optional search text to input in the search box. + /// Returns false if the DalamudInterface was null. + public bool OpenDalamudSettingsTo(SettingsOpenKind openTo = SettingsOpenKind.General, string searchText = null) + { + var dalamudInterface = Service.GetNullable(); // Can be null during boot + if (dalamudInterface == null) + { + return false; + } + + dalamudInterface.OpenSettingsTo(openTo); + dalamudInterface.SetSettingsSearchText(searchText); + + return true; + } + + /// + /// Opens the dev menu bar. + /// + /// Returns false if the DalamudInterface was null. + public bool OpenDeveloperMenu() + { + var dalamudInterface = Service.GetNullable(); // Can be null during boot + if (dalamudInterface == null) + { + return false; + } + + dalamudInterface.OpenDevMenu(); + return true; + } + #region IPC /// @@ -348,7 +398,7 @@ public sealed class DalamudPluginInterface : IDisposable if (currentConfig == null) return; - this.configs.Save(currentConfig, this.plugin.InternalName, this.plugin.Manifest.WorkingPluginId); + this.configs.Save(currentConfig, this.plugin.InternalName, this.plugin.EffectiveWorkingPluginId); } /// @@ -375,7 +425,7 @@ public sealed class DalamudPluginInterface : IDisposable } // this shouldn't be a thing, I think, but just in case - return this.configs.Load(this.plugin.InternalName, this.plugin.Manifest.WorkingPluginId); + return this.configs.Load(this.plugin.InternalName, this.plugin.EffectiveWorkingPluginId); } /// diff --git a/Dalamud/Plugin/IDalamudPlugin.cs b/Dalamud/Plugin/IDalamudPlugin.cs index b48d55d1c..ebf39708f 100644 --- a/Dalamud/Plugin/IDalamudPlugin.cs +++ b/Dalamud/Plugin/IDalamudPlugin.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Plugin; /// diff --git a/Dalamud/Plugin/InstalledPluginState.cs b/Dalamud/Plugin/InstalledPluginState.cs index 322db3423..79b9de1ee 100644 --- a/Dalamud/Plugin/InstalledPluginState.cs +++ b/Dalamud/Plugin/InstalledPluginState.cs @@ -1,5 +1,6 @@ -using System; +using Dalamud.Utility; namespace Dalamud.Plugin; +[Api10ToDo("Refactor into an interface, add wrappers for OpenMainUI and OpenConfigUI")] public record InstalledPluginState(string Name, string InternalName, bool IsLoaded, Version Version); diff --git a/Dalamud/Plugin/Internal/Exceptions/PluginException.cs b/Dalamud/Plugin/Internal/Exceptions/PluginException.cs index 292be5431..ff1f324ea 100644 --- a/Dalamud/Plugin/Internal/Exceptions/PluginException.cs +++ b/Dalamud/Plugin/Internal/Exceptions/PluginException.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Plugin.Internal.Exceptions; /// diff --git a/Dalamud/Plugin/Internal/Loader/AssemblyLoadContextBuilder.cs b/Dalamud/Plugin/Internal/Loader/AssemblyLoadContextBuilder.cs index 1a6830a3a..1c6e6feed 100644 --- a/Dalamud/Plugin/Internal/Loader/AssemblyLoadContextBuilder.cs +++ b/Dalamud/Plugin/Internal/Loader/AssemblyLoadContextBuilder.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster, Dalamud contributors. // Licensed under the Apache License, Version 2.0. See License.txt in the Loader root for license information. -using System; using System.Collections.Generic; using System.IO; using System.Reflection; diff --git a/Dalamud/Plugin/Internal/Loader/LibraryModel/ManagedLibrary.cs b/Dalamud/Plugin/Internal/Loader/LibraryModel/ManagedLibrary.cs index 386184c28..77672700c 100644 --- a/Dalamud/Plugin/Internal/Loader/LibraryModel/ManagedLibrary.cs +++ b/Dalamud/Plugin/Internal/Loader/LibraryModel/ManagedLibrary.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster, Dalamud contributors. // Licensed under the Apache License, Version 2.0. See License.txt in the Loader root for license information. -using System; using System.Diagnostics; using System.IO; using System.Reflection; diff --git a/Dalamud/Plugin/Internal/Loader/LibraryModel/NativeLibrary.cs b/Dalamud/Plugin/Internal/Loader/LibraryModel/NativeLibrary.cs index 47b9f701d..42b57502b 100644 --- a/Dalamud/Plugin/Internal/Loader/LibraryModel/NativeLibrary.cs +++ b/Dalamud/Plugin/Internal/Loader/LibraryModel/NativeLibrary.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster, Dalamud contributors. // Licensed under the Apache License, Version 2.0. See License.txt in the Loader root for license information. -using System; using System.Diagnostics; using System.IO; diff --git a/Dalamud/Plugin/Internal/Loader/LoaderConfig.cs b/Dalamud/Plugin/Internal/Loader/LoaderConfig.cs index 0b2150069..b863b8ee1 100644 --- a/Dalamud/Plugin/Internal/Loader/LoaderConfig.cs +++ b/Dalamud/Plugin/Internal/Loader/LoaderConfig.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster, Dalamud contributors. // Licensed under the Apache License, Version 2.0. See License.txt in the Loader root for license information. -using System; using System.Collections.Generic; using System.IO; using System.Reflection; diff --git a/Dalamud/Plugin/Internal/Loader/ManagedLoadContext.cs b/Dalamud/Plugin/Internal/Loader/ManagedLoadContext.cs index e0629217a..4ea4eb5c4 100644 --- a/Dalamud/Plugin/Internal/Loader/ManagedLoadContext.cs +++ b/Dalamud/Plugin/Internal/Loader/ManagedLoadContext.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster, Dalamud contributors. // Licensed under the Apache License, Version 2.0. See License.txt in the Loader root for license information. -using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; diff --git a/Dalamud/Plugin/Internal/Loader/PluginLoader.cs b/Dalamud/Plugin/Internal/Loader/PluginLoader.cs index 63b47cf17..54b9cad4b 100644 --- a/Dalamud/Plugin/Internal/Loader/PluginLoader.cs +++ b/Dalamud/Plugin/Internal/Loader/PluginLoader.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster, Dalamud team. // Licensed under the Apache License, Version 2.0. See License.txt in the Loader root for license information. -using System.IO; using System.Reflection; using System.Runtime.Loader; diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs index 5924a4e08..7517ae413 100644 --- a/Dalamud/Plugin/Internal/PluginManager.cs +++ b/Dalamud/Plugin/Internal/PluginManager.cs @@ -19,10 +19,10 @@ using Dalamud.Game.Gui.Dtr; using Dalamud.Game.Text; using Dalamud.Game.Text.SeStringHandling; using Dalamud.Game.Text.SeStringHandling.Payloads; +using Dalamud.Interface; using Dalamud.Interface.Internal; using Dalamud.Interface.Internal.Windows.PluginInstaller; using Dalamud.IoC; -using Dalamud.IoC.Internal; using Dalamud.Logging.Internal; using Dalamud.Networking.Http; using Dalamud.Plugin.Internal.Exceptions; @@ -42,8 +42,8 @@ namespace Dalamud.Plugin.Internal; /// NOTE: ALL plugin exposed services are marked as dependencies for /// from . /// -[ServiceManager.BlockingEarlyLoadedService("Accomodation of plugins that blocks the game startup.")] -internal partial class PluginManager : IInternalDisposableService +[ServiceManager.BlockingEarlyLoadedService("Accommodation of plugins that blocks the game startup.")] +internal class PluginManager : IInternalDisposableService { /// /// Default time to wait between plugin unload and plugin assembly unload. @@ -130,7 +130,7 @@ internal partial class PluginManager : IInternalDisposableService (_, _) => { Service.GetNullable()?.OpenPluginInstallerTo( - PluginInstallerWindow.PluginInstallerOpenKind.Changelogs); + PluginInstallerOpenKind.Changelogs); })); this.configuration.PluginTestingOptIns ??= new(); @@ -245,6 +245,11 @@ internal partial class PluginManager : IInternalDisposableService /// Gets or sets a value indicating whether banned plugins will be loaded. /// public bool LoadBannedPlugins { get; set; } + + /// + /// Gets a tracker for plugins that are loading at startup, used to display information to the user. + /// + public StartupLoadTracker? StartupLoadTracking { get; private set; } /// /// Gets a value indicating whether the given repo manifest should be visible to the user. @@ -632,6 +637,15 @@ internal partial class PluginManager : IInternalDisposableService Log.Information($"============= LoadPluginsAsync({logPrefix}) END ============="); } + // Initialize the startup load tracker for all LoadSync plugins + { + this.StartupLoadTracking = new(); + foreach (var pluginDef in pluginDefs.Where(x => x.Manifest.LoadSync)) + { + this.StartupLoadTracking.Add(pluginDef.Manifest!.InternalName, pluginDef.Manifest.Name); + } + } + var syncPlugins = pluginDefs.Where(def => def.Manifest?.LoadSync == true).ToList(); var asyncPlugins = pluginDefs.Where(def => def.Manifest?.LoadSync != true).ToList(); var loadTasks = new List(); @@ -702,6 +716,8 @@ internal partial class PluginManager : IInternalDisposableService { Log.Error(ex, "Plugin and profile validation failed!"); } + + this.StartupLoadTracking = null; }, tokenSource.Token); } @@ -1013,7 +1029,7 @@ internal partial class PluginManager : IInternalDisposableService { var plugin = metadata.InstalledPlugin; - var workingPluginId = metadata.InstalledPlugin.Manifest.WorkingPluginId; + var workingPluginId = metadata.InstalledPlugin.EffectiveWorkingPluginId; if (workingPluginId == Guid.Empty) throw new Exception("Existing plugin had no WorkingPluginId"); @@ -1163,7 +1179,8 @@ internal partial class PluginManager : IInternalDisposableService } // API level - we keep the API before this in the installer to show as "outdated" - if (manifest.DalamudApiLevel < DalamudApiLevel - 1 && !this.LoadAllApiLevels) + var effectiveApiLevel = this.UseTesting(manifest) && manifest.TestingDalamudApiLevel != null ? manifest.TestingDalamudApiLevel.Value : manifest.DalamudApiLevel; + if (effectiveApiLevel < DalamudApiLevel - 1 && !this.LoadAllApiLevels) { Log.Verbose($"API Level: {manifest.InternalName} - {manifest.AssemblyVersion} - {manifest.TestingAssemblyVersion}"); return false; @@ -1314,16 +1331,16 @@ internal partial class PluginManager : IInternalDisposableService foreach (var installedPlugin in this.InstalledPlugins) { - if (installedPlugin.Manifest.WorkingPluginId == Guid.Empty) + if (installedPlugin.EffectiveWorkingPluginId == Guid.Empty) throw new Exception($"{(installedPlugin is LocalDevPlugin ? "DevPlugin" : "Plugin")} '{installedPlugin.Manifest.InternalName}' has an empty WorkingPluginId."); - if (seenIds.Contains(installedPlugin.Manifest.WorkingPluginId)) + if (seenIds.Contains(installedPlugin.EffectiveWorkingPluginId)) { throw new Exception( - $"{(installedPlugin is LocalDevPlugin ? "DevPlugin" : "Plugin")} '{installedPlugin.Manifest.InternalName}' has a duplicate WorkingPluginId '{installedPlugin.Manifest.WorkingPluginId}'"); + $"{(installedPlugin is LocalDevPlugin ? "DevPlugin" : "Plugin")} '{installedPlugin.Manifest.InternalName}' has a duplicate WorkingPluginId '{installedPlugin.EffectiveWorkingPluginId}'"); } - seenIds.Add(installedPlugin.Manifest.WorkingPluginId); + seenIds.Add(installedPlugin.EffectiveWorkingPluginId); } this.profileManager.ParanoiaValidateProfiles(); @@ -1371,7 +1388,7 @@ internal partial class PluginManager : IInternalDisposableService { // Only remove entries from the default profile that are NOT currently tied to an active LocalPlugin var guidsToRemove = this.profileManager.DefaultProfile.Plugins - .Where(x => this.InstalledPlugins.All(y => y.Manifest.WorkingPluginId != x.WorkingPluginId)) + .Where(x => this.InstalledPlugins.All(y => y.EffectiveWorkingPluginId != x.WorkingPluginId)) .Select(x => x.WorkingPluginId) .ToArray(); @@ -1543,9 +1560,9 @@ internal partial class PluginManager : IInternalDisposableService // This will also happen if you are installing a plugin with the installer, and that's intended! // It means that, if you have a profile which has unsatisfied plugins, installing a matching plugin will // enter it into the profiles it can match. - if (plugin.Manifest.WorkingPluginId == Guid.Empty) + if (plugin.EffectiveWorkingPluginId == Guid.Empty) throw new Exception("Plugin should have a WorkingPluginId at this point"); - this.profileManager.MigrateProfilesToGuidsForPlugin(plugin.Manifest.InternalName, plugin.Manifest.WorkingPluginId); + this.profileManager.MigrateProfilesToGuidsForPlugin(plugin.Manifest.InternalName, plugin.EffectiveWorkingPluginId); var wantedByAnyProfile = false; @@ -1556,7 +1573,7 @@ internal partial class PluginManager : IInternalDisposableService loadPlugin &= !isBoot; var wantsInDefaultProfile = - this.profileManager.DefaultProfile.WantsPlugin(plugin.Manifest.WorkingPluginId); + this.profileManager.DefaultProfile.WantsPlugin(plugin.EffectiveWorkingPluginId); if (wantsInDefaultProfile == null) { // We don't know about this plugin, so we don't want to do anything here. @@ -1565,7 +1582,7 @@ internal partial class PluginManager : IInternalDisposableService // Check if any profile wants this plugin. We need to do this here, since we want to allow loading a dev plugin if a non-default profile wants it active. // Note that this will not add the plugin to the default profile. That's done below in any other case. - wantedByAnyProfile = await this.profileManager.GetWantStateAsync(plugin.Manifest.WorkingPluginId, plugin.Manifest.InternalName, false, false); + wantedByAnyProfile = await this.profileManager.GetWantStateAsync(plugin.EffectiveWorkingPluginId, plugin.Manifest.InternalName, false, false); // If it is wanted by any other profile, we do want to load it. if (wantedByAnyProfile) @@ -1575,28 +1592,28 @@ internal partial class PluginManager : IInternalDisposableService { // We didn't want this plugin, and StartOnBoot is on. That means we don't want it and it should stay off until manually enabled. Log.Verbose("DevPlugin {Name} disabled and StartOnBoot => disable", plugin.Manifest.InternalName); - await this.profileManager.DefaultProfile.AddOrUpdateAsync(plugin.Manifest.WorkingPluginId, plugin.Manifest.InternalName, false, false); + await this.profileManager.DefaultProfile.AddOrUpdateAsync(plugin.EffectiveWorkingPluginId, plugin.Manifest.InternalName, false, false); loadPlugin = false; } else if (wantsInDefaultProfile == true && devPlugin.StartOnBoot) { // We wanted this plugin, and StartOnBoot is on. That means we actually do want it. Log.Verbose("DevPlugin {Name} enabled and StartOnBoot => enable", plugin.Manifest.InternalName); - await this.profileManager.DefaultProfile.AddOrUpdateAsync(plugin.Manifest.WorkingPluginId, plugin.Manifest.InternalName, true, false); + await this.profileManager.DefaultProfile.AddOrUpdateAsync(plugin.EffectiveWorkingPluginId, plugin.Manifest.InternalName, true, false); loadPlugin = !doNotLoad; } else if (wantsInDefaultProfile == true && !devPlugin.StartOnBoot) { // We wanted this plugin, but StartOnBoot is off. This means we don't want it anymore. Log.Verbose("DevPlugin {Name} enabled and !StartOnBoot => disable", plugin.Manifest.InternalName); - await this.profileManager.DefaultProfile.AddOrUpdateAsync(plugin.Manifest.WorkingPluginId, plugin.Manifest.InternalName, false, false); + await this.profileManager.DefaultProfile.AddOrUpdateAsync(plugin.EffectiveWorkingPluginId, plugin.Manifest.InternalName, false, false); loadPlugin = false; } else if (wantsInDefaultProfile == false && !devPlugin.StartOnBoot) { // We didn't want this plugin, and StartOnBoot is off. We don't want it. Log.Verbose("DevPlugin {Name} disabled and !StartOnBoot => disable", plugin.Manifest.InternalName); - await this.profileManager.DefaultProfile.AddOrUpdateAsync(plugin.Manifest.WorkingPluginId, plugin.Manifest.InternalName, false, false); + await this.profileManager.DefaultProfile.AddOrUpdateAsync(plugin.EffectiveWorkingPluginId, plugin.Manifest.InternalName, false, false); loadPlugin = false; } @@ -1609,7 +1626,7 @@ internal partial class PluginManager : IInternalDisposableService // Plugins that aren't in any profile will be added to the default profile with this call. // We are skipping a double-lookup for dev plugins that are wanted by non-default profiles, as noted above. - wantedByAnyProfile = wantedByAnyProfile || await this.profileManager.GetWantStateAsync(plugin.Manifest.WorkingPluginId, plugin.Manifest.InternalName, defaultState); + wantedByAnyProfile = wantedByAnyProfile || await this.profileManager.GetWantStateAsync(plugin.EffectiveWorkingPluginId, plugin.Manifest.InternalName, defaultState); Log.Information("{Name} defaultState: {State} wantedByAnyProfile: {WantedByAny} loadPlugin: {LoadPlugin}", plugin.Manifest.InternalName, defaultState, wantedByAnyProfile, loadPlugin); if (loadPlugin) @@ -1683,12 +1700,16 @@ internal partial class PluginManager : IInternalDisposableService if (plugin == null) throw new Exception("Plugin was null when adding to list"); - + lock (this.pluginListLock) { this.installedPluginsList.Add(plugin); } + // Mark as finished loading + if (manifest.LoadSync) + this.StartupLoadTracking?.Finish(manifest.InternalName); + return plugin; } @@ -1709,7 +1730,15 @@ internal partial class PluginManager : IInternalDisposableService var updates = this.AvailablePlugins .Where(remoteManifest => plugin.Manifest.InternalName == remoteManifest.InternalName) .Where(remoteManifest => plugin.Manifest.InstalledFromUrl == remoteManifest.SourceRepo.PluginMasterUrl || !remoteManifest.SourceRepo.IsThirdParty) - .Where(remoteManifest => remoteManifest.DalamudApiLevel == DalamudApiLevel) + .Where(remoteManifest => + { + var useTesting = this.UseTesting(remoteManifest); + var candidateApiLevel = useTesting && remoteManifest.TestingDalamudApiLevel != null + ? remoteManifest.TestingDalamudApiLevel.Value + : remoteManifest.DalamudApiLevel; + + return candidateApiLevel == DalamudApiLevel; + }) .Select(remoteManifest => { var useTesting = this.UseTesting(remoteManifest); @@ -1782,7 +1811,16 @@ internal partial class PluginManager : IInternalDisposableService using (Timings.Start("PM Load Sync Plugins")) { - this.LoadAllPlugins().Wait(); + var loadAllPlugins = Task.Run(this.LoadAllPlugins); + + // We wait for all blocking services and tasks to finish before kicking off the main thread in any mode. + // This means that we don't want to block here if this stupid thing isn't enabled. + if (this.configuration.IsResumeGameAfterPluginLoad) + { + Log.Verbose("Waiting for all plugins to load before resuming game"); + loadAllPlugins.Wait(); + } + Log.Information("[T3] PML OK!"); } @@ -1793,6 +1831,63 @@ internal partial class PluginManager : IInternalDisposableService Log.Error(ex, "Plugin load failed"); } } + + /// + /// Simple class that tracks the internal names and public names of plugins that we are planning to load at startup, + /// and are still actively loading. + /// + public class StartupLoadTracker + { + private readonly Dictionary internalToPublic = new(); + private readonly ConcurrentBag allInternalNames = new(); + private readonly ConcurrentBag finishedInternalNames = new(); + + /// + /// Gets a value indicating the total load progress. + /// + public float Progress => (float)this.finishedInternalNames.Count / this.allInternalNames.Count; + + /// + /// Calculate a set of internal names that are still pending. + /// + /// Set of pending InternalNames. + public IReadOnlySet GetPendingInternalNames() + { + var pending = new HashSet(this.allInternalNames); + pending.ExceptWith(this.finishedInternalNames); + return pending; + } + + /// + /// Track a new plugin. + /// + /// The plugin's internal name. + /// The plugin's public name. + public void Add(string internalName, string publicName) + { + this.internalToPublic[internalName] = publicName; + this.allInternalNames.Add(internalName); + } + + /// + /// Mark a plugin as finished loading. + /// + /// The internal name of the plugin. + public void Finish(string internalName) + { + this.finishedInternalNames.Add(internalName); + } + + /// + /// Get the public name for a given internal name. + /// + /// The internal name to look up. + /// The public name. + public string? GetPublicName(string internalName) + { + return this.internalToPublic.TryGetValue(internalName, out var publicName) ? publicName : null; + } + } private static class Locs { diff --git a/Dalamud/Plugin/Internal/Profiles/Profile.cs b/Dalamud/Plugin/Internal/Profiles/Profile.cs index 6319cca0d..2c254167e 100644 --- a/Dalamud/Plugin/Internal/Profiles/Profile.cs +++ b/Dalamud/Plugin/Internal/Profiles/Profile.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; diff --git a/Dalamud/Plugin/Internal/Profiles/ProfileManager.cs b/Dalamud/Plugin/Internal/Profiles/ProfileManager.cs index ee8505174..e36e9908b 100644 --- a/Dalamud/Plugin/Internal/Profiles/ProfileManager.cs +++ b/Dalamud/Plugin/Internal/Profiles/ProfileManager.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text.RegularExpressions; @@ -184,8 +183,8 @@ internal class ProfileManager : IServiceType var installedPlugin = pm.InstalledPlugins.FirstOrDefault(x => x.Manifest.InternalName == plugin.InternalName); if (installedPlugin != null) { - Log.Information("Satisfying plugin {InternalName} for profile {Name} with {Guid}", plugin.InternalName, newModel.Name, installedPlugin.Manifest.WorkingPluginId); - plugin.WorkingPluginId = installedPlugin.Manifest.WorkingPluginId; + Log.Information("Satisfying plugin {InternalName} for profile {Name} with {Guid}", plugin.InternalName, newModel.Name, installedPlugin.EffectiveWorkingPluginId); + plugin.WorkingPluginId = installedPlugin.EffectiveWorkingPluginId; } else { @@ -238,7 +237,7 @@ internal class ProfileManager : IServiceType var pm = Service.Get(); foreach (var installedPlugin in pm.InstalledPlugins) { - var wantThis = wantActive.Any(x => x.WorkingPluginId == installedPlugin.Manifest.WorkingPluginId); + var wantThis = wantActive.Any(x => x.WorkingPluginId == installedPlugin.EffectiveWorkingPluginId); switch (wantThis) { case true when !installedPlugin.IsLoaded: diff --git a/Dalamud/Plugin/Internal/Types/BannedPlugin.cs b/Dalamud/Plugin/Internal/Types/BannedPlugin.cs index 1d5f956b3..a21bbf02b 100644 --- a/Dalamud/Plugin/Internal/Types/BannedPlugin.cs +++ b/Dalamud/Plugin/Internal/Types/BannedPlugin.cs @@ -1,5 +1,3 @@ -using System; - using Newtonsoft.Json; namespace Dalamud.Plugin.Internal.Types; diff --git a/Dalamud/Plugin/Internal/Types/LocalDevPlugin.cs b/Dalamud/Plugin/Internal/Types/LocalDevPlugin.cs index 3615f923b..5a3552199 100644 --- a/Dalamud/Plugin/Internal/Types/LocalDevPlugin.cs +++ b/Dalamud/Plugin/Internal/Types/LocalDevPlugin.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -51,14 +50,6 @@ internal class LocalDevPlugin : LocalPlugin, IDisposable Log.Verbose("{InternalName} was assigned new devPlugin GUID {Guid}", this.InternalName, this.devSettings.WorkingPluginId); configuration.QueueSave(); } - - // If the ID in the manifest is wrong, force the good one - if (this.DevImposedWorkingPluginId != this.manifest.WorkingPluginId) - { - Debug.Assert(this.DevImposedWorkingPluginId != Guid.Empty, "Empty guid for devPlugin"); - this.manifest.WorkingPluginId = this.DevImposedWorkingPluginId; - this.SaveManifest("dev imposed working plugin id"); - } if (this.AutomaticReload) { @@ -100,7 +91,10 @@ internal class LocalDevPlugin : LocalPlugin, IDisposable /// Gets an ID uniquely identifying this specific instance of a devPlugin. /// public Guid DevImposedWorkingPluginId => this.devSettings.WorkingPluginId; - + + /// + public override Guid EffectiveWorkingPluginId => this.DevImposedWorkingPluginId; + /// /// Gets a list of validation problems that have been dismissed by the user. /// @@ -149,6 +143,23 @@ internal class LocalDevPlugin : LocalPlugin, IDisposable } } + /// + /// Reload the manifest if it exists, to update possible changes. + /// + /// Thrown if the manifest could not be loaded. + public void ReloadManifest() + { + var manifestPath = LocalPluginManifest.GetManifestFile(this.DllFile); + if (manifestPath.Exists) + this.manifest = LocalPluginManifest.Load(manifestPath) ?? throw new Exception("Could not reload manifest."); + } + + /// + protected override void OnPreReload() + { + this.ReloadManifest(); + } + private void OnFileChanged(object sender, FileSystemEventArgs args) { var current = Interlocked.Increment(ref this.reloadCounter); diff --git a/Dalamud/Plugin/Internal/Types/LocalPlugin.cs b/Dalamud/Plugin/Internal/Types/LocalPlugin.cs index 37d4393b0..6c3ca8c0c 100644 --- a/Dalamud/Plugin/Internal/Types/LocalPlugin.cs +++ b/Dalamud/Plugin/Internal/Types/LocalPlugin.cs @@ -91,7 +91,7 @@ internal class LocalPlugin : IDisposable } // Create an installation instance ID for this plugin, if it doesn't have one yet - if (this.manifest.WorkingPluginId == Guid.Empty) + if (this.manifest.WorkingPluginId == Guid.Empty && !this.IsDev) { this.manifest.WorkingPluginId = Guid.NewGuid(); @@ -162,12 +162,12 @@ internal class LocalPlugin : IDisposable /// INCLUDES the default profile. /// public bool IsWantedByAnyProfile => - Service.Get().GetWantStateAsync(this.manifest.WorkingPluginId, this.Manifest.InternalName, false, false).GetAwaiter().GetResult(); + Service.Get().GetWantStateAsync(this.EffectiveWorkingPluginId, this.Manifest.InternalName, false, false).GetAwaiter().GetResult(); /// /// Gets a value indicating whether this plugin's API level is out of date. /// - public bool IsOutdated => this.manifest.DalamudApiLevel < PluginManager.DalamudApiLevel; + public bool IsOutdated => this.manifest.EffectiveApiLevel < PluginManager.DalamudApiLevel; /// /// Gets a value indicating whether the plugin is for testing use only. @@ -215,6 +215,11 @@ internal class LocalPlugin : IDisposable /// public Version EffectiveVersion => this.manifest.EffectiveVersion; + /// + /// Gets the effective working plugin ID for this plugin. + /// + public virtual Guid EffectiveWorkingPluginId => this.manifest.WorkingPluginId; + /// /// Gets the service scope for this plugin. /// @@ -271,11 +276,8 @@ internal class LocalPlugin : IDisposable await this.pluginLoadStateLock.WaitAsync(); try { - if (reloading && this.IsDev) - { - // Reload the manifest in-case there were changes here too. - this.ReloadManifest(); - } + if (reloading) + this.OnPreReload(); // If we reload a plugin we don't want to delete it. Makes sense, right? if (this.manifest.ScheduledForDeletion) @@ -318,8 +320,8 @@ internal class LocalPlugin : IDisposable if (this.manifest.ApplicableVersion < dalamud.StartInfo.GameVersion) throw new PluginPreconditionFailedException($"Unable to load {this.Name}, game is newer than applicable version {this.manifest.ApplicableVersion}"); - if (this.manifest.DalamudApiLevel < PluginManager.DalamudApiLevel && !pluginManager.LoadAllApiLevels) - throw new PluginPreconditionFailedException($"Unable to load {this.Name}, incompatible API level {this.manifest.DalamudApiLevel}"); + if (this.manifest.EffectiveApiLevel < PluginManager.DalamudApiLevel && !pluginManager.LoadAllApiLevels) + throw new PluginPreconditionFailedException($"Unable to load {this.Name}, incompatible API level {this.manifest.EffectiveApiLevel}"); // We might want to throw here? if (!this.IsWantedByAnyProfile) @@ -578,24 +580,6 @@ internal class LocalPlugin : IDisposable this.SaveManifest("scheduling for deletion"); } - /// - /// Reload the manifest if it exists, preserve the internal Disabled state. - /// - public void ReloadManifest() - { - var manifestPath = LocalPluginManifest.GetManifestFile(this.DllFile); - if (manifestPath.Exists) - { - // Save some state that we do actually want to carry over - var guid = this.manifest.WorkingPluginId; - - this.manifest = LocalPluginManifest.Load(manifestPath) ?? throw new Exception("Could not reload manifest."); - this.manifest.WorkingPluginId = guid; - - this.SaveManifest("dev reload"); - } - } - /// /// Get the repository this plugin was installed from. /// @@ -620,6 +604,13 @@ internal class LocalPlugin : IDisposable /// /// Why it should be saved. protected void SaveManifest(string reason) => this.manifest.Save(this.manifestFile, reason); + + /// + /// Called before a plugin is reloaded. + /// + protected virtual void OnPreReload() + { + } private static void SetupLoaderConfig(LoaderConfig config) { diff --git a/Dalamud/Plugin/Internal/Types/Manifest/ILocalPluginManifest.cs b/Dalamud/Plugin/Internal/Types/Manifest/ILocalPluginManifest.cs index 5b147dde1..2db1e5aad 100644 --- a/Dalamud/Plugin/Internal/Types/Manifest/ILocalPluginManifest.cs +++ b/Dalamud/Plugin/Internal/Types/Manifest/ILocalPluginManifest.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Plugin.Internal.Types.Manifest; +namespace Dalamud.Plugin.Internal.Types.Manifest; /// /// Public interface for the local plugin manifest. diff --git a/Dalamud/Plugin/Internal/Types/Manifest/IPluginManifest.cs b/Dalamud/Plugin/Internal/Types/Manifest/IPluginManifest.cs index 9e052efad..4b0951397 100644 --- a/Dalamud/Plugin/Internal/Types/Manifest/IPluginManifest.cs +++ b/Dalamud/Plugin/Internal/Types/Manifest/IPluginManifest.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; namespace Dalamud.Plugin.Internal.Types.Manifest; @@ -64,11 +63,17 @@ public interface IPluginManifest public List? Tags { get; } /// - /// Gets the API level of this plugin. For the current API level, please see - /// for the currently used API level. + /// Gets the API level of this plugin. + /// For the current API level, please see for the currently used API level. /// public int DalamudApiLevel { get; } + /// + /// Gets the API level of the plugin's testing variant. + /// For the current API level, please see for the currently used API level. + /// + public int? TestingDalamudApiLevel { get; } + /// /// Gets the number of downloads this plugin has. /// diff --git a/Dalamud/Plugin/Internal/Types/Manifest/LocalPluginManifest.cs b/Dalamud/Plugin/Internal/Types/Manifest/LocalPluginManifest.cs index b7fe6d062..31469a914 100644 --- a/Dalamud/Plugin/Internal/Types/Manifest/LocalPluginManifest.cs +++ b/Dalamud/Plugin/Internal/Types/Manifest/LocalPluginManifest.cs @@ -1,4 +1,3 @@ -using System; using System.IO; using Dalamud.Utility; @@ -46,6 +45,11 @@ internal record LocalPluginManifest : PluginManifest, ILocalPluginManifest /// public Version EffectiveVersion => this.Testing && this.TestingAssemblyVersion != null ? this.TestingAssemblyVersion : this.AssemblyVersion; + /// + /// Gets the effective API level of this plugin. + /// + public int EffectiveApiLevel => this.Testing && this.TestingDalamudApiLevel != null ? this.TestingDalamudApiLevel.Value : this.DalamudApiLevel; + /// /// Save a plugin manifest to file. /// diff --git a/Dalamud/Plugin/Internal/Types/PluginManifest.cs b/Dalamud/Plugin/Internal/Types/PluginManifest.cs index baaf37558..01951c8a6 100644 --- a/Dalamud/Plugin/Internal/Types/PluginManifest.cs +++ b/Dalamud/Plugin/Internal/Types/PluginManifest.cs @@ -79,6 +79,10 @@ internal record PluginManifest : IPluginManifest [JsonProperty] public int DalamudApiLevel { get; init; } = PluginManager.DalamudApiLevel; + /// + [JsonProperty] + public int? TestingDalamudApiLevel { get; init; } + /// [JsonProperty] public long DownloadCount { get; init; } diff --git a/Dalamud/Plugin/Internal/Types/PluginPatchData.cs b/Dalamud/Plugin/Internal/Types/PluginPatchData.cs index d95c1e62c..f713e4df0 100644 --- a/Dalamud/Plugin/Internal/Types/PluginPatchData.cs +++ b/Dalamud/Plugin/Internal/Types/PluginPatchData.cs @@ -1,4 +1,3 @@ -using System; using System.IO; namespace Dalamud.Plugin.Internal.Types; diff --git a/Dalamud/Plugin/Internal/Types/PluginRepository.cs b/Dalamud/Plugin/Internal/Types/PluginRepository.cs index 8de25aa08..2f63070c3 100644 --- a/Dalamud/Plugin/Internal/Types/PluginRepository.cs +++ b/Dalamud/Plugin/Internal/Types/PluginRepository.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; diff --git a/Dalamud/Plugin/Ipc/Exceptions/DataCacheCreationError.cs b/Dalamud/Plugin/Ipc/Exceptions/DataCacheCreationError.cs index 0dafc88aa..db095bad9 100644 --- a/Dalamud/Plugin/Ipc/Exceptions/DataCacheCreationError.cs +++ b/Dalamud/Plugin/Ipc/Exceptions/DataCacheCreationError.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Plugin.Ipc.Exceptions; /// diff --git a/Dalamud/Plugin/Ipc/Exceptions/DataCacheTypeMismatchError.cs b/Dalamud/Plugin/Ipc/Exceptions/DataCacheTypeMismatchError.cs index 4db731687..e5d9cc4db 100644 --- a/Dalamud/Plugin/Ipc/Exceptions/DataCacheTypeMismatchError.cs +++ b/Dalamud/Plugin/Ipc/Exceptions/DataCacheTypeMismatchError.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Plugin.Ipc.Exceptions; /// diff --git a/Dalamud/Plugin/Ipc/Exceptions/DataCacheValueNullError.cs b/Dalamud/Plugin/Ipc/Exceptions/DataCacheValueNullError.cs index daa8bf509..f81a7c324 100644 --- a/Dalamud/Plugin/Ipc/Exceptions/DataCacheValueNullError.cs +++ b/Dalamud/Plugin/Ipc/Exceptions/DataCacheValueNullError.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Plugin.Ipc.Exceptions; /// diff --git a/Dalamud/Plugin/Ipc/Exceptions/IpcError.cs b/Dalamud/Plugin/Ipc/Exceptions/IpcError.cs index 5cc0ccae9..0212bd673 100644 --- a/Dalamud/Plugin/Ipc/Exceptions/IpcError.cs +++ b/Dalamud/Plugin/Ipc/Exceptions/IpcError.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Plugin.Ipc.Exceptions; /// diff --git a/Dalamud/Plugin/Ipc/Exceptions/IpcTypeMismatchError.cs b/Dalamud/Plugin/Ipc/Exceptions/IpcTypeMismatchError.cs index 1aa191b78..abe6e70b8 100644 --- a/Dalamud/Plugin/Ipc/Exceptions/IpcTypeMismatchError.cs +++ b/Dalamud/Plugin/Ipc/Exceptions/IpcTypeMismatchError.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Plugin.Ipc.Exceptions; /// diff --git a/Dalamud/Plugin/Ipc/Exceptions/IpcValueNullError.cs b/Dalamud/Plugin/Ipc/Exceptions/IpcValueNullError.cs index f5a764387..50f9dcaba 100644 --- a/Dalamud/Plugin/Ipc/Exceptions/IpcValueNullError.cs +++ b/Dalamud/Plugin/Ipc/Exceptions/IpcValueNullError.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Plugin.Ipc.Exceptions; /// diff --git a/Dalamud/Plugin/Ipc/ICallGateProvider.cs b/Dalamud/Plugin/Ipc/ICallGateProvider.cs index 333878d07..cf4c59b2e 100644 --- a/Dalamud/Plugin/Ipc/ICallGateProvider.cs +++ b/Dalamud/Plugin/Ipc/ICallGateProvider.cs @@ -1,5 +1,3 @@ -using System; - using Dalamud.Plugin.Ipc.Internal; #pragma warning disable SA1402 // File may only contain a single type diff --git a/Dalamud/Plugin/Ipc/ICallGateSubscriber.cs b/Dalamud/Plugin/Ipc/ICallGateSubscriber.cs index 94afa200a..40d642a61 100644 --- a/Dalamud/Plugin/Ipc/ICallGateSubscriber.cs +++ b/Dalamud/Plugin/Ipc/ICallGateSubscriber.cs @@ -1,5 +1,3 @@ -using System; - using Dalamud.Plugin.Ipc.Internal; #pragma warning disable SA1402 // File may only contain a single type diff --git a/Dalamud/Plugin/Ipc/Internal/DataShare.cs b/Dalamud/Plugin/Ipc/Internal/DataShare.cs index 0d3eb1a10..8ce5ddb95 100644 --- a/Dalamud/Plugin/Ipc/Internal/DataShare.cs +++ b/Dalamud/Plugin/Ipc/Internal/DataShare.cs @@ -4,6 +4,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using Dalamud.Plugin.Ipc.Exceptions; + using Serilog; namespace Dalamud.Plugin.Ipc.Internal; diff --git a/Dalamud/Plugin/Services/IAddonEventManager.cs b/Dalamud/Plugin/Services/IAddonEventManager.cs index e696bbaae..c6ec5a941 100644 --- a/Dalamud/Plugin/Services/IAddonEventManager.cs +++ b/Dalamud/Plugin/Services/IAddonEventManager.cs @@ -1,5 +1,4 @@ -using Dalamud.Game.Addon; -using Dalamud.Game.Addon.Events; +using Dalamud.Game.Addon.Events; namespace Dalamud.Plugin.Services; diff --git a/Dalamud/Plugin/Services/IAddonLifecycle.cs b/Dalamud/Plugin/Services/IAddonLifecycle.cs index 6f44349d5..ebf629b85 100644 --- a/Dalamud/Plugin/Services/IAddonLifecycle.cs +++ b/Dalamud/Plugin/Services/IAddonLifecycle.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Runtime.InteropServices; -using Dalamud.Game.Addon; using Dalamud.Game.Addon.Lifecycle; using Dalamud.Game.Addon.Lifecycle.AddonArgTypes; diff --git a/Dalamud/Plugin/Services/IBuddyList.cs b/Dalamud/Plugin/Services/IBuddyList.cs index f273d71c9..f5b9651a2 100644 --- a/Dalamud/Plugin/Services/IBuddyList.cs +++ b/Dalamud/Plugin/Services/IBuddyList.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using Dalamud.Game.ClientState.Buddy; diff --git a/Dalamud/Plugin/Services/IChatGui.cs b/Dalamud/Plugin/Services/IChatGui.cs index 24fd4e830..09f485ac2 100644 --- a/Dalamud/Plugin/Services/IChatGui.cs +++ b/Dalamud/Plugin/Services/IChatGui.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Dalamud.Game.Gui; using Dalamud.Game.Text; @@ -15,39 +15,39 @@ public interface IChatGui /// A delegate type used with the event. /// /// The type of chat. - /// The sender ID. + /// The timestamp of when the message was sent. /// The sender name. /// The message sent. /// A value indicating whether the message was handled or should be propagated. - public delegate void OnMessageDelegate(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled); + public delegate void OnMessageDelegate(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled); /// /// A delegate type used with the event. /// /// The type of chat. - /// The sender ID. + /// The timestamp of when the message was sent. /// The sender name. /// The message sent. /// A value indicating whether the message was handled or should be propagated. - public delegate void OnCheckMessageHandledDelegate(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled); + public delegate void OnCheckMessageHandledDelegate(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled); /// /// A delegate type used with the event. /// /// The type of chat. - /// The sender ID. + /// The timestamp of when the message was sent. /// The sender name. /// The message sent. - public delegate void OnMessageHandledDelegate(XivChatType type, uint senderId, SeString sender, SeString message); + public delegate void OnMessageHandledDelegate(XivChatType type, int timestamp, SeString sender, SeString message); /// /// A delegate type used with the event. /// /// The type of chat. - /// The sender ID. + /// The timestamp of when the message was sent. /// The sender name. /// The message sent. - public delegate void OnMessageUnhandledDelegate(XivChatType type, uint senderId, SeString sender, SeString message); + public delegate void OnMessageUnhandledDelegate(XivChatType type, int timestamp, SeString sender, SeString message); /// /// Event that will be fired when a chat message is sent to chat by the game. diff --git a/Dalamud/Plugin/Services/IClientState.cs b/Dalamud/Plugin/Services/IClientState.cs index 50e31fad0..95d5259e6 100644 --- a/Dalamud/Plugin/Services/IClientState.cs +++ b/Dalamud/Plugin/Services/IClientState.cs @@ -1,5 +1,3 @@ -using System; - using Dalamud.Game.ClientState.Objects.SubKinds; namespace Dalamud.Plugin.Services; diff --git a/Dalamud/Plugin/Services/IDtrBar.cs b/Dalamud/Plugin/Services/IDtrBar.cs index a5a750cf6..ae2fe560b 100644 --- a/Dalamud/Plugin/Services/IDtrBar.cs +++ b/Dalamud/Plugin/Services/IDtrBar.cs @@ -1,7 +1,8 @@ -using System; +using System.Collections.Generic; using Dalamud.Game.Gui.Dtr; using Dalamud.Game.Text.SeStringHandling; +using Dalamud.Utility; namespace Dalamud.Plugin.Services; @@ -10,6 +11,11 @@ namespace Dalamud.Plugin.Services; /// public interface IDtrBar { + /// + /// Gets a read-only list of all DTR bar entries. + /// + public IReadOnlyList Entries { get; } + /// /// Get a DTR bar entry. /// This allows you to add your own text, and users to sort it. @@ -18,6 +24,7 @@ public interface IDtrBar /// The text the entry shows. /// The entry object used to update, hide and remove the entry. /// Thrown when an entry with the specified title exists. + [Api10ToDo("Return IDtrBarEntry instead of DtrBarEntry")] public DtrBarEntry Get(string title, SeString? text = null); /// diff --git a/Dalamud/Plugin/Services/IGameConfig.cs b/Dalamud/Plugin/Services/IGameConfig.cs index c69fa906a..ed70b5753 100644 --- a/Dalamud/Plugin/Services/IGameConfig.cs +++ b/Dalamud/Plugin/Services/IGameConfig.cs @@ -1,5 +1,4 @@ using System.Diagnostics; -using System.Threading.Tasks; using Dalamud.Game.Config; using Dalamud.Plugin.Internal.Types; diff --git a/Dalamud/Plugin/Services/IGameGui.cs b/Dalamud/Plugin/Services/IGameGui.cs index ddb0ec67c..0e2da7874 100644 --- a/Dalamud/Plugin/Services/IGameGui.cs +++ b/Dalamud/Plugin/Services/IGameGui.cs @@ -1,5 +1,4 @@ -using System; -using System.Numerics; +using System.Numerics; using Dalamud.Game.Gui; using Dalamud.Game.Text.SeStringHandling.Payloads; diff --git a/Dalamud/Plugin/Services/IGameInteropProvider.cs b/Dalamud/Plugin/Services/IGameInteropProvider.cs index 217e08445..99e36c7ed 100644 --- a/Dalamud/Plugin/Services/IGameInteropProvider.cs +++ b/Dalamud/Plugin/Services/IGameInteropProvider.cs @@ -48,7 +48,7 @@ public interface IGameInteropProvider /// Callback function. Delegate must have a same original function prototype. /// The hook with the supplied parameters. /// Delegate of detour. - public Hook HookFromFunctionPointerVariable(IntPtr address, T detour) where T : Delegate; + public Hook HookFromFunctionPointerVariable(nint address, T detour) where T : Delegate; /// /// Creates a hook by rewriting import table address. @@ -85,7 +85,31 @@ public interface IGameInteropProvider /// Hooking library to use. /// The hook with the supplied parameters. /// Delegate of detour. - Hook HookFromAddress(IntPtr procAddress, T detour, HookBackend backend = HookBackend.Automatic) where T : Delegate; + Hook HookFromAddress(nint procAddress, T detour, HookBackend backend = HookBackend.Automatic) where T : Delegate; + + /// + /// Creates a hook. Hooking address is inferred by calling to GetProcAddress() function. + /// The hook is not activated until Enable() method is called. + /// Please do not use MinHook unless you have thoroughly troubleshot why Reloaded does not work. + /// + /// A memory address to install a hook. + /// Callback function. Delegate must have a same original function prototype. + /// Hooking library to use. + /// The hook with the supplied parameters. + /// Delegate of detour. + Hook HookFromAddress(nuint procAddress, T detour, HookBackend backend = HookBackend.Automatic) where T : Delegate; + + /// + /// Creates a hook. Hooking address is inferred by calling to GetProcAddress() function. + /// The hook is not activated until Enable() method is called. + /// Please do not use MinHook unless you have thoroughly troubleshot why Reloaded does not work. + /// + /// A memory address to install a hook. + /// Callback function. Delegate must have a same original function prototype. + /// Hooking library to use. + /// The hook with the supplied parameters. + /// Delegate of detour. + unsafe Hook HookFromAddress(void* procAddress, T detour, HookBackend backend = HookBackend.Automatic) where T : Delegate; /// /// Creates a hook from a signature into the Dalamud target module. diff --git a/Dalamud/Plugin/Services/IObjectTable.cs b/Dalamud/Plugin/Services/IObjectTable.cs index d8d9fdb78..bc6f9f811 100644 --- a/Dalamud/Plugin/Services/IObjectTable.cs +++ b/Dalamud/Plugin/Services/IObjectTable.cs @@ -29,9 +29,9 @@ public interface IObjectTable : IEnumerable /// /// Search for a game object by their Object ID. /// - /// Object ID to find. + /// Object ID to find. /// A game object or null. - public GameObject? SearchById(ulong objectId); + public GameObject? SearchById(ulong gameObjectId); /// /// Gets the address of the game object at the specified index of the object table. diff --git a/Dalamud/Plugin/Services/IPluginLog.cs b/Dalamud/Plugin/Services/IPluginLog.cs index aac321092..dcba5bb29 100644 --- a/Dalamud/Plugin/Services/IPluginLog.cs +++ b/Dalamud/Plugin/Services/IPluginLog.cs @@ -1,5 +1,4 @@ -using Serilog; -using Serilog.Events; +using Serilog.Events; #pragma warning disable CS1573 // See https://github.com/dotnet/roslyn/issues/40325 diff --git a/Dalamud/Plugin/Services/ISigScanner.cs b/Dalamud/Plugin/Services/ISigScanner.cs index c3bb7d6c1..1aedb01fd 100644 --- a/Dalamud/Plugin/Services/ISigScanner.cs +++ b/Dalamud/Plugin/Services/ISigScanner.cs @@ -1,5 +1,4 @@ -using System; -using System.Diagnostics; +using System.Diagnostics; namespace Dalamud.Game; diff --git a/Dalamud/Plugin/Services/ITextureProvider.cs b/Dalamud/Plugin/Services/ITextureProvider.cs index a4fa0d382..5ebcb6145 100644 --- a/Dalamud/Plugin/Services/ITextureProvider.cs +++ b/Dalamud/Plugin/Services/ITextureProvider.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection; diff --git a/Dalamud/Plugin/Services/ITitleScreenMenu.cs b/Dalamud/Plugin/Services/ITitleScreenMenu.cs index b4af06e71..9db8c70e4 100644 --- a/Dalamud/Plugin/Services/ITitleScreenMenu.cs +++ b/Dalamud/Plugin/Services/ITitleScreenMenu.cs @@ -2,7 +2,6 @@ using Dalamud.Interface; using Dalamud.Interface.Internal; -using ImGuiScene; namespace Dalamud.Plugin.Services; diff --git a/Dalamud/SafeMemory.cs b/Dalamud/SafeMemory.cs index 4b2a981bd..3365ff118 100644 --- a/Dalamud/SafeMemory.cs +++ b/Dalamud/SafeMemory.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.InteropServices; using System.Text; diff --git a/Dalamud/IServiceType.cs b/Dalamud/Service/IServiceType.cs similarity index 100% rename from Dalamud/IServiceType.cs rename to Dalamud/Service/IServiceType.cs diff --git a/Dalamud/Service/LoadingDialog.cs b/Dalamud/Service/LoadingDialog.cs new file mode 100644 index 000000000..64af02171 --- /dev/null +++ b/Dalamud/Service/LoadingDialog.cs @@ -0,0 +1,252 @@ +using System.Drawing; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; + +using Dalamud.Plugin.Internal; +using Dalamud.Utility; +using Windows.Win32.Foundation; +using Windows.Win32.UI.WindowsAndMessaging; + +namespace Dalamud; + +/// +/// Class providing an early-loading dialog. +/// +internal class LoadingDialog +{ + // TODO: We can't localize any of what's in here at the moment, because Localization is an EarlyLoadedService. + + private static int wasGloballyHidden = 0; + + private Thread? thread; + private TaskDialogButton? inProgressHideButton; + private TaskDialogPage? page; + private bool canHide; + private State currentState = State.LoadingDalamud; + private DateTime firstShowTime; + + /// + /// Enum representing the state of the dialog. + /// + public enum State + { + /// + /// Show a message stating that Dalamud is currently loading. + /// + LoadingDalamud, + + /// + /// Show a message stating that Dalamud is currently loading plugins. + /// + LoadingPlugins, + + /// + /// Show a message stating that Dalamud is currently updating plugins. + /// + AutoUpdatePlugins, + } + + /// + /// Gets or sets the current state of the dialog. + /// + public State CurrentState + { + get => this.currentState; + set + { + this.currentState = value; + this.UpdatePage(); + } + } + + /// + /// Gets or sets a value indicating whether or not the dialog can be hidden by the user. + /// + /// Thrown if called before the dialog has been created. + public bool CanHide + { + get => this.canHide; + set + { + this.canHide = value; + this.UpdatePage(); + } + } + + /// + /// Show the dialog. + /// + public void Show() + { + if (Volatile.Read(ref wasGloballyHidden) == 1) + return; + + if (this.thread?.IsAlive == true) + return; + + this.thread = new Thread(this.ThreadStart) + { + Name = "Dalamud Loading Dialog", + }; + this.thread.SetApartmentState(ApartmentState.STA); + this.thread.Start(); + + this.firstShowTime = DateTime.Now; + } + + /// + /// Hide the dialog. + /// + public void HideAndJoin() + { + if (this.thread == null || !this.thread.IsAlive) + return; + + this.inProgressHideButton?.PerformClick(); + this.thread!.Join(); + } + + private void UpdatePage() + { + if (this.page == null) + return; + + this.page.Heading = this.currentState switch + { + State.LoadingDalamud => "Dalamud is loading...", + State.LoadingPlugins => "Waiting for plugins to load...", + State.AutoUpdatePlugins => "Updating plugins...", + _ => throw new ArgumentOutOfRangeException(), + }; + + var context = string.Empty; + if (this.currentState == State.LoadingPlugins) + { + context = "\nPreparing..."; + + var tracker = Service.GetNullable()?.StartupLoadTracking; + if (tracker != null) + { + var nameString = tracker.GetPendingInternalNames() + .Select(x => tracker.GetPublicName(x)) + .Where(x => x != null) + .Aggregate(string.Empty, (acc, x) => acc + x + ", "); + + if (!nameString.IsNullOrEmpty()) + context = $"\nWaiting for: {nameString[..^2]}"; + } + } + + // Add some text if loading takes more than a few minutes + if (DateTime.Now - this.firstShowTime > TimeSpan.FromMinutes(3)) + context += "\nIt's been a while now. Please report this issue on our Discord server."; + + this.page.Text = this.currentState switch + { + State.LoadingDalamud => "Please wait while Dalamud loads...", + State.LoadingPlugins => "Please wait while Dalamud loads plugins...", + State.AutoUpdatePlugins => "Please wait while Dalamud updates your plugins...", + _ => throw new ArgumentOutOfRangeException(), +#pragma warning disable SA1513 + } + context; +#pragma warning restore SA1513 + + this.inProgressHideButton!.Enabled = this.canHide; + } + + private async Task DialogStatePeriodicUpdate(CancellationToken token) + { + using var timer = new PeriodicTimer(TimeSpan.FromMilliseconds(50)); + while (!token.IsCancellationRequested) + { + await timer.WaitForNextTickAsync(token); + this.UpdatePage(); + } + } + + private void ThreadStart() + { + Application.EnableVisualStyles(); + + this.inProgressHideButton = new TaskDialogButton("Hide", this.canHide); + + // We don't have access to the asset service here. + var workingDirectory = Service.Get().StartInfo.WorkingDirectory; + TaskDialogIcon? dialogIcon = null; + if (!workingDirectory.IsNullOrEmpty()) + { + var extractedIcon = Icon.ExtractAssociatedIcon(Path.Combine(workingDirectory, "Dalamud.Injector.exe")); + if (extractedIcon != null) + { + dialogIcon = new TaskDialogIcon(extractedIcon); + } + } + + dialogIcon ??= TaskDialogIcon.Information; + this.page = new TaskDialogPage + { + ProgressBar = new TaskDialogProgressBar(TaskDialogProgressBarState.Marquee), + Caption = "Dalamud", + Icon = dialogIcon, + Buttons = { this.inProgressHideButton }, + AllowMinimize = false, + AllowCancel = false, + Expander = new TaskDialogExpander + { + CollapsedButtonText = "What does this mean?", + ExpandedButtonText = "What does this mean?", + Text = "Some of the plugins you have installed through Dalamud are taking a long time to load.\n" + + "This is likely normal, please wait a little while longer.", + }, + SizeToContent = true, + }; + + this.UpdatePage(); + + // Call private TaskDialog ctor + var ctor = typeof(TaskDialog).GetConstructor( + BindingFlags.Instance | BindingFlags.NonPublic, + null, + Array.Empty(), + null); + + var taskDialog = (TaskDialog)ctor!.Invoke(Array.Empty())!; + + this.page.Created += (_, _) => + { + var hwnd = new HWND(taskDialog.Handle); + + // Bring to front + Windows.Win32.PInvoke.SetWindowPos(hwnd, HWND.HWND_TOPMOST, 0, 0, 0, 0, + SET_WINDOW_POS_FLAGS.SWP_NOSIZE | SET_WINDOW_POS_FLAGS.SWP_NOMOVE); + Windows.Win32.PInvoke.SetWindowPos(hwnd, HWND.HWND_NOTOPMOST, 0, 0, 0, 0, + SET_WINDOW_POS_FLAGS.SWP_SHOWWINDOW | SET_WINDOW_POS_FLAGS.SWP_NOSIZE | + SET_WINDOW_POS_FLAGS.SWP_NOMOVE); + Windows.Win32.PInvoke.SetForegroundWindow(hwnd); + Windows.Win32.PInvoke.SetFocus(hwnd); + Windows.Win32.PInvoke.SetActiveWindow(hwnd); + }; + + // Call private "ShowDialogInternal" + var showDialogInternal = typeof(TaskDialog).GetMethod( + "ShowDialogInternal", + BindingFlags.Instance | BindingFlags.NonPublic, + null, + [typeof(IntPtr), typeof(TaskDialogPage), typeof(TaskDialogStartupLocation)], + null); + + var cts = new CancellationTokenSource(); + _ = this.DialogStatePeriodicUpdate(cts.Token); + + showDialogInternal!.Invoke( + taskDialog, + [IntPtr.Zero, this.page, TaskDialogStartupLocation.CenterScreen]); + + Interlocked.Exchange(ref wasGloballyHidden, 1); + cts.Cancel(); + } +} diff --git a/Dalamud/ServiceManager.cs b/Dalamud/Service/ServiceManager.cs similarity index 95% rename from Dalamud/ServiceManager.cs rename to Dalamud/Service/ServiceManager.cs index 75daf9187..7483b0a27 100644 --- a/Dalamud/ServiceManager.cs +++ b/Dalamud/Service/ServiceManager.cs @@ -16,6 +16,8 @@ using Dalamud.Utility; using Dalamud.Utility.Timing; using JetBrains.Annotations; +// API10 TODO: Move to Dalamud.Service namespace. Some plugins reflect this... including my own, oops. There's a todo +// for more reflective APIs, so I'll just leave it for now. namespace Dalamud; // TODO: @@ -47,6 +49,8 @@ internal static class ServiceManager private static ManualResetEvent unloadResetEvent = new(false); + private static LoadingDialog loadingDialog = new(); + /// /// Delegate for registering startup blocker task.
/// Do not use this delegate outside the constructor. @@ -179,7 +183,7 @@ internal static class ServiceManager var getAsyncTaskMap = new Dictionary(); var serviceContainer = Service.Get(); - + foreach (var serviceType in GetConcreteServiceTypes()) { var serviceKind = serviceType.GetServiceKind(); @@ -238,43 +242,51 @@ internal static class ServiceManager try { // Wait for all blocking constructors to complete first. - await WaitWithTimeoutConsent(blockingEarlyLoadingServices.Select(x => getAsyncTaskMap[x])); + await WaitWithTimeoutConsent(blockingEarlyLoadingServices.Select(x => getAsyncTaskMap[x]), + LoadingDialog.State.LoadingDalamud); // All the BlockingEarlyLoadedService constructors have been run, // and blockerTasks now will not change. Now wait for them. // Note that ServiceManager.CallWhenServicesReady does not get to register a blocker. - await WaitWithTimeoutConsent(blockerTasks); + await WaitWithTimeoutConsent(blockerTasks, + LoadingDialog.State.LoadingPlugins); - BlockingServicesLoadedTaskCompletionSource.SetResult(); + Log.Verbose("=============== BLOCKINGSERVICES & TASKS INITIALIZED ==============="); Timings.Event("BlockingServices Initialized"); + BlockingServicesLoadedTaskCompletionSource.SetResult(); + loadingDialog.HideAndJoin(); } catch (Exception e) { - BlockingServicesLoadedTaskCompletionSource.SetException(e); + try + { + BlockingServicesLoadedTaskCompletionSource.SetException(e); + } + catch (InvalidOperationException) + { + // ignored, may have been set by the try/catch below + } + + Log.Error(e, "Failed resolving blocking services"); } return; - async Task WaitWithTimeoutConsent(IEnumerable tasksEnumerable) + async Task WaitWithTimeoutConsent(IEnumerable tasksEnumerable, LoadingDialog.State state) { var tasks = tasksEnumerable.AsReadOnlyCollection(); if (tasks.Count == 0) return; + + // Time we wait until showing the loading dialog + const int loadingDialogTimeout = 10000; var aggregatedTask = Task.WhenAll(tasks); - while (await Task.WhenAny(aggregatedTask, Task.Delay(120000)) != aggregatedTask) + while (await Task.WhenAny(aggregatedTask, Task.Delay(loadingDialogTimeout)) != aggregatedTask) { - if (NativeFunctions.MessageBoxW( - IntPtr.Zero, - "Dalamud is taking a long time to load. Would you like to continue without Dalamud?\n" + - "This can be caused by a faulty plugin, or a bug in Dalamud.", - "Dalamud", - NativeFunctions.MessageBoxType.IconWarning | NativeFunctions.MessageBoxType.YesNo) == 6) - { - throw new TimeoutException( - "Failed to load services in the given time limit, " + - "and the user chose to continue without Dalamud."); - } + loadingDialog.Show(); + loadingDialog.CanHide = true; + loadingDialog.CurrentState = state; } } }).ConfigureAwait(false); @@ -387,6 +399,7 @@ internal static class ServiceManager try { BlockingServicesLoadedTaskCompletionSource.SetException(e); + loadingDialog.HideAndJoin(); } catch (Exception) { diff --git a/Dalamud/Service{T}.cs b/Dalamud/Service/Service{T}.cs similarity index 99% rename from Dalamud/Service{T}.cs rename to Dalamud/Service/Service{T}.cs index a4d404e18..b1e6e1eda 100644 --- a/Dalamud/Service{T}.cs +++ b/Dalamud/Service/Service{T}.cs @@ -8,6 +8,7 @@ using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Utility; using Dalamud.Utility.Timing; + using JetBrains.Annotations; namespace Dalamud; diff --git a/Dalamud/Support/Troubleshooting.cs b/Dalamud/Support/Troubleshooting.cs index 59ebcaa16..3ba088c66 100644 --- a/Dalamud/Support/Troubleshooting.cs +++ b/Dalamud/Support/Troubleshooting.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Dalamud/Utility/AsyncUtils.cs b/Dalamud/Utility/AsyncUtils.cs index d02c90195..9533f2ab0 100644 --- a/Dalamud/Utility/AsyncUtils.cs +++ b/Dalamud/Utility/AsyncUtils.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; diff --git a/Dalamud/Utility/Hash.cs b/Dalamud/Utility/Hash.cs index a8296315e..08fc78901 100644 --- a/Dalamud/Utility/Hash.cs +++ b/Dalamud/Utility/Hash.cs @@ -1,5 +1,4 @@ -using System; -using System.Security.Cryptography; +using System.Security.Cryptography; namespace Dalamud.Utility; diff --git a/Dalamud/Utility/HitchDetector.cs b/Dalamud/Utility/HitchDetector.cs index d749ec25d..0a5704584 100644 --- a/Dalamud/Utility/HitchDetector.cs +++ b/Dalamud/Utility/HitchDetector.cs @@ -1,5 +1,4 @@ -using System; -using System.Diagnostics; +using System.Diagnostics; using Serilog; diff --git a/Dalamud/Utility/MapUtil.cs b/Dalamud/Utility/MapUtil.cs index 2ed3dfad1..d71af9987 100644 --- a/Dalamud/Utility/MapUtil.cs +++ b/Dalamud/Utility/MapUtil.cs @@ -5,7 +5,6 @@ using Dalamud.Game.ClientState.Objects.Types; using FFXIVClientStructs.FFXIV.Client.UI.Agent; -using Lumina; using Lumina.Excel.GeneratedSheets; namespace Dalamud.Utility; diff --git a/Dalamud/Utility/ScopedSyncRoot.cs b/Dalamud/Utility/ScopedSyncRoot.cs index 724581f3f..cacfa4160 100644 --- a/Dalamud/Utility/ScopedSyncRoot.cs +++ b/Dalamud/Utility/ScopedSyncRoot.cs @@ -1,5 +1,4 @@ -using System; -using System.Threading; +using System.Threading; namespace Dalamud.Utility; diff --git a/Dalamud/Utility/Signatures/NullabilityUtil.cs b/Dalamud/Utility/Signatures/NullabilityUtil.cs index 9db1117cc..da4b24db6 100755 --- a/Dalamud/Utility/Signatures/NullabilityUtil.cs +++ b/Dalamud/Utility/Signatures/NullabilityUtil.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Reflection; diff --git a/Dalamud/Utility/Signatures/SignatureAttribute.cs b/Dalamud/Utility/Signatures/SignatureAttribute.cs index e4831fd8d..35e77b695 100755 --- a/Dalamud/Utility/Signatures/SignatureAttribute.cs +++ b/Dalamud/Utility/Signatures/SignatureAttribute.cs @@ -1,6 +1,4 @@ -using System; - -using JetBrains.Annotations; +using JetBrains.Annotations; namespace Dalamud.Utility.Signatures; diff --git a/Dalamud/Utility/Signatures/SignatureException.cs b/Dalamud/Utility/Signatures/SignatureException.cs index ea7cef396..7a3ad2085 100755 --- a/Dalamud/Utility/Signatures/SignatureException.cs +++ b/Dalamud/Utility/Signatures/SignatureException.cs @@ -1,6 +1,4 @@ -using System; - -namespace Dalamud.Utility.Signatures; +namespace Dalamud.Utility.Signatures; /// /// An exception for signatures. diff --git a/Dalamud/Utility/Signatures/SignatureHelper.cs b/Dalamud/Utility/Signatures/SignatureHelper.cs index bd90a0d13..cdf601852 100755 --- a/Dalamud/Utility/Signatures/SignatureHelper.cs +++ b/Dalamud/Utility/Signatures/SignatureHelper.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -7,7 +6,6 @@ using System.Runtime.InteropServices; using Dalamud.Game; using Dalamud.Hooking; using Dalamud.Logging; -using Dalamud.Plugin.Services; using Dalamud.Utility.Signatures.Wrappers; using Serilog; diff --git a/Dalamud/Utility/Signatures/SignatureUseFlags.cs b/Dalamud/Utility/Signatures/SignatureUseFlags.cs index f952bc00e..08f7e7b3a 100755 --- a/Dalamud/Utility/Signatures/SignatureUseFlags.cs +++ b/Dalamud/Utility/Signatures/SignatureUseFlags.cs @@ -1,6 +1,4 @@ -using System; - -using Dalamud.Hooking; +using Dalamud.Hooking; namespace Dalamud.Utility.Signatures; diff --git a/Dalamud/Utility/Signatures/Wrappers/FieldInfoWrapper.cs b/Dalamud/Utility/Signatures/Wrappers/FieldInfoWrapper.cs index 79233eae2..6024d1301 100755 --- a/Dalamud/Utility/Signatures/Wrappers/FieldInfoWrapper.cs +++ b/Dalamud/Utility/Signatures/Wrappers/FieldInfoWrapper.cs @@ -1,4 +1,3 @@ -using System; using System.Reflection; namespace Dalamud.Utility.Signatures.Wrappers; diff --git a/Dalamud/Utility/Signatures/Wrappers/IFieldOrPropertyInfo.cs b/Dalamud/Utility/Signatures/Wrappers/IFieldOrPropertyInfo.cs index 7690f86ec..76e32da28 100755 --- a/Dalamud/Utility/Signatures/Wrappers/IFieldOrPropertyInfo.cs +++ b/Dalamud/Utility/Signatures/Wrappers/IFieldOrPropertyInfo.cs @@ -1,5 +1,3 @@ -using System; - namespace Dalamud.Utility.Signatures.Wrappers; /// diff --git a/Dalamud/Utility/Signatures/Wrappers/PropertyInfoWrapper.cs b/Dalamud/Utility/Signatures/Wrappers/PropertyInfoWrapper.cs index 280e0c012..5fcc8ccb8 100755 --- a/Dalamud/Utility/Signatures/Wrappers/PropertyInfoWrapper.cs +++ b/Dalamud/Utility/Signatures/Wrappers/PropertyInfoWrapper.cs @@ -1,5 +1,4 @@ -using System; -using System.Reflection; +using System.Reflection; namespace Dalamud.Utility.Signatures.Wrappers; diff --git a/Dalamud/Utility/ThreadSafety.cs b/Dalamud/Utility/ThreadSafety.cs index ce3ddc602..ea8238d44 100644 --- a/Dalamud/Utility/ThreadSafety.cs +++ b/Dalamud/Utility/ThreadSafety.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.CompilerServices; namespace Dalamud.Utility; diff --git a/Dalamud/Utility/ThrowHelper.cs b/Dalamud/Utility/ThrowHelper.cs index 647aa92c0..279fda5c8 100644 --- a/Dalamud/Utility/ThrowHelper.cs +++ b/Dalamud/Utility/ThrowHelper.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; namespace Dalamud.Utility diff --git a/Dalamud/Utility/Timing/TimingHandle.cs b/Dalamud/Utility/Timing/TimingHandle.cs index e06836c8a..d73a9c2d3 100644 --- a/Dalamud/Utility/Timing/TimingHandle.cs +++ b/Dalamud/Utility/Timing/TimingHandle.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; diff --git a/Dalamud/Utility/Timing/Timings.cs b/Dalamud/Utility/Timing/Timings.cs index 0709be4e7..e2c00461c 100644 --- a/Dalamud/Utility/Timing/Timings.cs +++ b/Dalamud/Utility/Timing/Timings.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; diff --git a/Dalamud/Utility/Util.cs b/Dalamud/Utility/Util.cs index 617166610..2f6b4fb4a 100644 --- a/Dalamud/Utility/Util.cs +++ b/Dalamud/Utility/Util.cs @@ -19,12 +19,11 @@ using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Interface.Colors; using Dalamud.Interface.Utility; + using ImGuiNET; using Lumina.Excel.GeneratedSheets; using Serilog; - using TerraFX.Interop.Windows; - using Windows.Win32.Storage.FileSystem; namespace Dalamud.Utility; @@ -477,12 +476,12 @@ public static class Util case "MacOS": return OSPlatform.OSX; case "Linux": return OSPlatform.Linux; } - + // n.b. we had some fancy code here to check if the Wine host version returned "Darwin" but apparently // *all* our Wines report Darwin if exports aren't hidden. As such, it is effectively impossible (without some // (very cursed and inaccurate heuristics) to determine if we're on macOS or Linux unless we're explicitly told // by our launcher. See commit a7aacb15e4603a367e2f980578271a9a639d8852 for the old check. - + return IsWine() ? OSPlatform.Linux : OSPlatform.Windows; } @@ -545,7 +544,7 @@ public static class Util } } } - } + } finally { foreach (var enumerator in enumerators) @@ -586,7 +585,7 @@ public static class Util { WriteAllTextSafe(path, text, Encoding.UTF8); } - + /// /// Overwrite text in a file by first writing it to a temporary file, and then /// moving that file to the path specified. @@ -598,7 +597,7 @@ public static class Util { WriteAllBytesSafe(path, encoding.GetBytes(text)); } - + /// /// Overwrite data in a file by first writing it to a temporary file, and then /// moving that file to the path specified. @@ -608,13 +607,13 @@ public static class Util public static unsafe void WriteAllBytesSafe(string path, byte[] bytes) { ArgumentException.ThrowIfNullOrEmpty(path); - + // Open the temp file var tempPath = path + ".tmp"; using var tempFile = Windows.Win32.PInvoke.CreateFile( - tempPath, - (uint)(FILE_ACCESS_RIGHTS.FILE_GENERIC_READ | FILE_ACCESS_RIGHTS.FILE_GENERIC_WRITE), + tempPath, + (uint)(FILE_ACCESS_RIGHTS.FILE_GENERIC_READ | FILE_ACCESS_RIGHTS.FILE_GENERIC_WRITE), FILE_SHARE_MODE.FILE_SHARE_NONE, null, FILE_CREATION_DISPOSITION.CREATE_ALWAYS, @@ -623,7 +622,7 @@ public static class Util if (tempFile.IsInvalid) throw new Win32Exception(); - + // Write the data uint bytesWritten = 0; if (!Windows.Win32.PInvoke.WriteFile(tempFile, new ReadOnlySpan(bytes), &bytesWritten, null)) @@ -634,7 +633,7 @@ public static class Util if (!Windows.Win32.PInvoke.FlushFileBuffers(tempFile)) throw new Win32Exception(); - + tempFile.Close(); if (!Windows.Win32.PInvoke.MoveFileEx(tempPath, path, MOVE_FILE_FLAGS.MOVEFILE_REPLACE_EXISTING | MOVE_FILE_FLAGS.MOVEFILE_WRITE_THROUGH)) @@ -721,7 +720,7 @@ public static class Util 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"; + $"{actor.Address.ToInt64():X}:{actor.GameObjectId: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"; @@ -760,7 +759,7 @@ public static class Util "-", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, - null, + null, new[] { typeof(object), typeof(IList), typeof(ulong) }, obj.GetType(), true); @@ -917,7 +916,7 @@ public static class Util } } } - + /// /// Show a structure in an ImGui context. /// diff --git a/lib/FFXIVClientStructs b/lib/FFXIVClientStructs index 1ea76af5c..d0cbe19f1 160000 --- a/lib/FFXIVClientStructs +++ b/lib/FFXIVClientStructs @@ -1 +1 @@ -Subproject commit 1ea76af5c796e0d84e23e07207cee9e78dd8bd02 +Subproject commit d0cbe19f145bcae573a1eb2313f1f8240f869cd7