using HSUI.Config; using HSUI.Config.Attributes; using HSUI.Config.Profiles; using HSUI.Helpers; using Dalamud.Bindings.ImGui; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Numerics; using System.Reflection; using System.Text.RegularExpressions; namespace HSUI.Interface { [Disableable(false)] [Exportable(false)] [Shareable(false)] [Resettable(false)] [Section("Import")] [SubSection("General", 0)] public class ImportConfig : PluginConfigObject { private string _importString = ""; private bool _importing = false; private string? _errorMessage = null; private List? _importDataList = null; private List? _importDataEnabled = null; public new static ImportConfig DefaultConfig() { return new ImportConfig(); } [ManualDraw] public bool Draw(ref bool changed) { ImGui.Text("Import string:"); ImGui.InputText("", ref _importString, 999999); ImGui.Text("Here you can import specific parts of a profile.\nIf the string contains more than one part you will be able to select which parts you wish to import."); if (ImGui.Button("Import", new Vector2(560, 24))) { _importing = _importString.Length > 0; } ImGuiHelper.DrawSeparator(1, 1); // error modal if (_errorMessage != null) { if (ImGuiHelper.DrawErrorModal(_errorMessage)) { _importing = false; _errorMessage = null; } return false; } // parse import string if (_importing && _importDataList == null) { _errorMessage = Parse(); } // confirmation modal if (_importDataList != null && _importDataList.Count > 0) { var (didConfirm, didClose) = DrawImportConfirmationModal(); if (didConfirm) { _errorMessage = Import(); if (_errorMessage == null) { _importString = ""; } } if (didConfirm || didClose) { _importing = false; _importDataList = null; _importDataEnabled = null; changed = true; } return didConfirm && _errorMessage == null; } return false; } private string? Import() { if (_importDataList == null || _importDataEnabled == null) { return null; } List configObjects = new List(_importDataList.Count); for (int i = 0; i < _importDataList.Count; i++) { if (i >= _importDataEnabled.Count || _importDataEnabled[i] == false) { continue; } ImportData importData = _importDataList[i]; PluginConfigObject? config = importData.GetObject(); if (config == null) { return "Couldn't import \"" + importData.Name + "\""; } configObjects.Add(config); } foreach (PluginConfigObject config in configObjects) { ConfigurationManager.Instance.SetConfigObject(config); } return null; } private string? Parse() { string[] importStrings = _importString.Trim().Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries); if (importStrings.Length == 0) { return null; } _importDataList = new List(importStrings.Length); _importDataEnabled = new List(importStrings.Length); foreach (var str in importStrings) { try { ImportData importData = new ImportData(str); _importDataList.Add(importData); _importDataEnabled.Add(true); } catch (Exception e) { _importDataList = null; _importDataEnabled = null; return e is ArgumentException ? e.Message : "Invalid import string!"; } } return null; } public (bool, bool) DrawImportConfirmationModal() { if (_importDataList == null || _importDataEnabled == null) { return (false, true); } ConfigurationManager.Instance.ShowingModalWindow = true; bool didConfirm = false; bool didClose = false; ImGui.OpenPopup("Import ##HSUI"); Vector2 center = ImGui.GetMainViewport().GetCenter(); ImGui.SetNextWindowPos(center, ImGuiCond.Appearing, new Vector2(0.5f, 0.5f)); bool p_open = true; // i've no idea what this is used for if (ImGui.BeginPopupModal("Import ##HSUI", ref p_open, ImGuiWindowFlags.NoSavedSettings | ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoMove)) { float width = 300; ImGui.Text("Select which parts to import:"); ImGui.NewLine(); if (ImGui.Button("Select All", new Vector2(width / 2f - 5, 24))) { for (int i = 0; i < _importDataEnabled.Count; i++) { _importDataEnabled[i] = true; } } ImGui.SameLine(); if (ImGui.Button("Deselect All", new Vector2(width / 2f - 5, 24))) { for (int i = 0; i < _importDataEnabled.Count; i++) { _importDataEnabled[i] = false; } } ImGui.NewLine(); float height = Math.Min(30 * _importDataList.Count, 400); ImGui.BeginChild("import checkboxes", new Vector2(width, height), false); for (int i = 0; i < _importDataList.Count; i++) { bool value = _importDataEnabled[i]; if (ImGui.Checkbox(_importDataList[i].Name, ref value)) { _importDataEnabled[i] = value; } } ImGui.EndChild(); ImGui.NewLine(); if (ImGui.Button("OK", new Vector2(width / 2f - 5, 24))) { ImGui.CloseCurrentPopup(); didConfirm = true; didClose = true; } ImGui.SetItemDefaultFocus(); ImGui.SameLine(); if (ImGui.Button("Cancel", new Vector2(width / 2f - 5, 24))) { ImGui.CloseCurrentPopup(); didClose = true; } ImGui.EndPopup(); } // close button on nav else { didClose = true; } if (didClose) { ConfigurationManager.Instance.ShowingModalWindow = false; } return (didConfirm, didClose); } } public class ImportData { public readonly Type ConfigType; public readonly string Name; public readonly string ImportString; public readonly string JsonString; public ImportData(string base64String) { ImportString = base64String; JsonString = ImportExportHelper.Base64DecodeAndDecompress(base64String); string? typeString = (string?)JObject.Parse(JsonString)["$type"]; if (typeString == null) { throw new ArgumentException("Invalid type"); } // Migrate DelvUI type names to HSUI for profile/import compatibility if (typeString.Contains("DelvUI")) { typeString = typeString.Replace("DelvUI.", "HSUI.").Replace(", DelvUI", ", HSUI"); } Type? type = Type.GetType(typeString); if (type == null) { throw new ArgumentException("Invalid type: \"" + typeString + "\""); } ConfigType = type; Name = Utils.UserFriendlyConfigName(type.Name); } public PluginConfigObject? GetObject() { MethodInfo? methodInfo = typeof(PluginConfigObject).GetMethod("LoadFromJsonString", BindingFlags.Public | BindingFlags.Static); MethodInfo? function = methodInfo?.MakeGenericMethod(ConfigType); return (PluginConfigObject?)function?.Invoke(this, new object[] { JsonString })!; } } }