From 3f99d111794da2fd00c1a1781c2fc4271953aae0 Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Sun, 23 Jun 2024 22:55:31 +0200 Subject: [PATCH] Add support info to Glamourer. --- Glamourer/Glamourer.cs | 93 ++++++++++++++++++- Glamourer/Gui/MainWindow.cs | 37 +++++++- Glamourer/Gui/Tabs/SettingsTab/SettingsTab.cs | 9 +- Glamourer/Services/CodeService.cs | 3 + Glamourer/Services/ServiceManager.cs | 5 +- Glamourer/State/StateIndex.cs | 2 +- OtterGui | 2 +- 7 files changed, 138 insertions(+), 13 deletions(-) diff --git a/Glamourer/Glamourer.cs b/Glamourer/Glamourer.cs index b368195..5dd6040 100644 --- a/Glamourer/Glamourer.cs +++ b/Glamourer/Glamourer.cs @@ -1,5 +1,7 @@ using Dalamud.Plugin; using Glamourer.Api; +using Glamourer.Automation; +using Glamourer.Designs; using Glamourer.Gui; using Glamourer.Interop; using Glamourer.Services; @@ -30,7 +32,7 @@ public class Glamourer : IDalamudPlugin { try { - _services = StaticServiceManager.CreateProvider(pluginInterface, Log); + _services = StaticServiceManager.CreateProvider(pluginInterface, Log, this); Messager = _services.GetService(); _services.EnsureRequiredServices(); @@ -50,6 +52,95 @@ public class Glamourer : IDalamudPlugin } } + public string GatherSupportInformation() + { + var sb = new StringBuilder(10240); + var config = _services.GetService(); + sb.AppendLine("**Settings**"); + sb.Append($"> **`Plugin Version: `** {Version}\n"); + sb.Append($"> **`Commit Hash: `** {CommitHash}\n"); + sb.Append($"> **`Enable Auto Designs: `** {config.EnableAutoDesigns}\n"); + sb.Append($"> **`Gear Protection: `** {config.UseRestrictedGearProtection}\n"); + sb.Append($"> **`Item Restriction: `** {config.UnlockedItemMode}\n"); + sb.Append($"> **`Keep Manual Changes: `** {config.RespectManualOnAutomationUpdate}\n"); + sb.Append($"> **`Auto-Reload Gear: `** {config.AutoRedrawEquipOnChanges}\n"); + sb.Append($"> **`Revert on Zone Change:`** {config.RevertManualChangesOnZoneChange}\n"); + sb.Append($"> **`Festival Easter-Eggs: `** {config.DisableFestivals}\n"); + sb.Append($"> **`Advanced Customize: `** {config.UseAdvancedParameters}\n"); + sb.Append($"> **`Advanced Dye: `** {config.UseAdvancedDyes}\n"); + sb.Append($"> **`Apply Entire Weapon: `** {config.ChangeEntireItem}\n"); + sb.Append($"> **`Apply Associated Mods:`** {config.AlwaysApplyAssociatedMods}\n"); + sb.Append($"> **`Show QDB: `** {config.Ephemeral.ShowDesignQuickBar}\n"); + sb.Append($"> **`QDB Hotkey: `** {config.ToggleQuickDesignBar}\n"); + sb.Append($"> **`Smaller Equip Display:`** {config.SmallEquip}\n"); + sb.Append($"> **`Debug Mode: `** {config.DebugMode}\n"); + sb.Append($"> **`Cheat Codes: `** {(ulong)_services.GetService().AllEnabled:X8}\n"); + sb.AppendLine("**Plugins**"); + GatherRelevantPlugins(sb); + var designManager = _services.GetService(); + var autoManager = _services.GetService(); + var stateManager = _services.GetService(); + var objectManager = _services.GetService(); + var currentPlayer = objectManager.PlayerData.Identifier; + var states = stateManager.Where(kvp => objectManager.ContainsKey(kvp.Key)).ToList(); + + sb.AppendLine("**Statistics**"); + sb.Append($"> **`Current Player: `** {(currentPlayer.IsValid ? currentPlayer.Incognito(null) : "None")}\n"); + sb.Append($"> **`Saved Designs: `** {designManager.Designs.Count}\n"); + sb.Append($"> **`Automation Sets: `** {autoManager.Count} ({autoManager.Count(set => set.Enabled)} Enabled)\n"); + sb.Append( + $"> **`Actor States: `** {stateManager.Count} ({states.Count} Visible, {stateManager.Values.Count(s => s.IsLocked)} Locked)\n"); + + var enabledAutomation = autoManager.Where(s => s.Enabled).ToList(); + if (enabledAutomation.Count > 0) + { + sb.AppendLine("**Enabled Automation**"); + foreach (var set in enabledAutomation) + { + sb.Append( + $"> **`{set.Identifiers.First().Incognito(null) + ':',-24}`** {(set.Name.Length >= 2 ? $"{set.Name.AsSpan(0, 2)}..." : set.Name)} ({set.Designs.Count} {(set.Designs.Count == 1 ? "Design" : "Designs")})\n"); + } + } + + if (states.Count > 0) + { + sb.AppendLine("**State**"); + foreach (var (ident, state) in states) + { + var sources = Enum.GetValues().Select(s => (0, s)).ToArray(); + foreach (var source in StateIndex.All.Select(s => state.Sources[s])) + ++sources[(int)source].Item1; + foreach (var material in state.Materials.Values) + ++sources[(int)material.Value.Source].Item1; + var sourcesString = string.Join(", ", sources.Where(s => s.Item1 > 0).Select(s => $"{s.s} {s.Item1}")); + sb.Append( + $"> **`{ident.Incognito(null) + ':',-24}`** {(state.IsLocked ? "Locked, " : string.Empty)}Job {state.LastJob.Id}, Zone {state.LastTerritory}, Materials {state.Materials.Values.Count}, {sourcesString}\n"); + } + } + + return sb.ToString(); + } + + + private void GatherRelevantPlugins(StringBuilder sb) + { + ReadOnlySpan relevantPlugins = + [ + "Penumbra", "MareSynchronos", "CustomizePlus", "SimpleHeels", "VfxEditor", "heliosphere-plugin", "Ktisis", "Brio", "DynamicBridge", + ]; + var plugins = _services.GetService().InstalledPlugins + .GroupBy(p => p.InternalName) + .ToDictionary(g => g.Key, g => + { + var item = g.OrderByDescending(p => p.IsLoaded).ThenByDescending(p => p.Version).First(); + return (item.IsLoaded, item.Version, item.Name); + }); + foreach (var plugin in relevantPlugins) + { + if (plugins.TryGetValue(plugin, out var data)) + sb.Append($"> **`{data.Name + ':',-22}`** {data.Version}{(data.IsLoaded ? string.Empty : " (Disabled)")}\n"); + } + } public void Dispose() => _services?.Dispose(); diff --git a/Glamourer/Gui/MainWindow.cs b/Glamourer/Gui/MainWindow.cs index f7cd589..007d936 100644 --- a/Glamourer/Gui/MainWindow.cs +++ b/Glamourer/Gui/MainWindow.cs @@ -1,4 +1,5 @@ -using Dalamud.Interface.Windowing; +using Dalamud.Interface.Internal.Notifications; +using Dalamud.Interface.Windowing; using Dalamud.Plugin; using Glamourer.Designs; using Glamourer.Events; @@ -13,6 +14,7 @@ using Glamourer.Gui.Tabs.UnlocksTab; using Glamourer.Interop.Penumbra; using ImGuiNET; using OtterGui; +using OtterGui.Classes; using OtterGui.Custom; using OtterGui.Raii; using OtterGui.Services; @@ -131,7 +133,12 @@ public class MainWindow : Window, IDisposable if (_penumbra.CurrentMajor == 0) DrawProblemWindow( "Could not attach to Penumbra. Please make sure Penumbra is installed and running.\n\nPenumbra is required for Glamourer to work properly."); - else if (_penumbra is { CurrentMajor: PenumbraService.RequiredPenumbraBreakingVersion, CurrentMinor: >= PenumbraService.RequiredPenumbraFeatureVersion }) + else if (_penumbra is + { + + CurrentMajor: PenumbraService.RequiredPenumbraBreakingVersion, + CurrentMinor: >= PenumbraService.RequiredPenumbraFeatureVersion, + }) DrawProblemWindow( $"You are currently not attached to Penumbra, seemingly by manually detaching from it.\n\nPenumbra's last API Version was {_penumbra.CurrentMajor}.{_penumbra.CurrentMinor}.\n\nPenumbra is required for Glamourer to work properly."); else @@ -184,22 +191,42 @@ public class MainWindow : Window, IDisposable return TabType.None; } + /// The longest support button text. + public static ReadOnlySpan SupportInfoButtonText + => "Copy Support Info to Clipboard"u8; + /// Draw the support button group on the right-hand side of the window. - public static void DrawSupportButtons(Changelog changelog) + public static void DrawSupportButtons(Glamourer glamourer, Changelog changelog) { - var width = ImGui.CalcTextSize("Join Discord for Support").X + ImGui.GetStyle().FramePadding.X * 2; + var width = ImUtf8.CalcTextSize(SupportInfoButtonText).X + ImGui.GetStyle().FramePadding.X * 2; var xPos = ImGui.GetWindowWidth() - width; ImGui.SetCursorPos(new Vector2(xPos, 0)); CustomGui.DrawDiscordButton(Glamourer.Messager, width); ImGui.SetCursorPos(new Vector2(xPos, ImGui.GetFrameHeightWithSpacing())); - CustomGui.DrawGuideButton(Glamourer.Messager, width); + DrawSupportButton(glamourer); ImGui.SetCursorPos(new Vector2(xPos, 2 * ImGui.GetFrameHeightWithSpacing())); + CustomGui.DrawGuideButton(Glamourer.Messager, width); + + ImGui.SetCursorPos(new Vector2(xPos, 3 * ImGui.GetFrameHeightWithSpacing())); if (ImGui.Button("Show Changelogs", new Vector2(width, 0))) changelog.ForceOpen = true; } + /// + /// Draw a button that copies the support info to clipboards. + /// + private static void DrawSupportButton(Glamourer glamourer) + { + if (!ImUtf8.Button(SupportInfoButtonText)) + return; + + var text = glamourer.GatherSupportInformation(); + ImGui.SetClipboardText(text); + Glamourer.Messager.NotificationMessage("Copied Support Info to Clipboard.", NotificationType.Success, false); + } + private void OnTabSelected(TabType type, Design? _) { SelectTab = type; diff --git a/Glamourer/Gui/Tabs/SettingsTab/SettingsTab.cs b/Glamourer/Gui/Tabs/SettingsTab/SettingsTab.cs index 6259f06..834b9fc 100644 --- a/Glamourer/Gui/Tabs/SettingsTab/SettingsTab.cs +++ b/Glamourer/Gui/Tabs/SettingsTab/SettingsTab.cs @@ -10,6 +10,7 @@ using Glamourer.Interop.PalettePlus; using ImGuiNET; using OtterGui; using OtterGui.Raii; +using OtterGui.Text; using OtterGui.Widgets; namespace Glamourer.Gui.Tabs.SettingsTab; @@ -25,7 +26,8 @@ public class SettingsTab( PaletteImport paletteImport, PalettePlusChecker paletteChecker, CollectionOverrideDrawer overrides, - CodeDrawer codeDrawer) + CodeDrawer codeDrawer, + Glamourer glamourer) : ITab { private readonly VirtualKey[] _validKeys = keys.GetValidVirtualKeys().Prepend(VirtualKey.NO_KEY).ToArray(); @@ -45,8 +47,9 @@ public class SettingsTab( ImGui.NewLine(); ImGui.NewLine(); ImGui.NewLine(); + ImGui.NewLine(); - using (var child2 = ImRaii.Child("SettingsChild")) + using (ImRaii.Child("SettingsChild")) { DrawBehaviorSettings(); DrawInterfaceSettings(); @@ -55,7 +58,7 @@ public class SettingsTab( codeDrawer.Draw(); } - MainWindow.DrawSupportButtons(changelog.Changelog); + MainWindow.DrawSupportButtons(glamourer, changelog.Changelog); } private void DrawBehaviorSettings() diff --git a/Glamourer/Services/CodeService.cs b/Glamourer/Services/CodeService.cs index 7d513dd..61339e1 100644 --- a/Glamourer/Services/CodeService.cs +++ b/Glamourer/Services/CodeService.cs @@ -50,6 +50,9 @@ public class CodeService private CodeFlag _enabled; + public CodeFlag AllEnabled + => _enabled; + public bool Enabled(CodeFlag flag) => _enabled.HasFlag(flag); diff --git a/Glamourer/Services/ServiceManager.cs b/Glamourer/Services/ServiceManager.cs index f06e014..005944e 100644 --- a/Glamourer/Services/ServiceManager.cs +++ b/Glamourer/Services/ServiceManager.cs @@ -33,7 +33,7 @@ namespace Glamourer.Services; public static class StaticServiceManager { - public static ServiceManager CreateProvider(DalamudPluginInterface pi, Logger log) + public static ServiceManager CreateProvider(DalamudPluginInterface pi, Logger log, Glamourer glamourer) { EventWrapperBase.ChangeLogger(log); var services = new ServiceManager(log) @@ -44,7 +44,8 @@ public static class StaticServiceManager .AddData() .AddDesigns() .AddState() - .AddUi(); + .AddUi() + .AddExistingService(glamourer); DalamudServices.AddServices(services, pi); services.AddIServices(typeof(EquipItem).Assembly); services.AddIServices(typeof(Glamourer).Assembly); diff --git a/Glamourer/State/StateIndex.cs b/Glamourer/State/StateIndex.cs index a55d6b1..28cc722 100644 --- a/Glamourer/State/StateIndex.cs +++ b/Glamourer/State/StateIndex.cs @@ -200,7 +200,7 @@ public readonly record struct StateIndex(int Value) : IEqualityOperators All + public static IEnumerable All => Enumerable.Range(0, Size - 1).Select(i => new StateIndex(i)); public bool GetApply(DesignBase data) diff --git a/OtterGui b/OtterGui index e95c0f0..fd79128 160000 --- a/OtterGui +++ b/OtterGui @@ -1 +1 @@ -Subproject commit e95c0f04edc7e85aea67498fd8bf495a7fe6d3c8 +Subproject commit fd791285606d49a7644762ea0b4dc2bbb1368eac