mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2026-02-17 04:57:43 +01:00
Services here, too!
This commit is contained in:
parent
1eb16b98a8
commit
85adc3626e
47 changed files with 1015 additions and 562 deletions
|
|
@ -5,6 +5,7 @@ using System.Linq;
|
|||
using Dalamud.Plugin;
|
||||
using Dalamud.Utility;
|
||||
using Glamourer.Customization;
|
||||
using Glamourer.Services;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui;
|
||||
|
|
@ -21,8 +22,9 @@ public partial class Design
|
|||
public const string DesignFolderName = "designs";
|
||||
public readonly string DesignFolder;
|
||||
|
||||
private readonly FrameworkManager _framework;
|
||||
private readonly List<Design> _designs = new();
|
||||
private readonly ItemManager _items;
|
||||
private readonly SaveService _saveService;
|
||||
private readonly List<Design> _designs = new();
|
||||
|
||||
public enum DesignChangeType
|
||||
{
|
||||
|
|
@ -50,9 +52,10 @@ public partial class Design
|
|||
public IReadOnlyList<Design> Designs
|
||||
=> _designs;
|
||||
|
||||
public Manager(DalamudPluginInterface pi, FrameworkManager framework)
|
||||
public Manager(DalamudPluginInterface pi, SaveService saveService, ItemManager items)
|
||||
{
|
||||
_framework = framework;
|
||||
_saveService = saveService;
|
||||
_items = items;
|
||||
DesignFolder = SetDesignFolder(pi);
|
||||
DesignChange += OnChange;
|
||||
LoadDesigns();
|
||||
|
|
@ -105,7 +108,7 @@ public partial class Design
|
|||
=> Path.Combine(DesignFolder, $"{design.Identifier}.json");
|
||||
|
||||
public void SaveDesign(Design design)
|
||||
=> _framework.RegisterDelayed($"{nameof(SaveDesign)}_{design.Identifier}", () => SaveDesignInternal(design));
|
||||
=> _saveService.QueueSave(design);
|
||||
|
||||
private void SaveDesignInternal(Design design)
|
||||
{
|
||||
|
|
@ -133,7 +136,7 @@ public partial class Design
|
|||
{
|
||||
var text = File.ReadAllText(file.FullName);
|
||||
var data = JObject.Parse(text);
|
||||
var design = LoadDesign(data, out var changes);
|
||||
var design = LoadDesign(_items, data, out var changes);
|
||||
if (design.Identifier.ToString() != Path.GetFileNameWithoutExtension(file.Name))
|
||||
invalidNames.Add((design, file.FullName));
|
||||
if (_designs.Any(f => f.Identifier == design.Identifier))
|
||||
|
|
@ -177,7 +180,7 @@ public partial class Design
|
|||
|
||||
public Design Create(string name)
|
||||
{
|
||||
var design = new Design()
|
||||
var design = new Design(_items)
|
||||
{
|
||||
CreationDate = DateTimeOffset.UtcNow,
|
||||
Identifier = CreateNewGuid(),
|
||||
|
|
@ -297,7 +300,7 @@ public partial class Design
|
|||
public void ChangeEquip(Design design, EquipSlot slot, uint itemId, Lumina.Excel.GeneratedSheets.Item? item = null)
|
||||
{
|
||||
var old = design.Armor(slot);
|
||||
if (design.SetArmor(slot, itemId, item))
|
||||
if (design.SetArmor(_items, slot, itemId, item))
|
||||
{
|
||||
var n = design.Armor(slot);
|
||||
Glamourer.Log.Debug(
|
||||
|
|
@ -309,8 +312,8 @@ public partial class Design
|
|||
public void ChangeWeapon(Design design, uint itemId, EquipSlot offhand, Lumina.Excel.GeneratedSheets.Item? item = null)
|
||||
{
|
||||
var (old, change, n) = offhand == EquipSlot.OffHand
|
||||
? (design.WeaponOff, design.SetOffhand(itemId, item), design.WeaponOff)
|
||||
: (design.WeaponMain, design.SetMainhand(itemId, item), design.WeaponMain);
|
||||
? (design.WeaponOff, design.SetOffhand(_items, itemId, item), design.WeaponOff)
|
||||
: (design.WeaponMain, design.SetMainhand(_items, itemId, item), design.WeaponMain);
|
||||
if (change)
|
||||
{
|
||||
Glamourer.Log.Debug(
|
||||
|
|
@ -386,13 +389,13 @@ public partial class Design
|
|||
try
|
||||
{
|
||||
var actualName = Path.GetFileName(name);
|
||||
var design = new Design()
|
||||
var design = new Design(_items)
|
||||
{
|
||||
CreationDate = DateTimeOffset.UtcNow,
|
||||
Identifier = CreateNewGuid(),
|
||||
Name = actualName,
|
||||
};
|
||||
design.MigrateBase64(base64);
|
||||
design.MigrateBase64(_items, base64);
|
||||
Add(design, $"Migrated old design to {design.Identifier}.");
|
||||
migratedFileSystemPaths.Add(design.Identifier.ToString(), name);
|
||||
++successes;
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Glamourer.Customization;
|
||||
using Glamourer.Util;
|
||||
using Glamourer.Services;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui;
|
||||
using OtterGui.Classes;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
|
||||
namespace Glamourer.Designs;
|
||||
|
||||
public partial class Design : DesignBase
|
||||
public partial class Design : DesignBase, ISavable
|
||||
{
|
||||
public const int FileVersion = 1;
|
||||
|
||||
|
|
@ -69,7 +70,8 @@ public partial class Design : DesignBase
|
|||
}
|
||||
|
||||
|
||||
private Design()
|
||||
private Design(ItemManager items)
|
||||
: base(items)
|
||||
{ }
|
||||
|
||||
public JObject JsonSerialize()
|
||||
|
|
@ -142,17 +144,17 @@ public partial class Design : DesignBase
|
|||
return ret;
|
||||
}
|
||||
|
||||
public static Design LoadDesign(JObject json, out bool changes)
|
||||
public static Design LoadDesign(ItemManager items, JObject json, out bool changes)
|
||||
{
|
||||
var version = json[nameof(FileVersion)]?.ToObject<int>() ?? 0;
|
||||
return version switch
|
||||
{
|
||||
1 => LoadDesignV1(json, out changes),
|
||||
1 => LoadDesignV1(items, json, out changes),
|
||||
_ => throw new Exception("The design to be loaded has no valid Version."),
|
||||
};
|
||||
}
|
||||
|
||||
private static Design LoadDesignV1(JObject json, out bool changes)
|
||||
private static Design LoadDesignV1(ItemManager items, JObject json, out bool changes)
|
||||
{
|
||||
static string[] ParseTags(JObject json)
|
||||
{
|
||||
|
|
@ -160,7 +162,7 @@ public partial class Design : DesignBase
|
|||
return tags.OrderBy(t => t).Distinct().ToArray();
|
||||
}
|
||||
|
||||
var design = new Design()
|
||||
var design = new Design(items)
|
||||
{
|
||||
CreationDate = json["CreationDate"]?.ToObject<DateTimeOffset>() ?? throw new ArgumentNullException("CreationDate"),
|
||||
Identifier = json["Identifier"]?.ToObject<Guid>() ?? throw new ArgumentNullException("Identifier"),
|
||||
|
|
@ -169,12 +171,12 @@ public partial class Design : DesignBase
|
|||
Tags = ParseTags(json),
|
||||
};
|
||||
|
||||
changes = LoadEquip(json["Equipment"], design);
|
||||
changes = LoadEquip(items, json["Equipment"], design);
|
||||
changes |= LoadCustomize(json["Customize"], design);
|
||||
return design;
|
||||
}
|
||||
|
||||
private static bool LoadEquip(JToken? equip, Design design)
|
||||
private static bool LoadEquip(ItemManager items, JToken? equip, Design design)
|
||||
{
|
||||
if (equip == null)
|
||||
return true;
|
||||
|
|
@ -192,7 +194,7 @@ public partial class Design : DesignBase
|
|||
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
||||
{
|
||||
var (id, stain, apply, applyStain) = ParseItem(slot, equip[slot.ToString()]);
|
||||
changes |= !design.SetArmor(slot, id);
|
||||
changes |= !design.SetArmor(items, slot, id);
|
||||
changes |= !design.SetStain(slot, stain);
|
||||
design.SetApplyEquip(slot, apply);
|
||||
design.SetApplyStain(slot, applyStain);
|
||||
|
|
@ -205,11 +207,11 @@ public partial class Design : DesignBase
|
|||
}
|
||||
else
|
||||
{
|
||||
var id = main["ItemId"]?.ToObject<uint>() ?? Glamourer.Items.DefaultSword.RowId;
|
||||
var id = main["ItemId"]?.ToObject<uint>() ?? items.DefaultSword.RowId;
|
||||
var stain = (StainId)(main["Stain"]?.ToObject<byte>() ?? 0);
|
||||
var apply = main["Apply"]?.ToObject<bool>() ?? false;
|
||||
var applyStain = main["ApplyStain"]?.ToObject<bool>() ?? false;
|
||||
changes |= !design.SetMainhand(id);
|
||||
changes |= !design.SetMainhand(items, id);
|
||||
changes |= !design.SetStain(EquipSlot.MainHand, stain);
|
||||
design.SetApplyEquip(EquipSlot.MainHand, apply);
|
||||
design.SetApplyStain(EquipSlot.MainHand, applyStain);
|
||||
|
|
@ -226,7 +228,7 @@ public partial class Design : DesignBase
|
|||
var stain = (StainId)(off["Stain"]?.ToObject<byte>() ?? 0);
|
||||
var apply = off["Apply"]?.ToObject<bool>() ?? false;
|
||||
var applyStain = off["ApplyStain"]?.ToObject<bool>() ?? false;
|
||||
changes |= !design.SetOffhand(id);
|
||||
changes |= !design.SetOffhand(items, id);
|
||||
changes |= !design.SetStain(EquipSlot.OffHand, stain);
|
||||
design.SetApplyEquip(EquipSlot.OffHand, apply);
|
||||
design.SetApplyStain(EquipSlot.OffHand, applyStain);
|
||||
|
|
@ -259,14 +261,14 @@ public partial class Design : DesignBase
|
|||
return false;
|
||||
}
|
||||
|
||||
public void MigrateBase64(string base64)
|
||||
public void MigrateBase64(ItemManager items, string base64)
|
||||
{
|
||||
var data = MigrateBase64(base64, out var applyEquip, out var applyCustomize, out var writeProtected, out var wet, out var hat,
|
||||
out var visor, out var weapon);
|
||||
UpdateMainhand(data.MainHand);
|
||||
UpdateMainhand(data.OffHand);
|
||||
UpdateMainhand(items, data.MainHand);
|
||||
UpdateOffhand(items, data.OffHand);
|
||||
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
||||
UpdateArmor(slot, data.Equipment[slot], true);
|
||||
UpdateArmor(items, slot, data.Equipment[slot], true);
|
||||
CharacterData.CustomizeData = data.CustomizeData;
|
||||
ApplyEquip = applyEquip;
|
||||
ApplyCustomize = applyCustomize;
|
||||
|
|
@ -277,10 +279,10 @@ public partial class Design : DesignBase
|
|||
Weapon = weapon;
|
||||
}
|
||||
|
||||
public static Design CreateTemporaryFromBase64(string base64, bool customize, bool equip)
|
||||
public static Design CreateTemporaryFromBase64(ItemManager items, string base64, bool customize, bool equip)
|
||||
{
|
||||
var ret = new Design();
|
||||
ret.MigrateBase64(base64);
|
||||
var ret = new Design(items);
|
||||
ret.MigrateBase64(items, base64);
|
||||
if (!customize)
|
||||
ret.ApplyCustomize = 0;
|
||||
if (!equip)
|
||||
|
|
@ -296,4 +298,20 @@ public partial class Design : DesignBase
|
|||
public string CreateOldBase64()
|
||||
=> CreateOldBase64(in CharacterData, ApplyEquip, ApplyCustomize, Wetness == QuadBool.True, Hat.ForcedValue, Hat.Enabled,
|
||||
Visor.ForcedValue, Visor.Enabled, Weapon.ForcedValue, Weapon.Enabled, WriteProtected, 1f);
|
||||
|
||||
public string ToFilename(FilenameService fileNames)
|
||||
=> fileNames.DesignFile(this);
|
||||
|
||||
public void Save(StreamWriter writer)
|
||||
{
|
||||
using var j = new JsonTextWriter(writer)
|
||||
{
|
||||
Formatting = Formatting.Indented,
|
||||
};
|
||||
var obj = JsonSerialize();
|
||||
obj.WriteTo(j);
|
||||
}
|
||||
|
||||
public string LogName(string fileName)
|
||||
=> Path.GetFileNameWithoutExtension(fileName);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using Glamourer.Customization;
|
||||
using Glamourer.Services;
|
||||
using Glamourer.Util;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui;
|
||||
|
|
@ -45,14 +46,14 @@ public class DesignBase
|
|||
public CharacterEquip Equipment()
|
||||
=> CharacterData.Equipment;
|
||||
|
||||
public DesignBase()
|
||||
public DesignBase(ItemManager items)
|
||||
{
|
||||
MainHand = Glamourer.Items.DefaultSword.RowId;
|
||||
MainHand = items.DefaultSword.RowId;
|
||||
(_, CharacterData.MainHand.Set, CharacterData.MainHand.Type, CharacterData.MainHand.Variant, MainhandName, MainhandType) =
|
||||
Glamourer.Items.Resolve(MainHand, Glamourer.Items.DefaultSword);
|
||||
items.Resolve(MainHand, items.DefaultSword);
|
||||
OffHand = ItemManager.NothingId(MainhandType.Offhand());
|
||||
(_, CharacterData.OffHand.Set, CharacterData.OffHand.Type, CharacterData.OffHand.Variant, OffhandName, _) =
|
||||
Glamourer.Items.Resolve(OffHand, MainhandType);
|
||||
items.Resolve(OffHand, MainhandType);
|
||||
}
|
||||
|
||||
public uint ModelId
|
||||
|
|
@ -96,9 +97,9 @@ public class DesignBase
|
|||
return true;
|
||||
}
|
||||
|
||||
protected bool SetArmor(EquipSlot slot, uint itemId, Lumina.Excel.GeneratedSheets.Item? item = null)
|
||||
protected bool SetArmor(ItemManager items, EquipSlot slot, uint itemId, Lumina.Excel.GeneratedSheets.Item? item = null)
|
||||
{
|
||||
var (valid, set, variant, name) = Glamourer.Items.Resolve(slot, itemId, item);
|
||||
var (valid, set, variant, name) = items.Resolve(slot, itemId, item);
|
||||
if (!valid)
|
||||
return false;
|
||||
|
||||
|
|
@ -108,7 +109,7 @@ public class DesignBase
|
|||
protected bool SetArmor(EquipSlot slot, Item item)
|
||||
=> SetArmor(slot, item.ModelBase, item.Variant, item.Name, item.ItemId);
|
||||
|
||||
protected bool UpdateArmor(EquipSlot slot, CharacterArmor armor, bool force)
|
||||
protected bool UpdateArmor(ItemManager items, EquipSlot slot, CharacterArmor armor, bool force)
|
||||
{
|
||||
if (!force)
|
||||
switch (slot)
|
||||
|
|
@ -125,19 +126,19 @@ public class DesignBase
|
|||
case EquipSlot.LFinger when CharacterData.LFinger.Value == armor.Value: return false;
|
||||
}
|
||||
|
||||
var (valid, id, name) = Glamourer.Items.Identify(slot, armor.Set, armor.Variant);
|
||||
var (valid, id, name) = items.Identify(slot, armor.Set, armor.Variant);
|
||||
if (!valid)
|
||||
return false;
|
||||
|
||||
return SetArmor(slot, armor.Set, armor.Variant, name, id);
|
||||
}
|
||||
|
||||
protected bool SetMainhand(uint mainId, Lumina.Excel.GeneratedSheets.Item? main = null)
|
||||
protected bool SetMainhand(ItemManager items, uint mainId, Lumina.Excel.GeneratedSheets.Item? main = null)
|
||||
{
|
||||
if (mainId == MainHand)
|
||||
return false;
|
||||
|
||||
var (valid, set, weapon, variant, name, type) = Glamourer.Items.Resolve(mainId, main);
|
||||
var (valid, set, weapon, variant, name, type) = items.Resolve(mainId, main);
|
||||
if (!valid)
|
||||
return false;
|
||||
|
||||
|
|
@ -150,16 +151,16 @@ public class DesignBase
|
|||
CharacterData.MainHand.Type = weapon;
|
||||
CharacterData.MainHand.Variant = variant;
|
||||
if (fixOffhand)
|
||||
SetOffhand(ItemManager.NothingId(type.Offhand()));
|
||||
SetOffhand(items, ItemManager.NothingId(type.Offhand()));
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool SetOffhand(uint offId, Lumina.Excel.GeneratedSheets.Item? off = null)
|
||||
protected bool SetOffhand(ItemManager items, uint offId, Lumina.Excel.GeneratedSheets.Item? off = null)
|
||||
{
|
||||
if (offId == OffHand)
|
||||
return false;
|
||||
|
||||
var (valid, set, weapon, variant, name, type) = Glamourer.Items.Resolve(offId, MainhandType, off);
|
||||
var (valid, set, weapon, variant, name, type) = items.Resolve(offId, MainhandType, off);
|
||||
if (!valid)
|
||||
return false;
|
||||
|
||||
|
|
@ -171,12 +172,12 @@ public class DesignBase
|
|||
return true;
|
||||
}
|
||||
|
||||
protected bool UpdateMainhand(CharacterWeapon weapon)
|
||||
protected bool UpdateMainhand(ItemManager items, CharacterWeapon weapon)
|
||||
{
|
||||
if (weapon.Value == CharacterData.MainHand.Value)
|
||||
return false;
|
||||
|
||||
var (valid, id, name, type) = Glamourer.Items.Identify(EquipSlot.MainHand, weapon.Set, weapon.Type, (byte)weapon.Variant);
|
||||
var (valid, id, name, type) = items.Identify(EquipSlot.MainHand, weapon.Set, weapon.Type, (byte)weapon.Variant);
|
||||
if (!valid || id == MainHand)
|
||||
return false;
|
||||
|
||||
|
|
@ -190,16 +191,16 @@ public class DesignBase
|
|||
CharacterData.MainHand.Variant = weapon.Variant;
|
||||
CharacterData.MainHand.Stain = weapon.Stain;
|
||||
if (fixOffhand)
|
||||
SetOffhand(ItemManager.NothingId(type.Offhand()));
|
||||
SetOffhand(items, ItemManager.NothingId(type.Offhand()));
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool UpdateOffhand(CharacterWeapon weapon)
|
||||
protected bool UpdateOffhand(ItemManager items, CharacterWeapon weapon)
|
||||
{
|
||||
if (weapon.Value == CharacterData.OffHand.Value)
|
||||
return false;
|
||||
|
||||
var (valid, id, name, _) = Glamourer.Items.Identify(EquipSlot.OffHand, weapon.Set, weapon.Type, (byte)weapon.Variant, MainhandType);
|
||||
var (valid, id, name, _) = items.Identify(EquipSlot.OffHand, weapon.Set, weapon.Type, (byte)weapon.Variant, MainhandType);
|
||||
if (!valid || id == OffHand)
|
||||
return false;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Dalamud.Plugin;
|
||||
using Glamourer.Services;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui.Classes;
|
||||
|
|
@ -12,20 +13,20 @@ using OtterGui.Filesystem;
|
|||
|
||||
namespace Glamourer.Designs;
|
||||
|
||||
public sealed class DesignFileSystem : FileSystem<Design>, IDisposable
|
||||
public sealed class DesignFileSystem : FileSystem<Design>, IDisposable, ISavable
|
||||
{
|
||||
public static string GetDesignFileSystemFile(DalamudPluginInterface pi)
|
||||
=> Path.Combine(pi.GetPluginConfigDirectory(), "sort_order.json");
|
||||
|
||||
public readonly string DesignFileSystemFile;
|
||||
private readonly FrameworkManager _framework;
|
||||
private readonly Design.Manager _designManager;
|
||||
public readonly string DesignFileSystemFile;
|
||||
private readonly SaveService _saveService;
|
||||
private readonly Design.Manager _designManager;
|
||||
|
||||
public DesignFileSystem(Design.Manager designManager, DalamudPluginInterface pi, FrameworkManager framework)
|
||||
public DesignFileSystem(Design.Manager designManager, DalamudPluginInterface pi, SaveService saveService)
|
||||
{
|
||||
DesignFileSystemFile = GetDesignFileSystemFile(pi);
|
||||
_designManager = designManager;
|
||||
_framework = framework;
|
||||
_saveService = saveService;
|
||||
_designManager.DesignChange += OnDataChange;
|
||||
Changed += OnChange;
|
||||
Reload();
|
||||
|
|
@ -34,7 +35,7 @@ public sealed class DesignFileSystem : FileSystem<Design>, IDisposable
|
|||
private void Reload()
|
||||
{
|
||||
if (Load(new FileInfo(DesignFileSystemFile), _designManager.Designs, DesignToIdentifier, DesignToName))
|
||||
SaveFilesystem();
|
||||
_saveService.ImmediateSave(this);
|
||||
|
||||
Glamourer.Log.Debug("Reloaded design filesystem.");
|
||||
}
|
||||
|
|
@ -71,18 +72,9 @@ public sealed class DesignFileSystem : FileSystem<Design>, IDisposable
|
|||
private void OnChange(FileSystemChangeType type, IPath _1, IPath? _2, IPath? _3)
|
||||
{
|
||||
if (type != FileSystemChangeType.Reload)
|
||||
SaveFilesystem();
|
||||
_saveService.QueueSave(this);
|
||||
}
|
||||
|
||||
private void SaveFilesystem()
|
||||
{
|
||||
SaveToFile(new FileInfo(DesignFileSystemFile), SaveDesign, true);
|
||||
Glamourer.Log.Verbose("Saved design filesystem.");
|
||||
}
|
||||
|
||||
public void Save()
|
||||
=> _framework.RegisterDelayed(nameof(SaveFilesystem), SaveFilesystem);
|
||||
|
||||
private void OnDataChange(Design.Manager.DesignChangeType type, Design design, object? data)
|
||||
{
|
||||
switch (type)
|
||||
|
|
@ -176,4 +168,12 @@ public sealed class DesignFileSystem : FileSystem<Design>, IDisposable
|
|||
Glamourer.Log.Error($"Could not migrate old folder paths to new version:\n{ex}");
|
||||
}
|
||||
}
|
||||
|
||||
public string ToFilename(FilenameService fileNames)
|
||||
=> fileNames.DesignFileSystem;
|
||||
|
||||
public void Save(StreamWriter writer)
|
||||
{
|
||||
SaveToFile(writer, SaveDesign, true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue