From fcb0660deffa383d040567350bbab87aad777cf6 Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Sun, 4 May 2025 00:36:39 +0200 Subject: [PATCH] Implement new IPC methods and API 1.6 --- Glamourer.Api | 2 +- Glamourer/Api/DesignsApi.cs | 66 ++++++++++++++++++- Glamourer/Api/GlamourerApi.cs | 2 +- Glamourer/Api/IpcProviders.cs | 5 ++ .../DebugTab/IpcTester/DesignIpcTester.cs | 45 +++++++++++++ OtterGui | 2 +- 6 files changed, 118 insertions(+), 4 deletions(-) diff --git a/Glamourer.Api b/Glamourer.Api index 2158bd4..9c86a9d 160000 --- a/Glamourer.Api +++ b/Glamourer.Api @@ -1 +1 @@ -Subproject commit 2158bd4bbcb6cefe3ce48e6d8b32e134cbee9a91 +Subproject commit 9c86a9d6847f68e75679fe57d34f53f680d949c6 diff --git a/Glamourer/Api/DesignsApi.cs b/Glamourer/Api/DesignsApi.cs index 0ee0b64..e21e6cb 100644 --- a/Glamourer/Api/DesignsApi.cs +++ b/Glamourer/Api/DesignsApi.cs @@ -2,11 +2,18 @@ using Glamourer.Api.Enums; using Glamourer.Designs; using Glamourer.State; +using Newtonsoft.Json.Linq; using OtterGui.Services; namespace Glamourer.Api; -public class DesignsApi(ApiHelpers helpers, DesignManager designs, StateManager stateManager, DesignFileSystem fileSystem, DesignColors color) +public class DesignsApi( + ApiHelpers helpers, + DesignManager designs, + StateManager stateManager, + DesignFileSystem fileSystem, + DesignColors color, + DesignConverter converter) : IGlamourerApiDesigns, IApiService { public Dictionary GetDesignList() @@ -16,6 +23,11 @@ public class DesignsApi(ApiHelpers helpers, DesignManager designs, StateManager => designs.Designs.ToDictionary(d => d.Identifier, d => (d.Name.Text, fileSystem.FindLeaf(d, out var leaf) ? leaf.FullName() : d.Name.Text, color.GetColor(d), d.QuickDesign)); + public (string DisplayName, string FullPath, uint DisplayColor, bool ShowInQdb) GetExtendedDesignData(Guid designId) + => designs.Designs.ByIdentifier(designId) is { } d + ? (d.Name.Text, fileSystem.FindLeaf(d, out var leaf) ? leaf.FullName() : d.Name.Text, color.GetColor(d), d.QuickDesign) + : (string.Empty, string.Empty, 0, false); + public GlamourerApiEc ApplyDesign(Guid designId, int objectIndex, uint key, ApplyFlag flags) { var args = ApiHelpers.Args("Design", designId, "Index", objectIndex, "Key", key, "Flags", flags); @@ -71,4 +83,56 @@ public class DesignsApi(ApiHelpers helpers, DesignManager designs, StateManager return ApiHelpers.Return(GlamourerApiEc.Success, args); } + + public (GlamourerApiEc, Guid) AddDesign(string designInput, string name) + { + var args = ApiHelpers.Args("DesignData", designInput, "Name", name); + + if (converter.FromBase64(designInput, true, true, out _) is not { } designBase) + try + { + var jObj = JObject.Parse(designInput); + designBase = converter.FromJObject(jObj, true, true); + if (designBase is null) + return (ApiHelpers.Return(GlamourerApiEc.CouldNotParse, args), Guid.Empty); + } + catch (Exception ex) + { + Glamourer.Log.Error($"Failure parsing data for AddDesign due to\n{ex}"); + return (ApiHelpers.Return(GlamourerApiEc.CouldNotParse, args), Guid.Empty); + } + + try + { + var design = designBase is Design d + ? designs.CreateClone(d, name, true) + : designs.CreateClone(designBase, name, true); + return (ApiHelpers.Return(GlamourerApiEc.Success, args), design.Identifier); + } + catch (Exception ex) + { + Glamourer.Log.Error($"Unknown error creating design via IPC:\n{ex}"); + return (ApiHelpers.Return(GlamourerApiEc.UnknownError, args), Guid.Empty); + } + } + + public GlamourerApiEc DeleteDesign(Guid designId) + { + var args = ApiHelpers.Args("DesignId", designId); + if (designs.Designs.ByIdentifier(designId) is not { } design) + return ApiHelpers.Return(GlamourerApiEc.NothingDone, args); + + designs.Delete(design); + return ApiHelpers.Return(GlamourerApiEc.Success, args); + } + + public string? GetDesignBase64(Guid designId) + => designs.Designs.ByIdentifier(designId) is { } design + ? converter.ShareBase64(design) + : null; + + public JObject? GetDesignJObject(Guid designId) + => designs.Designs.ByIdentifier(designId) is { } design + ? converter.ShareJObject(design) + : null; } diff --git a/Glamourer/Api/GlamourerApi.cs b/Glamourer/Api/GlamourerApi.cs index 9aaf72f..14c0512 100644 --- a/Glamourer/Api/GlamourerApi.cs +++ b/Glamourer/Api/GlamourerApi.cs @@ -6,7 +6,7 @@ namespace Glamourer.Api; public class GlamourerApi(DesignsApi designs, StateApi state, ItemsApi items) : IGlamourerApi, IApiService { public const int CurrentApiVersionMajor = 1; - public const int CurrentApiVersionMinor = 5; + public const int CurrentApiVersionMinor = 6; public (int Major, int Minor) ApiVersion => (CurrentApiVersionMajor, CurrentApiVersionMinor); diff --git a/Glamourer/Api/IpcProviders.cs b/Glamourer/Api/IpcProviders.cs index 8058818..2701f18 100644 --- a/Glamourer/Api/IpcProviders.cs +++ b/Glamourer/Api/IpcProviders.cs @@ -25,8 +25,13 @@ public sealed class IpcProviders : IDisposable, IApiService IpcSubscribers.GetDesignList.Provider(pi, api.Designs), IpcSubscribers.GetDesignListExtended.Provider(pi, api.Designs), + IpcSubscribers.GetExtendedDesignData.Provider(pi, api.Designs), IpcSubscribers.ApplyDesign.Provider(pi, api.Designs), IpcSubscribers.ApplyDesignName.Provider(pi, api.Designs), + IpcSubscribers.AddDesign.Provider(pi, api.Designs), + IpcSubscribers.DeleteDesign.Provider(pi, api.Designs), + IpcSubscribers.GetDesignBase64.Provider(pi, api.Designs), + IpcSubscribers.GetDesignJObject.Provider(pi, api.Designs), IpcSubscribers.SetItem.Provider(pi, api.Items), IpcSubscribers.SetItemName.Provider(pi, api.Items), diff --git a/Glamourer/Gui/Tabs/DebugTab/IpcTester/DesignIpcTester.cs b/Glamourer/Gui/Tabs/DebugTab/IpcTester/DesignIpcTester.cs index 918c7ad..9e11b99 100644 --- a/Glamourer/Gui/Tabs/DebugTab/IpcTester/DesignIpcTester.cs +++ b/Glamourer/Gui/Tabs/DebugTab/IpcTester/DesignIpcTester.cs @@ -7,6 +7,7 @@ using ImGuiNET; using OtterGui; using OtterGui.Raii; using OtterGui.Services; +using OtterGui.Text; namespace Glamourer.Gui.Tabs.DebugTab.IpcTester; @@ -15,6 +16,7 @@ public class DesignIpcTester(IDalamudPluginInterface pluginInterface) : IUiServi private Dictionary _designs = []; private int _gameObjectIndex; private string _gameObjectName = string.Empty; + private string _designName = string.Empty; private uint _key; private ApplyFlag _flags = ApplyFlagEx.DesignDefault; private Guid? _design; @@ -30,6 +32,7 @@ public class DesignIpcTester(IDalamudPluginInterface pluginInterface) : IUiServi IpcTesterHelpers.IndexInput(ref _gameObjectIndex); IpcTesterHelpers.KeyInput(ref _key); IpcTesterHelpers.NameInput(ref _gameObjectName); + ImUtf8.InputText("##designName"u8, ref _designName, "Design Name..."u8); ImGuiUtil.GuidInput("##identifier", "Design Identifier...", string.Empty, ref _design, ref _designText, ImGui.GetContentRegionAvail().X); IpcTesterHelpers.DrawFlagInput(ref _flags); @@ -54,6 +57,48 @@ public class DesignIpcTester(IDalamudPluginInterface pluginInterface) : IUiServi IpcTesterHelpers.DrawIntro(ApplyDesignName.Label); if (ImGuiUtil.DrawDisabledButton("Apply##Name", Vector2.Zero, string.Empty, !_design.HasValue)) _lastError = new ApplyDesignName(pluginInterface).Invoke(_design!.Value, _gameObjectName, _key, _flags); + + IpcTesterHelpers.DrawIntro(GetExtendedDesignData.Label); + if (_design.HasValue) + { + var (display, path, color, draw) = new GetExtendedDesignData(pluginInterface).Invoke(_design.Value); + if (path.Length > 0) + ImUtf8.Text($"{display} ({path}){(draw ? " in QDB"u8 : ""u8)}", color); + else + ImUtf8.Text("No Data"u8); + } + else + { + ImUtf8.Text("No Data"u8); + } + + IpcTesterHelpers.DrawIntro(GetDesignBase64.Label); + if (ImUtf8.Button("To Clipboard##Base64"u8) && _design.HasValue) + { + var data = new GetDesignBase64(pluginInterface).Invoke(_design.Value); + ImUtf8.SetClipboardText(data); + } + + IpcTesterHelpers.DrawIntro(AddDesign.Label); + if (ImUtf8.Button("Add from Clipboard"u8)) + try + { + var data = ImUtf8.GetClipboardText(); + _lastError = new AddDesign(pluginInterface).Invoke(data, _designName, out var newDesign); + if (_lastError is GlamourerApiEc.Success) + { + _design = newDesign; + _designText = newDesign.ToString(); + } + } + catch + { + _lastError = GlamourerApiEc.UnknownError; + } + + IpcTesterHelpers.DrawIntro(DeleteDesign.Label); + if (ImUtf8.Button("Delete##Design"u8) && _design.HasValue) + _lastError = new DeleteDesign(pluginInterface).Invoke(_design.Value); } private void DrawDesignsPopup() diff --git a/OtterGui b/OtterGui index abfce28..d1ba194 160000 --- a/OtterGui +++ b/OtterGui @@ -1 +1 @@ -Subproject commit abfce28e0bacdea841f029f59bc19971c43814d8 +Subproject commit d1ba1942efaae219b06ebc27d43de6d1889af97d