diff --git a/Glamourer/Automation/AutoDesignApplier.cs b/Glamourer/Automation/AutoDesignApplier.cs
index 5f47780..c765584 100644
--- a/Glamourer/Automation/AutoDesignApplier.cs
+++ b/Glamourer/Automation/AutoDesignApplier.cs
@@ -156,9 +156,9 @@ public class AutoDesignApplier : IDisposable
private unsafe void Reduce(Actor actor, ActorState state, AutoDesignSet set, bool respectManual)
{
- EquipFlag totalEquipFlags = 0;
- var totalCustomizeFlags = _code.EnabledMesmer ? 0 : CustomizeFlagExtensions.RedrawRequired;
- byte totalMetaFlags = 0;
+ EquipFlag totalEquipFlags = 0;
+ CustomizeFlag totalCustomizeFlags = 0;
+ byte totalMetaFlags = 0;
foreach (var design in set.Designs)
{
if (!design.IsActive(actor))
@@ -202,7 +202,7 @@ public class AutoDesignApplier : IDisposable
if (equipFlags.HasFlag(flag))
{
var item = design.Item(slot);
- if (_code.EnabledInventory || _itemUnlocks.IsUnlocked(item.ItemId, out _))
+ if (!_config.UnlockedItemMode || _itemUnlocks.IsUnlocked(item.ItemId, out _))
{
if (!respectManual || state[slot, false] is not StateChanged.Source.Manual)
_state.ChangeItem(state, slot, item, StateChanged.Source.Fixed);
@@ -223,7 +223,7 @@ public class AutoDesignApplier : IDisposable
{
var item = design.Item(EquipSlot.MainHand);
if (state.ModelData.Item(EquipSlot.MainHand).Type == item.Type
- && (_code.EnabledInventory || _itemUnlocks.IsUnlocked(item.ItemId, out _)))
+ && (!_config.UnlockedItemMode || _itemUnlocks.IsUnlocked(item.ItemId, out _)))
{
if (!respectManual || state[EquipSlot.MainHand, false] is not StateChanged.Source.Manual)
_state.ChangeItem(state, EquipSlot.MainHand, item, StateChanged.Source.Fixed);
@@ -235,7 +235,7 @@ public class AutoDesignApplier : IDisposable
{
var item = design.Item(EquipSlot.OffHand);
if (state.ModelData.Item(EquipSlot.OffHand).Type == item.Type
- && (_code.EnabledInventory || _itemUnlocks.IsUnlocked(item.ItemId, out _)))
+ && (!_config.UnlockedItemMode || _itemUnlocks.IsUnlocked(item.ItemId, out _)))
{
if (!respectManual || state[EquipSlot.OffHand, false] is not StateChanged.Source.Manual)
_state.ChangeItem(state, EquipSlot.OffHand, item, StateChanged.Source.Fixed);
@@ -274,7 +274,6 @@ public class AutoDesignApplier : IDisposable
// Skip invalid designs entirely.
if (_config.SkipInvalidCustomizations
- && !_code.EnabledMesmer
&& (customize.Clan != design.Customize.Clan
|| customize.Gender != design.Customize.Gender
|| customize.Face != design.Customize.Face))
@@ -320,7 +319,7 @@ public class AutoDesignApplier : IDisposable
var value = design.Customize[index];
if (CustomizationService.IsCustomizationValid(set, face, index, value, out var data)
- && (_code.EnabledInventory || _customizeUnlocks.IsUnlocked(data.Value, out _)))
+ && (!_config.UnlockedItemMode || _customizeUnlocks.IsUnlocked(data.Value, out _)))
{
if (!respectManual || state[index] is not StateChanged.Source.Manual)
_state.ChangeCustomize(state, index, value, StateChanged.Source.Fixed);
diff --git a/Glamourer/Configuration.cs b/Glamourer/Configuration.cs
index 9bfe41d..f950782 100644
--- a/Glamourer/Configuration.cs
+++ b/Glamourer/Configuration.cs
@@ -27,6 +27,7 @@ public class Configuration : IPluginConfiguration, ISavable
public bool SkipInvalidCustomizations { get; set; } = false;
public bool HideApplyCheckmarks { get; set; } = false;
public bool SmallEquip { get; set; } = false;
+ public bool UnlockedItemMode { get; set; } = false;
public MainWindow.TabType SelectedTab { get; set; } = MainWindow.TabType.Settings;
public DoubleModifier DeleteDesignModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift);
@@ -86,10 +87,7 @@ public class Configuration : IPluginConfiguration, ISavable
"Error reading Configuration, reverting to default.\nYou may be able to restore your configuration using the rolling backups in the XIVLauncher/backups/Glamourer directory.",
"Error reading Configuration", "Error", NotificationType.Error);
}
- if (Codes.All(p => p.Code != CodeService.CodeInventoryString))
- Codes.Insert(0, (CodeService.CodeInventoryString, false));
- if (Codes.All(p => p.Code != CodeService.CodeMesmerString))
- Codes.Insert(0, (CodeService.CodeMesmerString, false));
+
migrator.Migrate(this);
}
diff --git a/Glamourer/Glamourer.csproj b/Glamourer/Glamourer.csproj
index 24551af..82e9962 100644
--- a/Glamourer/Glamourer.csproj
+++ b/Glamourer/Glamourer.csproj
@@ -5,8 +5,8 @@
x64
Glamourer
Glamourer
- 0.2.0.4
- 0.2.0.4
+ 0.2.0.5
+ 0.2.0.5
SoftOtter
Glamourer
Copyright © 2020
diff --git a/Glamourer/Glamourer.json b/Glamourer/Glamourer.json
index 25ead5e..2efd3a2 100644
--- a/Glamourer/Glamourer.json
+++ b/Glamourer/Glamourer.json
@@ -5,7 +5,7 @@
"Description": "Adds functionality to change and store appearance of players, customization and equip. Requires Penumbra to be installed and activated to work. Can also add preview options to the Changed Items tab for Penumbra.",
"Tags": [ "Appearance", "Glamour", "Race", "Outfit", "Armor", "Clothes", "Skins", "Customization", "Design", "Character" ],
"InternalName": "Glamourer",
- "AssemblyVersion": "0.2.0.4",
+ "AssemblyVersion": "0.2.0.5",
"RepoUrl": "https://github.com/Ottermandias/Glamourer",
"ApplicableVersion": "any",
"DalamudApiLevel": 8,
diff --git a/Glamourer/Gui/Customization/CustomizationDrawer.GenderRace.cs b/Glamourer/Gui/Customization/CustomizationDrawer.GenderRace.cs
index 059ad8d..23f8c8d 100644
--- a/Glamourer/Gui/Customization/CustomizationDrawer.GenderRace.cs
+++ b/Glamourer/Gui/Customization/CustomizationDrawer.GenderRace.cs
@@ -22,10 +22,10 @@ public partial class CustomizationDrawer
var clan = _service.AwaitedService.GetName(CustomName.Clan);
if (_withApply)
{
- if (UiHelpers.DrawCheckbox("##applyGender", "Apply gender of this design.", _currentApply, out var applyGender, _locked))
+ if (UiHelpers.DrawCheckbox("##applyGender", "Apply gender of this design.", ChangeApply.HasFlag(CustomizeFlag.Gender), out var applyGender, _locked))
ChangeApply = applyGender ? ChangeApply | CustomizeFlag.Gender : ChangeApply & ~CustomizeFlag.Gender;
ImGui.SameLine();
- if (UiHelpers.DrawCheckbox("##applyClan", "Apply clan of this design.", _currentApply, out var applyClan, _locked))
+ if (UiHelpers.DrawCheckbox("##applyClan", "Apply clan of this design.", ChangeApply.HasFlag(CustomizeFlag.Clan), out var applyClan, _locked))
ChangeApply = applyClan ? ChangeApply | CustomizeFlag.Clan : ChangeApply & ~CustomizeFlag.Clan;
ImGui.SameLine();
}
diff --git a/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs b/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs
index a6f7265..8bd9eff 100644
--- a/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs
+++ b/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs
@@ -28,6 +28,7 @@ public class SetPanel
private readonly CustomizeUnlockManager _customizeUnlocks;
private readonly CustomizationService _customizations;
+ private readonly Configuration _config;
private readonly DesignCombo _designCombo;
private readonly JobGroupCombo _jobGroupCombo;
private readonly IdentifierDrawer _identifierDrawer;
@@ -40,7 +41,7 @@ public class SetPanel
public SetPanel(SetSelector selector, AutoDesignManager manager, DesignManager designs, JobService jobs, ItemUnlockManager itemUnlocks,
CustomizeUnlockManager customizeUnlocks, CustomizationService customizations, IdentifierDrawer identifierDrawer,
- CodeService codeService)
+ CodeService codeService, Configuration config)
{
_selector = selector;
_manager = manager;
@@ -49,6 +50,7 @@ public class SetPanel
_customizations = customizations;
_identifierDrawer = identifierDrawer;
_codeService = codeService;
+ _config = config;
_designCombo = new DesignCombo(_manager, designs);
_jobGroupCombo = new JobGroupCombo(manager, jobs);
}
@@ -105,7 +107,7 @@ public class SetPanel
ImGui.TableSetupColumn("Design", ImGuiTableColumnFlags.WidthFixed, 220 * ImGuiHelpers.GlobalScale);
ImGui.TableSetupColumn("Application", ImGuiTableColumnFlags.WidthFixed, 5 * ImGui.GetFrameHeight() + 4 * 2 * ImGuiHelpers.GlobalScale);
ImGui.TableSetupColumn("Job Restrictions", ImGuiTableColumnFlags.WidthStretch);
- ImGui.TableSetupColumn("Warnings", ImGuiTableColumnFlags.WidthFixed, 4 * ImGui.GetFrameHeight() + 3 * 2 * ImGuiHelpers.GlobalScale);
+ ImGui.TableSetupColumn("Warnings", ImGuiTableColumnFlags.WidthFixed, ImGui.CalcTextSize("Warnings").X);
ImGui.TableHeadersRow();
foreach (var (design, idx) in Selection.Designs.WithIndex())
@@ -159,7 +161,7 @@ public class SetPanel
var item = design.Design.DesignData.Item(slot);
if (!_itemUnlocks.IsUnlocked(item.ItemId, out _))
- sb.AppendLine($"{item.Name} in {slot.ToName()} slot is not unlocked but should be applied.");
+ sb.AppendLine($"{item.Name} in {slot.ToName()} slot is not unlocked. Consider obtaining it via gameplay means!");
}
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, new Vector2(2 * ImGuiHelpers.GlobalScale, 0));
@@ -185,10 +187,10 @@ public class SetPanel
}
}
- var tt = _codeService.EnabledInventory
- ? "\nThese items will still be applied, because you have enabled a cheat code."
- : $"\nThese items will be skipped when applied automatically.\n\nTo change this, enable the \"{CodeService.CodeInventoryString}\" Cheat Code in Settings.";
- DrawWarning(sb, !_codeService.EnabledInventory ? 0xA03030F0 : 0x0, size, tt, "All equipment to be applied is unlocked.");
+ var tt = _config.UnlockedItemMode
+ ? "\nThese items will be skipped when applied automatically.\n\nTo change this, disable the Obtained Item Mode setting."
+ : string.Empty;
+ DrawWarning(sb, _config.UnlockedItemMode ? 0xA03030F0 : 0x0, size, tt, "All equipment to be applied is unlocked.");
sb.Clear();
var sb2 = new StringBuilder();
@@ -213,17 +215,11 @@ public class SetPanel
}
ImGui.SameLine();
- tt = _codeService.EnabledInventory
- ? "\nThese customizations will still be applied, because you have enabled a cheat code."
- : $"\nThese customizations will be skipped when applied automatically.\n\nTo change this, enable the \"{CodeService.CodeInventoryString}\" Cheat Code in Settings.";
- DrawWarning(sb2, !_codeService.EnabledInventory ? 0xA03030F0 : 0x0, size, tt, "All customizations to be applied are unlocked.");
+ tt = _config.UnlockedItemMode
+ ? "\nThese customizations will be skipped when applied automatically.\n\nTo change this, disable the Obtained Item Mode setting."
+ : string.Empty;
+ DrawWarning(sb2, _config.UnlockedItemMode ? 0xA03030F0 : 0x0, size, tt, "All customizations to be applied are unlocked.");
ImGui.SameLine();
-
- tt = _codeService.EnabledMesmer
- ? "\nThese customizations will still be applied, because you have enabled a cheat code."
- : $"\nThese customizations will be skipped when applied automatically.\n\nTo change this, enable the \"{CodeService.CodeMesmerString}\" Cheat Code in Settings.";
- DrawWarning(sb, !_codeService.EnabledMesmer ? 0xA03030F0 : 0x0, size, tt,
- "No customizations unable to be applied automatically are set to be applied."); // TODO
}
private void DrawDragDrop(AutoDesignSet set, int index)
diff --git a/Glamourer/Gui/Tabs/SettingsTab.cs b/Glamourer/Gui/Tabs/SettingsTab.cs
index e2542e1..c4cf5cb 100644
--- a/Glamourer/Gui/Tabs/SettingsTab.cs
+++ b/Glamourer/Gui/Tabs/SettingsTab.cs
@@ -50,6 +50,9 @@ public class SettingsTab : ITab
Checkbox("Restricted Gear Protection",
"Use gender- and race-appropriate models when detecting certain items not available for a characters current gender and race.",
_config.UseRestrictedGearProtection, v => _config.UseRestrictedGearProtection = v);
+ Checkbox("Unlocked Item Mode",
+ "Enable this if you want automatically applied designs to only consider items and customizations you have actually unlocked once, and skip those you have not.",
+ _config.UnlockedItemMode, v => _config.UnlockedItemMode = v);
Checkbox("Auto-Reload Gear",
"Automatically reload equipment pieces on your own character when changing any mod options in Penumbra in their associated collection.",
_config.AutoRedrawEquipOnChanges, _autoRedraw.SetState);
diff --git a/Glamourer/Services/CodeService.cs b/Glamourer/Services/CodeService.cs
index 49c1531..af94ab0 100644
--- a/Glamourer/Services/CodeService.cs
+++ b/Glamourer/Services/CodeService.cs
@@ -23,10 +23,8 @@ public class CodeService
public bool EnabledEmperor { get; private set; }
public bool EnabledIndividual { get; private set; }
public Sizing EnabledSizing { get; private set; }
- public Race EnabledOops { get; private set; }
- public bool EnabledMesmer { get; private set; }
- public bool EnabledInventory { get; private set; }
- public bool EnabledArtisan { get; private set; }
+ public Race EnabledOops { get; private set; }
+ public bool EnabledArtisan { get; private set; }
public CodeService(Configuration config)
{
@@ -42,8 +40,7 @@ public class CodeService
var enabled = CheckCode(_config.Codes[i].Code);
if (enabled == null)
{
- --i;
- _config.Codes.RemoveAt(i);
+ _config.Codes.RemoveAt(i--);
changes = true;
}
else
@@ -64,7 +61,6 @@ public class CodeService
_config.Codes.Add((name, false));
_config.Save();
return true;
-
}
public Action? CheckCode(string name)
@@ -78,7 +74,6 @@ public class CodeService
_ when CodeIndividual.SequenceEqual(sha) => v => EnabledIndividual = v,
_ when CodeDwarf.SequenceEqual(sha) => v => EnabledSizing = v ? Sizing.Dwarf : Sizing.None,
_ when CodeGiant.SequenceEqual(sha) => v => EnabledSizing = v ? Sizing.Giant : Sizing.None,
- _ when CodeMesmer.SequenceEqual(sha) => v => EnabledMesmer = v,
_ when CodeOops1.SequenceEqual(sha) => v => EnabledOops = v ? Race.Hyur : Race.Unknown,
_ when CodeOops2.SequenceEqual(sha) => v => EnabledOops = v ? Race.Elezen : Race.Unknown,
_ when CodeOops3.SequenceEqual(sha) => v => EnabledOops = v ? Race.Lalafell : Race.Unknown,
@@ -87,22 +82,17 @@ public class CodeService
_ when CodeOops6.SequenceEqual(sha) => v => EnabledOops = v ? Race.AuRa : Race.Unknown,
_ when CodeOops7.SequenceEqual(sha) => v => EnabledOops = v ? Race.Hrothgar : Race.Unknown,
_ when CodeOops8.SequenceEqual(sha) => v => EnabledOops = v ? Race.Viera : Race.Unknown,
- _ when CodeInventory.SequenceEqual(sha) => v => EnabledInventory = v,
_ when CodeArtisan.SequenceEqual(sha) => v => EnabledArtisan = v,
_ => null,
};
}
- public const string CodeInventoryString = "I found this secret cheat code and all I got was all the lousy t-shirts.";
- public const string CodeMesmerString = "With the power of cheats, you can be anything you want!";
-
// @formatter:off
private static ReadOnlySpan CodeClown => new byte[] { 0xC4, 0xEE, 0x1D, 0x6F, 0xC5, 0x5D, 0x47, 0xBE, 0x78, 0x63, 0x66, 0x86, 0x81, 0x15, 0xEB, 0xFA, 0xF6, 0x4A, 0x90, 0xEA, 0xC0, 0xE4, 0xEE, 0x86, 0x69, 0x01, 0x8E, 0xDB, 0xCC, 0x69, 0xD1, 0xBD };
private static ReadOnlySpan CodeEmperor => new byte[] { 0xE2, 0x2D, 0x3E, 0x57, 0x16, 0x82, 0x65, 0x98, 0x7E, 0xE6, 0x8F, 0x45, 0x14, 0x7D, 0x65, 0x31, 0xE9, 0xD8, 0xDB, 0xEA, 0xDC, 0xBF, 0xEE, 0x2A, 0xBA, 0xD5, 0x69, 0x96, 0x78, 0x34, 0x3B, 0x57 };
private static ReadOnlySpan CodeIndividual => new byte[] { 0x95, 0xA4, 0x71, 0xAC, 0xA3, 0xC2, 0x34, 0x94, 0xC1, 0x65, 0x07, 0xF3, 0x7F, 0x93, 0x57, 0xEE, 0xE3, 0x04, 0xC0, 0xE8, 0x1B, 0xA0, 0xE2, 0x08, 0x68, 0x02, 0x8D, 0xAD, 0x76, 0x03, 0x9B, 0xC5 };
private static ReadOnlySpan CodeDwarf => new byte[] { 0x55, 0x97, 0xFE, 0xE9, 0x78, 0x64, 0xE8, 0x2F, 0xCD, 0x25, 0xD1, 0xAE, 0xDF, 0x35, 0xE6, 0xED, 0x03, 0x78, 0x54, 0x1D, 0x56, 0x22, 0x34, 0x75, 0x4B, 0x96, 0x6F, 0xBA, 0xAC, 0xEC, 0x00, 0x46 };
private static ReadOnlySpan CodeGiant => new byte[] { 0x6E, 0xBB, 0x91, 0x1D, 0x67, 0xE3, 0x00, 0x07, 0xA1, 0x0F, 0x2A, 0xF0, 0x26, 0x91, 0x38, 0x63, 0xD3, 0x52, 0x82, 0xF7, 0x5D, 0x93, 0xE8, 0x83, 0xB1, 0xF6, 0xB9, 0x69, 0x78, 0x20, 0xC4, 0xCE };
- private static ReadOnlySpan CodeMesmer => new byte[] { 0x6A, 0x84, 0x12, 0xEA, 0x3B, 0x03, 0x2E, 0xD9, 0xA3, 0x51, 0xB0, 0x4F, 0xE7, 0x4D, 0x59, 0x87, 0xA9, 0xA1, 0x6E, 0x08, 0xC7, 0x3E, 0xD3, 0x15, 0xEE, 0x40, 0x2C, 0xB3, 0x44, 0x78, 0x1F, 0xA0 };
private static ReadOnlySpan CodeOops1 => new byte[] { 0x4C, 0x51, 0xE2, 0x38, 0xEF, 0xAD, 0x84, 0x0E, 0x4E, 0x11, 0x0F, 0x5E, 0xDE, 0x45, 0x41, 0x9F, 0x6A, 0xF6, 0x5F, 0x5B, 0xA8, 0x91, 0x64, 0x22, 0xEE, 0x62, 0x97, 0x3C, 0x78, 0x18, 0xCD, 0xAF };
private static ReadOnlySpan CodeOops2 => new byte[] { 0x3D, 0x5B, 0xA9, 0x62, 0xCE, 0xBE, 0x52, 0xF5, 0x94, 0x2A, 0xF9, 0xB7, 0xCF, 0xD9, 0x24, 0x2B, 0x38, 0xC7, 0x4F, 0x28, 0x97, 0x29, 0x1D, 0x01, 0x13, 0x53, 0x44, 0x11, 0x15, 0x6F, 0x9B, 0x56 };
private static ReadOnlySpan CodeOops3 => new byte[] { 0x85, 0x8D, 0x5B, 0xC2, 0x66, 0x53, 0x2E, 0xB9, 0xE9, 0x85, 0xE5, 0xF8, 0xD3, 0x75, 0x18, 0x7C, 0x58, 0x55, 0xD4, 0x8C, 0x8E, 0x5F, 0x58, 0x2E, 0xF3, 0xF1, 0xAE, 0xA8, 0xA0, 0x81, 0xC6, 0x0E };
@@ -111,7 +101,6 @@ public class CodeService
private static ReadOnlySpan CodeOops6 => new byte[] { 0x69, 0x93, 0xAF, 0xE4, 0xB8, 0xEC, 0x5F, 0x40, 0xEB, 0x8A, 0x6F, 0xD1, 0x9B, 0xD9, 0x56, 0x0B, 0xEA, 0x64, 0x79, 0x9B, 0x54, 0xA1, 0x41, 0xED, 0xBC, 0x3E, 0x6E, 0x5C, 0xF1, 0x23, 0x60, 0xF8 };
private static ReadOnlySpan CodeOops7 => new byte[] { 0x41, 0xEC, 0x65, 0x05, 0x8D, 0x20, 0x68, 0x5A, 0xB7, 0xEB, 0x92, 0x15, 0x43, 0xCF, 0x15, 0x05, 0x27, 0x51, 0xFE, 0x20, 0xC9, 0xB6, 0x2B, 0x84, 0xD9, 0x6A, 0x49, 0x5A, 0x5B, 0x7F, 0x2E, 0xE7 };
private static ReadOnlySpan CodeOops8 => new byte[] { 0x16, 0xFF, 0x63, 0x85, 0x1C, 0xF5, 0x34, 0x33, 0x67, 0x8C, 0x46, 0x8E, 0x3E, 0xE3, 0xA6, 0x94, 0xF9, 0x74, 0x47, 0xAA, 0xC7, 0x29, 0x59, 0x1F, 0x6C, 0x6E, 0xF2, 0xF5, 0x87, 0x24, 0x9E, 0x2B };
- private static ReadOnlySpan CodeInventory => new byte[] { 0xD1, 0x35, 0xD7, 0x18, 0xBE, 0x45, 0x42, 0xBD, 0x88, 0x77, 0x7E, 0xC4, 0x41, 0x06, 0x34, 0x4D, 0x71, 0x3A, 0xC5, 0xCC, 0xA4, 0x1B, 0x7D, 0x3F, 0x3B, 0x86, 0x07, 0xCB, 0x63, 0xD7, 0xF9, 0xDB };
private static ReadOnlySpan CodeArtisan => new byte[] { 0xDE, 0x01, 0x32, 0x1E, 0x7F, 0x22, 0x80, 0x3D, 0x76, 0xDF, 0x74, 0x0E, 0xEC, 0x33, 0xD3, 0xF4, 0x1A, 0x98, 0x9E, 0x9D, 0x22, 0x5C, 0xAC, 0x3B, 0xFE, 0x0B, 0xC2, 0x13, 0xB9, 0x91, 0x24, 0x61 };
// @formatter:on
}
diff --git a/GlamourerTest.zip b/GlamourerTest.zip
index d57e835..f41961c 100644
Binary files a/GlamourerTest.zip and b/GlamourerTest.zip differ
diff --git a/repo.json b/repo.json
index 1a910f0..5e40415 100644
--- a/repo.json
+++ b/repo.json
@@ -7,7 +7,7 @@
"Tags": [ "Appearance", "Glamour", "Race", "Outfit", "Armor", "Clothes", "Skins", "Customization", "Design", "Character" ],
"InternalName": "Glamourer",
"AssemblyVersion": "0.1.3.1",
- "TestingAssemblyVersion": "0.2.0.4",
+ "TestingAssemblyVersion": "0.2.0.5",
"RepoUrl": "https://github.com/Ottermandias/Glamourer",
"ApplicableVersion": "any",
"DalamudApiLevel": 8,