diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj index 3502d1bc0..869faf2da 100644 --- a/Dalamud/Dalamud.csproj +++ b/Dalamud/Dalamud.csproj @@ -84,11 +84,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - - diff --git a/Dalamud/EntryPoint.cs b/Dalamud/EntryPoint.cs index 54e25b6f2..d9f6ef172 100644 --- a/Dalamud/EntryPoint.cs +++ b/Dalamud/EntryPoint.cs @@ -192,8 +192,8 @@ public sealed class EntryPoint var dalamud = new Dalamud(info, fs, configuration, mainThreadContinueEvent); Log.Information("This is Dalamud - Core: {GitHash}, CS: {CsGitHash} [{CsVersion}]", - Util.GetScmVersion(), - Util.GetGitHashClientStructs(), + Versioning.GetScmVersion(), + Versioning.GetGitHashClientStructs(), FFXIVClientStructs.ThisAssembly.Git.Commits); dalamud.WaitForUnload(); diff --git a/Dalamud/Game/ChatHandlers.cs b/Dalamud/Game/ChatHandlers.cs index b1b798a8a..279bf46e5 100644 --- a/Dalamud/Game/ChatHandlers.cs +++ b/Dalamud/Game/ChatHandlers.cs @@ -104,7 +104,7 @@ internal partial class ChatHandlers : IServiceType if (this.configuration.PrintDalamudWelcomeMsg) { - chatGui.Print(string.Format(Loc.Localize("DalamudWelcome", "Dalamud {0} loaded."), Util.GetScmVersion()) + chatGui.Print(string.Format(Loc.Localize("DalamudWelcome", "Dalamud {0} loaded."), Versioning.GetScmVersion()) + string.Format(Loc.Localize("PluginsWelcome", " {0} plugin(s) loaded."), pluginManager.InstalledPlugins.Count(x => x.IsLoaded))); } @@ -116,7 +116,7 @@ internal partial class ChatHandlers : IServiceType } } - if (string.IsNullOrEmpty(this.configuration.LastVersion) || !Util.AssemblyVersion.StartsWith(this.configuration.LastVersion)) + if (string.IsNullOrEmpty(this.configuration.LastVersion) || !Versioning.GetAssemblyVersion().StartsWith(this.configuration.LastVersion)) { var linkPayload = chatGui.AddChatLinkHandler( (_, _) => dalamudInterface.OpenPluginInstallerTo(PluginInstallerOpenKind.Changelogs)); @@ -137,7 +137,7 @@ internal partial class ChatHandlers : IServiceType Type = XivChatType.Notice, }); - this.configuration.LastVersion = Util.AssemblyVersion; + this.configuration.LastVersion = Versioning.GetAssemblyVersion(); this.configuration.QueueSave(); } diff --git a/Dalamud/Game/Gui/FlyText/FlyTextKind.cs b/Dalamud/Game/Gui/FlyText/FlyTextKind.cs index 2b8325927..da448c683 100644 --- a/Dalamud/Game/Gui/FlyText/FlyTextKind.cs +++ b/Dalamud/Game/Gui/FlyText/FlyTextKind.cs @@ -92,34 +92,16 @@ public enum FlyTextKind : int /// IslandExp = 15, - /// - /// Val1 in serif font next to all caps condensed font Text1 with Text2 in sans-serif as subtitle. - /// - [Obsolete("Use Dataset instead", true)] - Unknown16 = 16, - /// /// Val1 in serif font next to all caps condensed font Text1 with Text2 in sans-serif as subtitle. /// Dataset = 16, - /// - /// Val1 in serif font, Text2 in sans-serif as subtitle. - /// - [Obsolete("Use Knowledge instead", true)] - Unknown17 = 17, - /// /// Val1 in serif font, Text2 in sans-serif as subtitle. /// Knowledge = 17, - /// - /// Val1 in serif font, Text2 in sans-serif as subtitle. - /// - [Obsolete("Use PhantomExp instead", true)] - Unknown18 = 18, - /// /// Val1 in serif font, Text2 in sans-serif as subtitle. /// diff --git a/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringRenderer.cs b/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringRenderer.cs index 4a8e6517e..f161c1868 100644 --- a/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringRenderer.cs +++ b/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringRenderer.cs @@ -162,8 +162,7 @@ internal class SeStringRenderer : IServiceType if (drawParams.Font.HasValue) font = drawParams.Font.Value; - // API14: Remove commented out code - if (ThreadSafety.IsMainThread /* && drawParams.TargetDrawList is null */ && font is null) + if (ThreadSafety.IsMainThread && drawParams.TargetDrawList is null && font is null) font = ImGui.GetFont(); if (font is null) throw new ArgumentException("Specified font is empty."); diff --git a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs index 5edf60e9d..dcbe123e7 100644 --- a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs +++ b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs @@ -66,17 +66,10 @@ public unsafe ref struct SeStringDrawState : IDisposable this.drawList = ssdp.TargetDrawList.Value; this.ScreenOffset = ssdp.ScreenOffset ?? Vector2.Zero; - // API14: Remove, always throw - if (ThreadSafety.IsMainThread) - { - this.ScreenOffset = ssdp.ScreenOffset ?? ImGui.GetCursorScreenPos(); - this.FontSize = ssdp.FontSize ?? ImGui.GetFontSize(); - } - else - { - throw new ArgumentException( - $"{nameof(ssdp.FontSize)} must be set when specifying a target draw list, as it cannot be fetched from the ImGui state."); - } + this.ScreenOffset = ssdp.ScreenOffset ?? throw new ArgumentException( + $"{nameof(ssdp.ScreenOffset)} must be set when specifying a target draw list, as it cannot be fetched from the ImGui state. (GetCursorScreenPos?)"); + this.FontSize = ssdp.FontSize ?? throw new ArgumentException( + $"{nameof(ssdp.FontSize)} must be set when specifying a target draw list, as it cannot be fetched from the ImGui state."); // this.FontSize = ssdp.FontSize ?? throw new ArgumentException( // $"{nameof(ssdp.FontSize)} must be set when specifying a target draw list, as it cannot be fetched from the ImGui state."); diff --git a/Dalamud/Interface/Internal/DalamudCommands.cs b/Dalamud/Interface/Internal/DalamudCommands.cs index b1fdb5232..3e4a5cec6 100644 --- a/Dalamud/Interface/Internal/DalamudCommands.cs +++ b/Dalamud/Interface/Internal/DalamudCommands.cs @@ -305,12 +305,12 @@ internal class DalamudCommands : IServiceType chatGui.Print(new SeStringBuilder() .AddItalics("Dalamud:") - .AddText($" {Util.GetScmVersion()}") + .AddText($" {Versioning.GetScmVersion()}") .Build()); chatGui.Print(new SeStringBuilder() .AddItalics("FFXIVCS:") - .AddText($" {Util.GetGitHashClientStructs()}") + .AddText($" {Versioning.GetGitHashClientStructs()}") .Build()); } diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs index b0fbeb6c5..be4228a81 100644 --- a/Dalamud/Interface/Internal/DalamudInterface.cs +++ b/Dalamud/Interface/Internal/DalamudInterface.cs @@ -182,7 +182,7 @@ internal class DalamudInterface : IInternalDisposableService () => Service.GetNullable()?.ToggleDevMenu(), VirtualKey.SHIFT); - if (Util.GetActiveTrack() != "release") + if (Versioning.GetActiveTrack() != "release") { titleScreenMenu.AddEntryCore( Loc.Localize("TSMDalamudDevMenu", "Developer Menu"), @@ -865,7 +865,7 @@ internal class DalamudInterface : IInternalDisposableService } ImGui.MenuItem(this.dalamud.StartInfo.GameVersion?.ToString() ?? "Unknown version", false, false); - ImGui.MenuItem($"D: {Util.GetScmVersion()} CS: {Util.GetGitHashClientStructs()}[{FFXIVClientStructs.ThisAssembly.Git.Commits}]", false, false); + ImGui.MenuItem($"D: {Versioning.GetScmVersion()} CS: {Versioning.GetGitHashClientStructs()}[{FFXIVClientStructs.ThisAssembly.Git.Commits}]", false, false); ImGui.MenuItem($"CLR: {Environment.Version}", false, false); ImGui.EndMenu(); @@ -1076,8 +1076,8 @@ internal class DalamudInterface : IInternalDisposableService { ImGui.PushFont(InterfaceManager.MonoFont); - ImGui.BeginMenu($"{Util.GetActiveTrack() ?? "???"} on {Util.GetGitBranch() ?? "???"}", false); - ImGui.BeginMenu($"{Util.GetScmVersion()}", false); + ImGui.BeginMenu($"{Versioning.GetActiveTrack() ?? "???"} on {Versioning.GetGitBranch() ?? "???"}", false); + ImGui.BeginMenu($"{Versioning.GetScmVersion()}", false); ImGui.BeginMenu(this.FrameCount.ToString("000000"), false); ImGui.BeginMenu(ImGui.GetIO().Framerate.ToString("000"), false); ImGui.BeginMenu($"W:{Util.FormatBytes(GC.GetTotalMemory(false))}", false); diff --git a/Dalamud/Interface/Internal/Windows/BranchSwitcherWindow.cs b/Dalamud/Interface/Internal/Windows/BranchSwitcherWindow.cs index 9cc14ea14..51a9c48a6 100644 --- a/Dalamud/Interface/Internal/Windows/BranchSwitcherWindow.cs +++ b/Dalamud/Interface/Internal/Windows/BranchSwitcherWindow.cs @@ -47,7 +47,7 @@ public class BranchSwitcherWindow : Window this.branches = await client.GetFromJsonAsync>(BranchInfoUrl); Debug.Assert(this.branches != null, "this.branches != null"); - var trackName = Util.GetActiveTrack(); + var trackName = Versioning.GetActiveTrack(); this.selectedBranchIndex = this.branches.IndexOf(x => x.Value.Track == trackName); if (this.selectedBranchIndex == -1) { diff --git a/Dalamud/Interface/Internal/Windows/ChangelogWindow.cs b/Dalamud/Interface/Internal/Windows/ChangelogWindow.cs index b0a910ead..44626ba31 100644 --- a/Dalamud/Interface/Internal/Windows/ChangelogWindow.cs +++ b/Dalamud/Interface/Internal/Windows/ChangelogWindow.cs @@ -147,7 +147,7 @@ internal sealed class ChangelogWindow : Window, IDisposable var pmWantsChangelog = pm?.InstalledPlugins.Any() ?? true; return (string.IsNullOrEmpty(configuration.LastChangelogMajorMinor) || (!WarrantsChangelogForMajorMinor.StartsWith(configuration.LastChangelogMajorMinor) && - Util.AssemblyVersion.StartsWith(WarrantsChangelogForMajorMinor))) && pmWantsChangelog; + Versioning.GetAssemblyVersion().StartsWith(WarrantsChangelogForMajorMinor))) && pmWantsChangelog; } /// @@ -357,7 +357,7 @@ internal sealed class ChangelogWindow : Window, IDisposable { case State.WindowFadeIn: case State.ExplainerIntro: - ImGui.TextWrapped($"Welcome to Dalamud v{Util.GetScmVersion()}!"); + ImGui.TextWrapped($"Welcome to Dalamud v{Versioning.GetScmVersion()}!"); ImGuiHelpers.ScaledDummy(5); ImGui.TextWrapped(ChangeLog); ImGuiHelpers.ScaledDummy(5); diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/PluginIpcWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/PluginIpcWidget.cs index 0ca754a91..1f1f82cdd 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/PluginIpcWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/PluginIpcWidget.cs @@ -48,12 +48,20 @@ internal class PluginIpcWidget : IDataWindowWidget this.ipcPub.RegisterAction(msg => { - Log.Information("Data action was called: {Msg}", msg); + Log.Information( + "Data action was called: {Msg}\n" + + " Context: {Context}", + msg, + this.ipcPub.GetContext()); }); this.ipcPub.RegisterFunc(msg => { - Log.Information("Data func was called: {Msg}", msg); + Log.Information( + "Data func was called: {Msg}\n" + + " Context: {Context}", + msg, + this.ipcPub.GetContext()); return Guid.NewGuid().ToString(); }); } @@ -61,14 +69,8 @@ internal class PluginIpcWidget : IDataWindowWidget if (this.ipcSub == null) { this.ipcSub = new CallGatePubSub("dataDemo1"); - this.ipcSub.Subscribe(_ => - { - Log.Information("PONG1"); - }); - this.ipcSub.Subscribe(_ => - { - Log.Information("PONG2"); - }); + this.ipcSub.Subscribe(_ => { Log.Information("PONG1"); }); + this.ipcSub.Subscribe(_ => { Log.Information("PONG2"); }); this.ipcSub.Subscribe(_ => throw new Exception("PONG3")); } @@ -78,12 +80,21 @@ internal class PluginIpcWidget : IDataWindowWidget this.ipcPubGo.RegisterAction(go => { - Log.Information("Data action was called: {Name}", go?.Name); + Log.Information( + "Data action was called: {Name}" + + "\n Context: {Context}", + go?.Name, + this.ipcPubGo.GetContext()); }); this.ipcPubGo.RegisterFunc(go => { - Log.Information("Data func was called: {Name}", go?.Name); + Log.Information( + "Data func was called: {Name}\n" + + " Context: {Context}", + go?.Name, + this.ipcPubGo.GetContext()); + return "test"; }); } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/SeStringCreatorWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/SeStringCreatorWidget.cs index a88f576f9..e9b4022e4 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/SeStringCreatorWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/SeStringCreatorWidget.cs @@ -144,7 +144,7 @@ internal class SeStringCreatorWidget : IDataWindowWidget new TextEntry(TextEntryType.Macro, " "), ]; - private SeStringParameter[]? localParameters = [Util.GetScmVersion()]; + private SeStringParameter[]? localParameters = [Versioning.GetScmVersion()]; private ReadOnlySeString input; private ClientLanguage? language; private Task? validImportSheetNamesTask; diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs index ac092bd25..3241015fc 100644 --- a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs +++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs @@ -302,7 +302,7 @@ internal class PluginInstallerWindow : Window, IDisposable this.profileManagerWidget.Reset(); - if (this.staleDalamudNewVersion == null && !Util.GetActiveTrack().IsNullOrEmpty()) + if (this.staleDalamudNewVersion == null && !Versioning.GetActiveTrack().IsNullOrEmpty()) { Service.Get().GetVersionForCurrentTrack().ContinueWith(t => { @@ -310,7 +310,7 @@ internal class PluginInstallerWindow : Window, IDisposable return; var versionInfo = t.Result; - if (versionInfo.AssemblyVersion != Util.GetScmVersion()) + if (versionInfo.AssemblyVersion != Versioning.GetScmVersion()) { this.staleDalamudNewVersion = versionInfo.AssemblyVersion; } @@ -1670,7 +1670,7 @@ internal class PluginInstallerWindow : Window, IDisposable DrawWarningIcon(); DrawLinesCentered("A new version of Dalamud is available.\n" + "Please restart the game to ensure compatibility with updated plugins.\n" + - $"old: {Util.GetScmVersion()} new: {this.staleDalamudNewVersion}"); + $"old: {Versioning.GetScmVersion()} new: {this.staleDalamudNewVersion}"); ImGuiHelpers.ScaledDummy(10); } @@ -2461,7 +2461,7 @@ internal class PluginInstallerWindow : Window, IDisposable var isOutdated = effectiveApiLevel < PluginManager.DalamudApiLevel; var isIncompatible = manifest.MinimumDalamudVersion != null && - manifest.MinimumDalamudVersion > Util.AssemblyVersionParsed; + manifest.MinimumDalamudVersion > Versioning.GetAssemblyVersionParsed(); var enableInstallButton = this.updateStatus != OperationStatus.InProgress && this.installStatus != OperationStatus.InProgress && diff --git a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabAbout.cs b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabAbout.cs index 74b9b0fd7..4785ceb3c 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabAbout.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabAbout.cs @@ -223,7 +223,7 @@ Contribute at: https://github.com/goatcorp/Dalamud .Select(plugin => $"{plugin.Manifest.Name} by {plugin.Manifest.Author}\n") .Aggregate(string.Empty, (current, next) => $"{current}{next}"); - this.creditsText = string.Format(CreditsTextTempl, typeof(Dalamud).Assembly.GetName().Version, pluginCredits, Util.GetGitHashClientStructs()); + this.creditsText = string.Format(CreditsTextTempl, typeof(Dalamud).Assembly.GetName().Version, pluginCredits, Versioning.GetGitHashClientStructs()); var gameGui = Service.Get(); var playerState = PlayerState.Instance(); diff --git a/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs b/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs index 69cdc4d28..e14dbc545 100644 --- a/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs +++ b/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs @@ -503,7 +503,7 @@ internal class TitleScreenMenuWindow : Window, IDisposable lssb.PushEdgeColorType(701).PushColorType(539) .Append(SeIconChar.BoxedLetterD.ToIconChar()) .PopColorType().PopEdgeColorType(); - lssb.Append($" Dalamud: {Util.GetScmVersion()}"); + lssb.Append($" Dalamud: {Versioning.GetScmVersion()}"); lssb.Append($" - {count} {(count != 1 ? "plugins" : "plugin")} loaded"); diff --git a/Dalamud/Networking/Http/HappyHttpClient.cs b/Dalamud/Networking/Http/HappyHttpClient.cs index aeed98695..c6a476fff 100644 --- a/Dalamud/Networking/Http/HappyHttpClient.cs +++ b/Dalamud/Networking/Http/HappyHttpClient.cs @@ -36,7 +36,7 @@ internal class HappyHttpClient : IInternalDisposableService { UserAgent = { - new ProductInfoHeaderValue("Dalamud", Util.AssemblyVersion), + new ProductInfoHeaderValue("Dalamud", Versioning.GetAssemblyVersion()), }, }, }; diff --git a/Dalamud/Networking/Rpc/Service/ClientHelloService.cs b/Dalamud/Networking/Rpc/Service/ClientHelloService.cs index c5a4c851a..ae8319f21 100644 --- a/Dalamud/Networking/Rpc/Service/ClientHelloService.cs +++ b/Dalamud/Networking/Rpc/Service/ClientHelloService.cs @@ -38,7 +38,7 @@ internal sealed class ClientHelloService : IInternalDisposableService return new ClientHelloResponse { ApiVersion = "1.0", - DalamudVersion = Util.GetScmVersion(), + DalamudVersion = Versioning.GetScmVersion(), GameVersion = dalamud.StartInfo.GameVersion?.ToString() ?? "Unknown", ProcessId = Environment.ProcessId, ProcessStartTime = new DateTimeOffset(Process.GetCurrentProcess().StartTime).ToUnixTimeSeconds(), diff --git a/Dalamud/Plugin/DalamudPluginInterface.cs b/Dalamud/Plugin/DalamudPluginInterface.cs index 6fd9064b6..90850a08b 100644 --- a/Dalamud/Plugin/DalamudPluginInterface.cs +++ b/Dalamud/Plugin/DalamudPluginInterface.cs @@ -16,18 +16,15 @@ using Dalamud.Game.Text; using Dalamud.Game.Text.Sanitizer; using Dalamud.Interface; using Dalamud.Interface.Internal; -using Dalamud.Interface.Internal.Windows.PluginInstaller; -using Dalamud.Interface.Internal.Windows.SelfTest; -using Dalamud.Interface.Internal.Windows.Settings; using Dalamud.IoC.Internal; using Dalamud.Plugin.Internal; using Dalamud.Plugin.Internal.AutoUpdate; using Dalamud.Plugin.Internal.Types; using Dalamud.Plugin.Internal.Types.Manifest; using Dalamud.Plugin.Ipc; -using Dalamud.Plugin.Ipc.Exceptions; using Dalamud.Plugin.Ipc.Internal; -using Dalamud.Plugin.Services; +using Dalamud.Plugin.VersionInfo; +using Dalamud.Utility; using Serilog; @@ -204,11 +201,7 @@ internal sealed class DalamudPluginInterface : IDalamudPluginInterface, IDisposa return true; } - /// - /// Gets the plugin the given assembly is part of. - /// - /// The assembly to check. - /// The plugin the given assembly is part of, or null if this is a shared assembly or if this information cannot be determined. + /// public IExposedPlugin? GetPlugin(Assembly assembly) => AssemblyLoadContext.GetLoadContext(assembly) switch { @@ -216,11 +209,7 @@ internal sealed class DalamudPluginInterface : IDalamudPluginInterface, IDisposa var context => this.GetPlugin(context), }; - /// - /// Gets the plugin that loads in the given context. - /// - /// The context to check. - /// The plugin that loads in the given context, or null if this isn't a plugin's context or if this information cannot be determined. + /// public IExposedPlugin? GetPlugin(AssemblyLoadContext context) => Service.Get().InstalledPlugins.FirstOrDefault(p => p.LoadsIn(context)) switch { @@ -228,6 +217,12 @@ internal sealed class DalamudPluginInterface : IDalamudPluginInterface, IDisposa var p => new ExposedPlugin(p), }; + /// + public IDalamudVersionInfo GetDalamudVersion() + { + return new DalamudVersionInfo(Versioning.GetAssemblyVersionParsed(), Versioning.GetActiveTrack()); + } + #region IPC /// @@ -248,75 +243,75 @@ internal sealed class DalamudPluginInterface : IDalamudPluginInterface, IDisposa /// public ICallGateProvider GetIpcProvider(string name) - => new CallGatePubSub(name); + => new CallGatePubSub(name, this.plugin); /// public ICallGateProvider GetIpcProvider(string name) - => new CallGatePubSub(name); + => new CallGatePubSub(name, this.plugin); /// public ICallGateProvider GetIpcProvider(string name) - => new CallGatePubSub(name); + => new CallGatePubSub(name, this.plugin); /// public ICallGateProvider GetIpcProvider(string name) - => new CallGatePubSub(name); + => new CallGatePubSub(name, this.plugin); /// public ICallGateProvider GetIpcProvider(string name) - => new CallGatePubSub(name); + => new CallGatePubSub(name, this.plugin); /// public ICallGateProvider GetIpcProvider(string name) - => new CallGatePubSub(name); + => new CallGatePubSub(name, this.plugin); /// public ICallGateProvider GetIpcProvider(string name) - => new CallGatePubSub(name); + => new CallGatePubSub(name, this.plugin); /// public ICallGateProvider GetIpcProvider(string name) - => new CallGatePubSub(name); + => new CallGatePubSub(name, this.plugin); /// public ICallGateProvider GetIpcProvider(string name) - => new CallGatePubSub(name); + => new CallGatePubSub(name, this.plugin); /// public ICallGateSubscriber GetIpcSubscriber(string name) - => new CallGatePubSub(name); + => new CallGatePubSub(name, this.plugin); /// public ICallGateSubscriber GetIpcSubscriber(string name) - => new CallGatePubSub(name); + => new CallGatePubSub(name, this.plugin); /// public ICallGateSubscriber GetIpcSubscriber(string name) - => new CallGatePubSub(name); + => new CallGatePubSub(name, this.plugin); /// public ICallGateSubscriber GetIpcSubscriber(string name) - => new CallGatePubSub(name); + => new CallGatePubSub(name, this.plugin); /// public ICallGateSubscriber GetIpcSubscriber(string name) - => new CallGatePubSub(name); + => new CallGatePubSub(name, this.plugin); /// public ICallGateSubscriber GetIpcSubscriber(string name) - => new CallGatePubSub(name); + => new CallGatePubSub(name, this.plugin); /// public ICallGateSubscriber GetIpcSubscriber(string name) - => new CallGatePubSub(name); + => new CallGatePubSub(name, this.plugin); /// public ICallGateSubscriber GetIpcSubscriber(string name) - => new CallGatePubSub(name); + => new CallGatePubSub(name, this.plugin); /// public ICallGateSubscriber GetIpcSubscriber(string name) - => new CallGatePubSub(name); + => new CallGatePubSub(name, this.plugin); #endregion diff --git a/Dalamud/Plugin/IDalamudPluginInterface.cs b/Dalamud/Plugin/IDalamudPluginInterface.cs index d1b6977d4..92ecab006 100644 --- a/Dalamud/Plugin/IDalamudPluginInterface.cs +++ b/Dalamud/Plugin/IDalamudPluginInterface.cs @@ -15,7 +15,7 @@ using Dalamud.Plugin.Internal.Types.Manifest; using Dalamud.Plugin.Ipc; using Dalamud.Plugin.Ipc.Exceptions; using Dalamud.Plugin.Ipc.Internal; -using Dalamud.Plugin.Services; +using Dalamud.Plugin.VersionInfo; namespace Dalamud.Plugin; @@ -194,6 +194,12 @@ public interface IDalamudPluginInterface : IServiceProvider /// The plugin that loads in the given context, or null if this isn't a plugin's context or if this information cannot be determined. IExposedPlugin? GetPlugin(AssemblyLoadContext context); + /// + /// Gets information about the version of Dalamud this plugin is loaded into. + /// + /// Class containing version information. + IDalamudVersionInfo GetDalamudVersion(); + /// T GetOrCreateData(string tag, Func dataGenerator) where T : class; diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs index e2eded57c..193a2d45f 100644 --- a/Dalamud/Plugin/Internal/PluginManager.cs +++ b/Dalamud/Plugin/Internal/PluginManager.cs @@ -1790,7 +1790,7 @@ internal 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.MinimumDalamudVersion == null || Util.AssemblyVersionParsed >= remoteManifest.MinimumDalamudVersion) + .Where(remoteManifest => remoteManifest.MinimumDalamudVersion == null || Versioning.GetAssemblyVersionParsed() >= remoteManifest.MinimumDalamudVersion) .Where(remoteManifest => { var useTesting = this.UseTesting(remoteManifest); diff --git a/Dalamud/Plugin/Internal/Types/LocalPlugin.cs b/Dalamud/Plugin/Internal/Types/LocalPlugin.cs index 0197683ef..1fe18b95b 100644 --- a/Dalamud/Plugin/Internal/Types/LocalPlugin.cs +++ b/Dalamud/Plugin/Internal/Types/LocalPlugin.cs @@ -315,7 +315,7 @@ internal class LocalPlugin : IAsyncDisposable if (!this.CheckPolicy()) throw new PluginPreconditionFailedException($"Unable to load {this.Name} as a load policy forbids it"); - if (this.Manifest.MinimumDalamudVersion != null && this.Manifest.MinimumDalamudVersion > Util.AssemblyVersionParsed) + if (this.Manifest.MinimumDalamudVersion != null && this.Manifest.MinimumDalamudVersion > Versioning.GetAssemblyVersionParsed()) throw new PluginPreconditionFailedException($"Unable to load {this.Name}, Dalamud version is lower than minimum required version {this.Manifest.MinimumDalamudVersion}"); this.State = PluginState.Loading; diff --git a/Dalamud/Plugin/Internal/Types/PluginRepository.cs b/Dalamud/Plugin/Internal/Types/PluginRepository.cs index c5e703e4b..d5c1131af 100644 --- a/Dalamud/Plugin/Internal/Types/PluginRepository.cs +++ b/Dalamud/Plugin/Internal/Types/PluginRepository.cs @@ -59,7 +59,7 @@ internal class PluginRepository }, UserAgent = { - new ProductInfoHeaderValue("Dalamud", Util.AssemblyVersion), + new ProductInfoHeaderValue("Dalamud", Versioning.GetAssemblyVersion()), }, }, }; @@ -164,7 +164,7 @@ internal class PluginRepository } this.PluginMaster = pluginMaster.Where(this.IsValidManifest).ToList().AsReadOnly(); - + // API9 HACK: Force IsHide to false, we should remove that if (!this.IsThirdParty) { @@ -197,7 +197,7 @@ internal class PluginRepository Log.Error("Plugin {PluginName} in {RepoLink} has an invalid Name.", manifest.InternalName, this.PluginMasterUrl); return false; } - + // ReSharper disable once ConditionIsAlwaysTrueOrFalse if (manifest.AssemblyVersion == null) { @@ -224,7 +224,7 @@ internal class PluginRepository request.Headers.CacheControl = new CacheControlHeaderValue { NoCache = true }; using var requestCts = new CancellationTokenSource(TimeSpan.FromSeconds(timeout)); - + return await httpClient.SendAsync(request, requestCts.Token); } } diff --git a/Dalamud/Plugin/Ipc/ICallGateProvider.cs b/Dalamud/Plugin/Ipc/ICallGateProvider.cs index f4e5c76d7..387f0adf9 100644 --- a/Dalamud/Plugin/Ipc/ICallGateProvider.cs +++ b/Dalamud/Plugin/Ipc/ICallGateProvider.cs @@ -19,6 +19,9 @@ public interface ICallGateProvider /// public void UnregisterFunc(); + + /// + public IpcContext? GetContext(); } /// diff --git a/Dalamud/Plugin/Ipc/Internal/CallGateChannel.cs b/Dalamud/Plugin/Ipc/Internal/CallGateChannel.cs index ea94103f7..e177abab7 100644 --- a/Dalamud/Plugin/Ipc/Internal/CallGateChannel.cs +++ b/Dalamud/Plugin/Ipc/Internal/CallGateChannel.cs @@ -2,7 +2,9 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Reflection; +using System.Threading; +using Dalamud.Plugin.Internal.Types; using Dalamud.Plugin.Ipc.Exceptions; using Dalamud.Plugin.Ipc.Internal.Converters; @@ -16,6 +18,8 @@ namespace Dalamud.Plugin.Ipc.Internal; /// internal class CallGateChannel { + private readonly ThreadLocal ipcExecutionContext = new(); + /// /// The actual storage. /// @@ -145,6 +149,21 @@ internal class CallGateChannel return (TRet)result; } + internal void SetInvocationContext(IpcContext ipcContext) + { + this.ipcExecutionContext.Value = ipcContext; + } + + internal IpcContext? GetInvocationContext() + { + return this.ipcExecutionContext.IsValueCreated ? this.ipcExecutionContext.Value : null; + } + + internal void ClearInvocationContext() + { + this.ipcExecutionContext.Value = null; + } + private void CheckAndConvertArgs(object?[]? args, MethodInfo methodInfo) { var paramTypes = methodInfo.GetParameters() diff --git a/Dalamud/Plugin/Ipc/Internal/CallGatePubSub.cs b/Dalamud/Plugin/Ipc/Internal/CallGatePubSub.cs index cc54a563b..8725ef733 100644 --- a/Dalamud/Plugin/Ipc/Internal/CallGatePubSub.cs +++ b/Dalamud/Plugin/Ipc/Internal/CallGatePubSub.cs @@ -1,3 +1,5 @@ +using Dalamud.Plugin.Internal.Types; + #pragma warning disable SA1402 // File may only contain a single type namespace Dalamud.Plugin.Ipc.Internal; @@ -5,9 +7,9 @@ namespace Dalamud.Plugin.Ipc.Internal; /// internal class CallGatePubSub : CallGatePubSubBase, ICallGateProvider, ICallGateSubscriber { - /// - public CallGatePubSub(string name) - : base(name) + /// + public CallGatePubSub(string name, LocalPlugin? owningPlugin = null) + : base(name, owningPlugin) { } @@ -43,9 +45,9 @@ internal class CallGatePubSub : CallGatePubSubBase, ICallGateProvider internal class CallGatePubSub : CallGatePubSubBase, ICallGateProvider, ICallGateSubscriber { - /// - public CallGatePubSub(string name) - : base(name) + /// + public CallGatePubSub(string name, LocalPlugin? owningPlugin = null) + : base(name, owningPlugin) { } @@ -81,9 +83,9 @@ internal class CallGatePubSub : CallGatePubSubBase, ICallGateProvider< /// internal class CallGatePubSub : CallGatePubSubBase, ICallGateProvider, ICallGateSubscriber { - /// - public CallGatePubSub(string name) - : base(name) + /// + public CallGatePubSub(string name, LocalPlugin? owningPlugin = null) + : base(name, owningPlugin) { } @@ -119,9 +121,9 @@ internal class CallGatePubSub : CallGatePubSubBase, ICallGateProvi /// internal class CallGatePubSub : CallGatePubSubBase, ICallGateProvider, ICallGateSubscriber { - /// - public CallGatePubSub(string name) - : base(name) + /// + public CallGatePubSub(string name, LocalPlugin? owningPlugin = null) + : base(name, owningPlugin) { } @@ -157,9 +159,9 @@ internal class CallGatePubSub : CallGatePubSubBase, ICallGateP /// internal class CallGatePubSub : CallGatePubSubBase, ICallGateProvider, ICallGateSubscriber { - /// - public CallGatePubSub(string name) - : base(name) + /// + public CallGatePubSub(string name, LocalPlugin? owningPlugin = null) + : base(name, owningPlugin) { } @@ -195,9 +197,9 @@ internal class CallGatePubSub : CallGatePubSubBase, ICallG /// internal class CallGatePubSub : CallGatePubSubBase, ICallGateProvider, ICallGateSubscriber { - /// - public CallGatePubSub(string name) - : base(name) + /// + public CallGatePubSub(string name, LocalPlugin? owningPlugin = null) + : base(name, owningPlugin) { } @@ -233,9 +235,9 @@ internal class CallGatePubSub : CallGatePubSubBase, IC /// internal class CallGatePubSub : CallGatePubSubBase, ICallGateProvider, ICallGateSubscriber { - /// - public CallGatePubSub(string name) - : base(name) + /// + public CallGatePubSub(string name, LocalPlugin? owningPlugin = null) + : base(name, owningPlugin) { } @@ -271,9 +273,9 @@ internal class CallGatePubSub : CallGatePubSubBase /// internal class CallGatePubSub : CallGatePubSubBase, ICallGateProvider, ICallGateSubscriber { - /// - public CallGatePubSub(string name) - : base(name) + /// + public CallGatePubSub(string name, LocalPlugin? owningPlugin = null) + : base(name, owningPlugin) { } @@ -309,9 +311,9 @@ internal class CallGatePubSub : CallGatePubSub /// internal class CallGatePubSub : CallGatePubSubBase, ICallGateProvider, ICallGateSubscriber { - /// - public CallGatePubSub(string name) - : base(name) + /// + public CallGatePubSub(string name, LocalPlugin? owningPlugin = null) + : base(name, owningPlugin) { } diff --git a/Dalamud/Plugin/Ipc/Internal/CallGatePubSubBase.cs b/Dalamud/Plugin/Ipc/Internal/CallGatePubSubBase.cs index 308457373..521824b7b 100644 --- a/Dalamud/Plugin/Ipc/Internal/CallGatePubSubBase.cs +++ b/Dalamud/Plugin/Ipc/Internal/CallGatePubSubBase.cs @@ -1,4 +1,11 @@ +using System.Reactive.Disposables; +using System.Threading; + +using Dalamud.Plugin.Internal.Types; using Dalamud.Plugin.Ipc.Exceptions; +using Dalamud.Utility; + +using Serilog; namespace Dalamud.Plugin.Ipc.Internal; @@ -11,9 +18,11 @@ internal abstract class CallGatePubSubBase /// Initializes a new instance of the class. /// /// The name of the IPC registration. - protected CallGatePubSubBase(string name) + /// The plugin that owns this IPC pubsub. + protected CallGatePubSubBase(string name, LocalPlugin? owningPlugin) { this.Channel = Service.Get().GetOrCreateChannel(name); + this.OwningPlugin = owningPlugin; } /// @@ -21,7 +30,7 @@ internal abstract class CallGatePubSubBase /// s. /// public bool HasAction => this.Channel.Action != null; - + /// /// Gets a value indicating whether this IPC call gate has an associated Function. Only exposed to /// s. @@ -33,12 +42,17 @@ internal abstract class CallGatePubSubBase /// s, and can be used to determine if messages should be sent through the gate. /// public int SubscriptionCount => this.Channel.Subscriptions.Count; - + /// /// Gets the underlying channel implementation. /// protected CallGateChannel Channel { get; init; } - + + /// + /// Gets the plugin that owns this pubsub instance. + /// + protected LocalPlugin? OwningPlugin { get; init; } + /// /// Removes the associated Action from this call gate, effectively disabling RPC calls. /// @@ -53,6 +67,16 @@ internal abstract class CallGatePubSubBase public void UnregisterFunc() => this.Channel.Func = null; + /// + /// Gets the current context for this IPC call. This will only be present when called from within an IPC action + /// or function handler, and will be null otherwise. + /// + /// Returns a potential IPC context. + public IpcContext? GetContext() + { + return this.Channel.GetInvocationContext(); + } + /// /// Registers a for use by other plugins via RPC. This Delegate must satisfy the constraints /// of an type as defined by the interface, meaning they may not return a value and must have @@ -105,7 +129,12 @@ internal abstract class CallGatePubSubBase /// /// private protected void InvokeAction(params object?[]? args) - => this.Channel.InvokeAction(args); + { + using (this.BuildContext()) + { + this.Channel.InvokeAction(args); + } + } /// /// Executes the Function registered for this IPC call gate via . This method is intended @@ -120,7 +149,12 @@ internal abstract class CallGatePubSubBase /// /// private protected TRet InvokeFunc(params object?[]? args) - => this.Channel.InvokeFunc(args); + { + using (this.BuildContext()) + { + return this.Channel.InvokeFunc(args); + } + } /// /// Send the given arguments to all subscribers (through ) of this IPC call gate. This method @@ -132,4 +166,14 @@ internal abstract class CallGatePubSubBase /// Delegate arguments. private protected void SendMessage(params object?[]? args) => this.Channel.SendMessage(args); + + private IDisposable BuildContext() + { + this.Channel.SetInvocationContext(new IpcContext + { + SourcePlugin = this.OwningPlugin != null ? new ExposedPlugin(this.OwningPlugin) : null, + }); + + return Disposable.Create(() => { this.Channel.ClearInvocationContext(); }); + } } diff --git a/Dalamud/Plugin/Ipc/IpcContext.cs b/Dalamud/Plugin/Ipc/IpcContext.cs new file mode 100644 index 000000000..25fde6a36 --- /dev/null +++ b/Dalamud/Plugin/Ipc/IpcContext.cs @@ -0,0 +1,15 @@ +namespace Dalamud.Plugin.Ipc; + +/// +/// The context associated for an IPC call. Reads from ThreadLocal. +/// +public class IpcContext +{ + /// + /// Gets the plugin that initiated this IPC call. + /// + public IExposedPlugin? SourcePlugin { get; init; } + + /// + public override string ToString() => $""; +} diff --git a/Dalamud/Plugin/VersionInfo/DalamudVersionInfo.cs b/Dalamud/Plugin/VersionInfo/DalamudVersionInfo.cs new file mode 100644 index 000000000..c87c012af --- /dev/null +++ b/Dalamud/Plugin/VersionInfo/DalamudVersionInfo.cs @@ -0,0 +1,11 @@ +namespace Dalamud.Plugin.VersionInfo; + +/// +internal class DalamudVersionInfo(Version version, string? track) : IDalamudVersionInfo +{ + /// + public Version Version { get; } = version; + + /// + public string? BetaTrack { get; } = track; +} diff --git a/Dalamud/Plugin/VersionInfo/IDalamudVersionInfo.cs b/Dalamud/Plugin/VersionInfo/IDalamudVersionInfo.cs new file mode 100644 index 000000000..e6b6a9601 --- /dev/null +++ b/Dalamud/Plugin/VersionInfo/IDalamudVersionInfo.cs @@ -0,0 +1,19 @@ +namespace Dalamud.Plugin.VersionInfo; + +/// +/// Interface exposing various information related to Dalamud versioning. +/// +public interface IDalamudVersionInfo +{ + /// + /// Gets the Dalamud version. + /// + Version Version { get; } + + /// + /// Gets the currently used beta track. + /// Please don't tell users to switch branches. They have it bad enough, fix your things instead. + /// Null if this build wasn't launched from XIVLauncher. + /// + string? BetaTrack { get; } +} diff --git a/Dalamud/Support/BugBait.cs b/Dalamud/Support/BugBait.cs index 7ce96208c..f0a98ca98 100644 --- a/Dalamud/Support/BugBait.cs +++ b/Dalamud/Support/BugBait.cs @@ -37,7 +37,7 @@ internal static class BugBait Name = plugin.InternalName, Version = isTesting ? plugin.TestingAssemblyVersion?.ToString() : plugin.AssemblyVersion.ToString(), Platform = Util.GetHostPlatform().ToString(), - DalamudHash = Util.GetScmVersion(), + DalamudHash = Versioning.GetScmVersion(), }; if (includeException) diff --git a/Dalamud/Support/DalamudReleases.cs b/Dalamud/Support/DalamudReleases.cs index 603c77487..949ebf94a 100644 --- a/Dalamud/Support/DalamudReleases.cs +++ b/Dalamud/Support/DalamudReleases.cs @@ -38,7 +38,7 @@ internal class DalamudReleases : IServiceType /// The version info for the current track. public async Task GetVersionForCurrentTrack() { - var currentTrack = Util.GetActiveTrack(); + var currentTrack = Versioning.GetActiveTrack(); if (currentTrack.IsNullOrEmpty()) return null; diff --git a/Dalamud/Support/Troubleshooting.cs b/Dalamud/Support/Troubleshooting.cs index 88048c462..de529a29b 100644 --- a/Dalamud/Support/Troubleshooting.cs +++ b/Dalamud/Support/Troubleshooting.cs @@ -69,11 +69,11 @@ public static class Troubleshooting LoadedPlugins = pluginManager?.InstalledPlugins?.Select(x => x.Manifest as LocalPluginManifest)?.OrderByDescending(x => x.InternalName).ToArray(), PluginStates = pluginManager?.InstalledPlugins?.Where(x => !x.IsDev).ToDictionary(x => x.Manifest.InternalName, x => x.IsBanned ? "Banned" : x.State.ToString()), EverStartedLoadingPlugins = pluginManager?.InstalledPlugins.Where(x => x.HasEverStartedLoad).Select(x => x.InternalName).ToList(), - DalamudVersion = Util.GetScmVersion(), - DalamudGitHash = Util.GetGitHash() ?? "Unknown", + DalamudVersion = Versioning.GetScmVersion(), + DalamudGitHash = Versioning.GetGitHash() ?? "Unknown", GameVersion = startInfo.GameVersion?.ToString() ?? "Unknown", Language = startInfo.Language.ToString(), - BetaKey = Util.GetActiveTrack(), + BetaKey = Versioning.GetActiveTrack(), DoPluginTest = configuration.DoPluginTest, LoadAllApiLevels = pluginManager?.LoadAllApiLevels == true, InterfaceLoaded = interfaceManager?.IsReady ?? false, diff --git a/Dalamud/Utility/Util.cs b/Dalamud/Utility/Util.cs index bde113904..0ea5bbcbf 100644 --- a/Dalamud/Utility/Util.cs +++ b/Dalamud/Utility/Util.cs @@ -68,96 +68,10 @@ public static partial class Util ]; private static readonly Type GenericSpanType = typeof(Span<>); - private static string? scmVersionInternal; - private static string? gitHashInternal; - private static string? gitHashClientStructsInternal; - private static string? branchInternal; private static ulong moduleStartAddr; private static ulong moduleEndAddr; - /// - /// Gets the Dalamud version. - /// - [Api13ToDo("Remove. Make both versions here internal. Add an API somewhere.")] - public static string AssemblyVersion { get; } = - Assembly.GetAssembly(typeof(ChatHandlers))!.GetName().Version!.ToString(); - - /// - /// Gets the Dalamud version. - /// - internal static Version AssemblyVersionParsed { get; } = - Assembly.GetAssembly(typeof(ChatHandlers))!.GetName().Version!; - - /// - /// Gets the SCM Version from the assembly, or null if it cannot be found. This method will generally return - /// the git describe output for this build, which will be a raw version if this is a stable build or an - /// appropriately-annotated version if this is *not* stable. Local builds will return a `Local Build` text string. - /// - /// The SCM version of the assembly. - public static string GetScmVersion() - { - if (scmVersionInternal != null) return scmVersionInternal; - - var asm = typeof(Util).Assembly; - var attrs = asm.GetCustomAttributes(); - - return scmVersionInternal = attrs.First(a => a.Key == "SCMVersion").Value - ?? asm.GetName().Version!.ToString(); - } - - /// - /// Gets the git commit hash value from the assembly or null if it cannot be found. Will be null for Debug builds, - /// and will be suffixed with `-dirty` if in release with pending changes. - /// - /// The git hash of the assembly. - public static string? GetGitHash() - { - if (gitHashInternal != null) - return gitHashInternal; - - var asm = typeof(Util).Assembly; - var attrs = asm.GetCustomAttributes(); - - return gitHashInternal = attrs.FirstOrDefault(a => a.Key == "GitHash")?.Value ?? "N/A"; - } - - /// - /// Gets the git hash value from the assembly or null if it cannot be found. - /// - /// The git hash of the assembly. - public static string? GetGitHashClientStructs() - { - if (gitHashClientStructsInternal != null) - return gitHashClientStructsInternal; - - var asm = typeof(Util).Assembly; - var attrs = asm.GetCustomAttributes(); - - gitHashClientStructsInternal = attrs.First(a => a.Key == "GitHashClientStructs").Value; - - return gitHashClientStructsInternal; - } - - /// - /// Gets the Git branch name this version of Dalamud was built from, or null, if this is a Debug build. - /// - /// The branch name. - public static string? GetGitBranch() - { - if (branchInternal != null) - return branchInternal; - - var asm = typeof(Util).Assembly; - var attrs = asm.GetCustomAttributes(); - - var gitBranch = attrs.FirstOrDefault(a => a.Key == "GitBranch")?.Value; - if (gitBranch == null) - return null; - - return branchInternal = gitBranch; - } - /// public static unsafe string DescribeAddress(void* p) => DescribeAddress((nint)p); @@ -693,16 +607,6 @@ public static partial class Util } } - /// - /// Gets the active Dalamud track, if this instance was launched through XIVLauncher and used a version - /// downloaded from webservices. - /// - /// The name of the track, or null. - internal static string? GetActiveTrack() - { - return Environment.GetEnvironmentVariable("DALAMUD_BRANCH"); - } - /// /// Gets a random, inoffensive, human-friendly string. /// diff --git a/Dalamud/Utility/Versioning.cs b/Dalamud/Utility/Versioning.cs new file mode 100644 index 000000000..d3b30b834 --- /dev/null +++ b/Dalamud/Utility/Versioning.cs @@ -0,0 +1,108 @@ +using System.Linq; +using System.Reflection; + +namespace Dalamud.Utility; + +/// +/// Helpers to access Dalamud versioning information. +/// +internal static class Versioning +{ + private static string? scmVersionInternal; + private static string? gitHashInternal; + private static string? gitHashClientStructsInternal; + private static string? branchInternal; + + /// + /// Gets the Dalamud version. + /// + /// The raw Dalamud assembly version. + internal static string GetAssemblyVersion() => + Assembly.GetAssembly(typeof(Versioning))!.GetName().Version!.ToString(); + + /// + /// Gets the Dalamud version. + /// + /// The parsed Dalamud assembly version. + internal static Version GetAssemblyVersionParsed() => + Assembly.GetAssembly(typeof(Versioning))!.GetName().Version!; + + /// + /// Gets the SCM Version from the assembly, or null if it cannot be found. This method will generally return + /// the git describe output for this build, which will be a raw version if this is a stable build or an + /// appropriately-annotated version if this is *not* stable. Local builds will return a `Local Build` text string. + /// + /// The SCM version of the assembly. + internal static string GetScmVersion() + { + if (scmVersionInternal != null) return scmVersionInternal; + + var asm = typeof(Util).Assembly; + var attrs = asm.GetCustomAttributes(); + + return scmVersionInternal = attrs.First(a => a.Key == "SCMVersion").Value + ?? asm.GetName().Version!.ToString(); + } + + /// + /// Gets the git commit hash value from the assembly or null if it cannot be found. Will be null for Debug builds, + /// and will be suffixed with `-dirty` if in release with pending changes. + /// + /// The git hash of the assembly. + internal static string? GetGitHash() + { + if (gitHashInternal != null) + return gitHashInternal; + + var asm = typeof(Util).Assembly; + var attrs = asm.GetCustomAttributes(); + + return gitHashInternal = attrs.FirstOrDefault(a => a.Key == "GitHash")?.Value ?? "N/A"; + } + + /// + /// Gets the git hash value from the assembly or null if it cannot be found. + /// + /// The git hash of the assembly. + internal static string? GetGitHashClientStructs() + { + if (gitHashClientStructsInternal != null) + return gitHashClientStructsInternal; + + var asm = typeof(Util).Assembly; + var attrs = asm.GetCustomAttributes(); + + gitHashClientStructsInternal = attrs.First(a => a.Key == "GitHashClientStructs").Value; + + return gitHashClientStructsInternal; + } + + /// + /// Gets the Git branch name this version of Dalamud was built from, or null, if this is a Debug build. + /// + /// The branch name. + internal static string? GetGitBranch() + { + if (branchInternal != null) + return branchInternal; + + var asm = typeof(Util).Assembly; + var attrs = asm.GetCustomAttributes(); + + var gitBranch = attrs.FirstOrDefault(a => a.Key == "GitBranch")?.Value; + if (gitBranch == null) + return null; + + return branchInternal = gitBranch; + } + + /// + /// Gets the active Dalamud track, if this instance was launched through XIVLauncher and used a version + /// downloaded from webservices. + /// + /// The name of the track, or null. + internal static string? GetActiveTrack() + { + return Environment.GetEnvironmentVariable("DALAMUD_BRANCH"); + } +} diff --git a/Directory.Packages.props b/Directory.Packages.props index 58e355400..ec2e7e276 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -6,38 +6,35 @@ - + - + - + - + - - - + - - + - - - - + + + + - - + + @@ -52,15 +49,15 @@ - - + + - - - - - - - + + + + + + +