mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2026-02-22 23:47:45 +01:00
.
This commit is contained in:
parent
7710cfadfa
commit
2d6fd6015d
88 changed files with 2304 additions and 383 deletions
30
GlamourerOld/Services/BackupService.cs
Normal file
30
GlamourerOld/Services/BackupService.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Log;
|
||||
|
||||
namespace Glamourer.Services;
|
||||
|
||||
public class BackupService
|
||||
{
|
||||
public BackupService(Logger logger, FilenameService fileNames)
|
||||
{
|
||||
var files = GlamourerFiles(fileNames);
|
||||
Backup.CreateBackup(logger, new DirectoryInfo(fileNames.ConfigDirectory), files);
|
||||
}
|
||||
|
||||
/// <summary> Collect all relevant files for glamourer configuration. </summary>
|
||||
private static IReadOnlyList<FileInfo> GlamourerFiles(FilenameService fileNames)
|
||||
{
|
||||
var list = new List<FileInfo>(16)
|
||||
{
|
||||
new(fileNames.ConfigFile),
|
||||
new(fileNames.DesignFileSystem),
|
||||
new(fileNames.MigrationDesignFile),
|
||||
};
|
||||
|
||||
list.AddRange(fileNames.Designs());
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
36
GlamourerOld/Services/CommandService.cs
Normal file
36
GlamourerOld/Services/CommandService.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using Dalamud.Game.Command;
|
||||
using Glamourer.Gui;
|
||||
|
||||
namespace Glamourer.Services;
|
||||
|
||||
public class CommandService : IDisposable
|
||||
{
|
||||
private const string HelpString = "[Copy|Apply|Save],[Name or PlaceHolder],<Name for Save>";
|
||||
private const string MainCommandString = "/glamourer";
|
||||
private const string ApplyCommandString = "/glamour";
|
||||
|
||||
private readonly CommandManager _commands;
|
||||
private readonly Interface _interface;
|
||||
|
||||
public CommandService(CommandManager commands, Interface ui)
|
||||
{
|
||||
_commands = commands;
|
||||
_interface = ui;
|
||||
|
||||
_commands.AddHandler(MainCommandString, new CommandInfo(OnGlamourer) { HelpMessage = "Open or close the Glamourer window." });
|
||||
_commands.AddHandler(ApplyCommandString, new CommandInfo(OnGlamour) { HelpMessage = $"Use Glamourer Functions: {HelpString}" });
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_commands.RemoveHandler(MainCommandString);
|
||||
_commands.RemoveHandler(ApplyCommandString);
|
||||
}
|
||||
|
||||
private void OnGlamourer(string command, string arguments)
|
||||
=> _interface.Toggle();
|
||||
|
||||
private void OnGlamour(string command, string arguments)
|
||||
{ }
|
||||
}
|
||||
40
GlamourerOld/Services/FilenameService.cs
Normal file
40
GlamourerOld/Services/FilenameService.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Dalamud.Plugin;
|
||||
using Glamourer.Designs;
|
||||
|
||||
namespace Glamourer.Services;
|
||||
|
||||
public class FilenameService
|
||||
{
|
||||
public readonly string ConfigDirectory;
|
||||
public readonly string ConfigFile;
|
||||
public readonly string DesignFileSystem;
|
||||
public readonly string MigrationDesignFile;
|
||||
public readonly string DesignDirectory;
|
||||
|
||||
public FilenameService(DalamudPluginInterface pi)
|
||||
{
|
||||
ConfigDirectory = pi.ConfigDirectory.FullName;
|
||||
ConfigFile = pi.ConfigFile.FullName;
|
||||
DesignFileSystem = Path.Combine(ConfigDirectory, "sort_order.json");
|
||||
MigrationDesignFile = Path.Combine(ConfigDirectory, "Designs.json");
|
||||
DesignDirectory = Path.Combine(ConfigDirectory, "designs");
|
||||
}
|
||||
|
||||
public IEnumerable<FileInfo> Designs()
|
||||
{
|
||||
if (!Directory.Exists(DesignDirectory))
|
||||
yield break;
|
||||
|
||||
foreach (var file in Directory.EnumerateFiles(DesignDirectory, "*.json", SearchOption.TopDirectoryOnly))
|
||||
yield return new FileInfo(file);
|
||||
}
|
||||
|
||||
public string DesignFile(Design design)
|
||||
=> DesignFile(design.Identifier.ToString());
|
||||
|
||||
public string DesignFile(string identifier)
|
||||
=> Path.Combine(DesignDirectory, $"{identifier}.json");
|
||||
}
|
||||
189
GlamourerOld/Services/ItemManager.cs
Normal file
189
GlamourerOld/Services/ItemManager.cs
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Dalamud.Data;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Utility;
|
||||
using Lumina.Excel;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using Lumina.Text;
|
||||
using Penumbra.GameData.Data;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Race = Penumbra.GameData.Enums.Race;
|
||||
|
||||
namespace Glamourer.Services;
|
||||
|
||||
public class ItemManager : IDisposable
|
||||
{
|
||||
public const string Nothing = "Nothing";
|
||||
public const string SmallClothesNpc = "Smallclothes (NPC)";
|
||||
public const ushort SmallClothesNpcModel = 9903;
|
||||
|
||||
private readonly Configuration _config;
|
||||
public readonly IdentifierService IdentifierService;
|
||||
public readonly ExcelSheet<Item> ItemSheet;
|
||||
public readonly StainData Stains;
|
||||
public readonly ItemService ItemService;
|
||||
public readonly RestrictedGear RestrictedGear;
|
||||
|
||||
public ItemManager(DalamudPluginInterface pi, DataManager gameData, IdentifierService identifierService, ItemService itemService, Configuration config)
|
||||
{
|
||||
_config = config;
|
||||
ItemSheet = gameData.GetExcelSheet<Item>()!;
|
||||
IdentifierService = identifierService;
|
||||
Stains = new StainData(pi, gameData, gameData.Language);
|
||||
ItemService = itemService;
|
||||
RestrictedGear = new RestrictedGear(pi, gameData.Language, gameData);
|
||||
DefaultSword = ItemSheet.GetRow(1601)!; // Weathered Shortsword
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Stains.Dispose();
|
||||
RestrictedGear.Dispose();
|
||||
}
|
||||
|
||||
public (bool, CharacterArmor) ResolveRestrictedGear(CharacterArmor armor, EquipSlot slot, Race race, Gender gender)
|
||||
{
|
||||
if (_config.UseRestrictedGearProtection)
|
||||
return RestrictedGear.ResolveRestricted(armor, slot, race, gender);
|
||||
|
||||
return (false, armor);
|
||||
}
|
||||
|
||||
public readonly Item DefaultSword;
|
||||
|
||||
public static uint NothingId(EquipSlot slot)
|
||||
=> uint.MaxValue - 128 - (uint)slot.ToSlot();
|
||||
|
||||
public static uint SmallclothesId(EquipSlot slot)
|
||||
=> uint.MaxValue - 256 - (uint)slot.ToSlot();
|
||||
|
||||
public static uint NothingId(FullEquipType type)
|
||||
=> uint.MaxValue - 384 - (uint)type;
|
||||
|
||||
public static Designs.Item NothingItem(EquipSlot slot)
|
||||
{
|
||||
Debug.Assert(slot.IsEquipment() || slot.IsAccessory(), $"Called {nameof(NothingItem)} on {slot}.");
|
||||
return new Designs.Item(Nothing, NothingId(slot), CharacterArmor.Empty);
|
||||
}
|
||||
|
||||
public static Designs.Weapon NothingItem(FullEquipType type)
|
||||
{
|
||||
Debug.Assert(type.ToSlot() == EquipSlot.OffHand, $"Called {nameof(NothingItem)} on {type}.");
|
||||
return new Designs.Weapon(Nothing, NothingId(type), CharacterWeapon.Empty, type);
|
||||
}
|
||||
|
||||
public static Designs.Item SmallClothesItem(EquipSlot slot)
|
||||
{
|
||||
Debug.Assert(slot.IsEquipment(), $"Called {nameof(SmallClothesItem)} on {slot}.");
|
||||
return new Designs.Item(SmallClothesNpc, SmallclothesId(slot), new CharacterArmor(SmallClothesNpcModel, 1, 0));
|
||||
}
|
||||
|
||||
public (bool Valid, SetId Id, byte Variant, string ItemName) Resolve(EquipSlot slot, uint itemId, Item? item = null)
|
||||
{
|
||||
slot = slot.ToSlot();
|
||||
if (itemId == NothingId(slot))
|
||||
return (true, 0, 0, Nothing);
|
||||
if (itemId == SmallclothesId(slot))
|
||||
return (true, SmallClothesNpcModel, 1, SmallClothesNpc);
|
||||
|
||||
if (item == null || item.RowId != itemId)
|
||||
item = ItemSheet.GetRow(itemId);
|
||||
|
||||
if (item == null)
|
||||
return (false, 0, 0, string.Intern($"Unknown #{itemId}"));
|
||||
if (item.ToEquipType().ToSlot() != slot)
|
||||
return (false, 0, 0, string.Intern($"Invalid ({item.Name.ToDalamudString()})"));
|
||||
|
||||
return (true, (SetId)item.ModelMain, (byte)(item.ModelMain >> 16), string.Intern(item.Name.ToDalamudString().TextValue));
|
||||
}
|
||||
|
||||
public (bool Valid, SetId Id, WeaponType Weapon, byte Variant, string ItemName, FullEquipType Type) Resolve(uint itemId, Item? item = null)
|
||||
{
|
||||
if (item == null || item.RowId != itemId)
|
||||
item = ItemSheet.GetRow(itemId);
|
||||
|
||||
if (item == null)
|
||||
return (false, 0, 0, 0, string.Intern($"Unknown #{itemId}"), FullEquipType.Unknown);
|
||||
|
||||
var type = item.ToEquipType();
|
||||
if (type.ToSlot() != EquipSlot.MainHand)
|
||||
return (false, 0, 0, 0, string.Intern($"Invalid ({item.Name.ToDalamudString()})"), type);
|
||||
|
||||
return (true, (SetId)item.ModelMain, (WeaponType)(item.ModelMain >> 16), (byte)(item.ModelMain >> 32),
|
||||
string.Intern(item.Name.ToDalamudString().TextValue), type);
|
||||
}
|
||||
|
||||
public (bool Valid, SetId Id, WeaponType Weapon, byte Variant, string ItemName, FullEquipType Type) Resolve(uint itemId,
|
||||
FullEquipType mainType, Item? item = null)
|
||||
{
|
||||
var offType = mainType.Offhand();
|
||||
if (itemId == NothingId(offType))
|
||||
return (true, 0, 0, 0, Nothing, offType);
|
||||
|
||||
if (item == null || item.RowId != itemId)
|
||||
item = ItemSheet.GetRow(itemId);
|
||||
|
||||
if (item == null)
|
||||
return (false, 0, 0, 0, string.Intern($"Unknown #{itemId}"), FullEquipType.Unknown);
|
||||
|
||||
|
||||
var type = item.ToEquipType();
|
||||
if (offType != type)
|
||||
return (false, 0, 0, 0, string.Intern($"Invalid ({item.Name.ToDalamudString()})"), type);
|
||||
|
||||
var (m, w, v) = offType.ToSlot() == EquipSlot.MainHand
|
||||
? ((SetId)item.ModelSub, (WeaponType)(item.ModelSub >> 16), (byte)(item.ModelSub >> 32))
|
||||
: ((SetId)item.ModelMain, (WeaponType)(item.ModelMain >> 16), (byte)(item.ModelMain >> 32));
|
||||
|
||||
return (true, m, w, v, string.Intern(item.Name.ToDalamudString().TextValue), type);
|
||||
}
|
||||
|
||||
public (bool Valid, uint ItemId, string ItemName) Identify(EquipSlot slot, SetId id, byte variant)
|
||||
{
|
||||
slot = slot.ToSlot();
|
||||
if (!slot.IsEquipmentPiece())
|
||||
return (false, 0, string.Intern($"Unknown ({id.Value}-{variant})"));
|
||||
|
||||
switch (id.Value)
|
||||
{
|
||||
case 0: return (true, NothingId(slot), Nothing);
|
||||
case SmallClothesNpcModel: return (true, SmallclothesId(slot), SmallClothesNpc);
|
||||
default:
|
||||
var item = IdentifierService.AwaitedService.Identify(id, variant, slot).FirstOrDefault();
|
||||
return item == null
|
||||
? (false, 0, string.Intern($"Unknown ({id.Value}-{variant})"))
|
||||
: (true, item.RowId, string.Intern(item.Name.ToDalamudString().TextValue));
|
||||
}
|
||||
}
|
||||
|
||||
public (bool Valid, uint ItemId, string ItemName, FullEquipType Type) Identify(EquipSlot slot, SetId id, WeaponType type, byte variant,
|
||||
FullEquipType mainhandType = FullEquipType.Unknown)
|
||||
{
|
||||
switch (slot)
|
||||
{
|
||||
case EquipSlot.MainHand:
|
||||
{
|
||||
var item = IdentifierService.AwaitedService.Identify(id, type, variant, slot).FirstOrDefault();
|
||||
return item != null
|
||||
? (true, item.RowId, string.Intern(item.Name.ToDalamudString().TextValue), item.ToEquipType())
|
||||
: (false, 0, string.Intern($"Unknown ({id.Value}-{type.Value}-{variant})"), mainhandType);
|
||||
}
|
||||
case EquipSlot.OffHand:
|
||||
{
|
||||
var weaponType = mainhandType.Offhand();
|
||||
if (id.Value == 0)
|
||||
return (true, NothingId(weaponType), Nothing, weaponType);
|
||||
|
||||
var item = IdentifierService.AwaitedService.Identify(id, type, variant, slot).FirstOrDefault();
|
||||
return item != null
|
||||
? (true, item.RowId, string.Intern(item.Name.ToDalamudString().TextValue), item.ToEquipType())
|
||||
: (false, 0, string.Intern($"Unknown ({id.Value}-{type.Value}-{variant})"),
|
||||
weaponType);
|
||||
}
|
||||
default: return (false, 0, string.Intern($"Unknown ({id.Value}-{type.Value}-{variant})"), FullEquipType.Unknown);
|
||||
}
|
||||
}
|
||||
}
|
||||
97
GlamourerOld/Services/SaveService.cs
Normal file
97
GlamourerOld/Services/SaveService.cs
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Log;
|
||||
|
||||
namespace Glamourer.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Any file type that we want to save via SaveService.
|
||||
/// </summary>
|
||||
public interface ISavable
|
||||
{
|
||||
/// <summary> The full file name of a given object. </summary>
|
||||
public string ToFilename(FilenameService fileNames);
|
||||
|
||||
/// <summary> Write the objects data to the given stream writer. </summary>
|
||||
public void Save(StreamWriter writer);
|
||||
|
||||
/// <summary> An arbitrary message printed to Debug before saving. </summary>
|
||||
public string LogName(string fileName)
|
||||
=> fileName;
|
||||
|
||||
public string TypeName
|
||||
=> GetType().Name;
|
||||
}
|
||||
|
||||
public class SaveService
|
||||
{
|
||||
private readonly Logger _log;
|
||||
private readonly FrameworkManager _framework;
|
||||
|
||||
public readonly FilenameService FileNames;
|
||||
|
||||
public SaveService(Logger log, FrameworkManager framework, FilenameService fileNames)
|
||||
{
|
||||
_log = log;
|
||||
_framework = framework;
|
||||
FileNames = fileNames;
|
||||
}
|
||||
|
||||
/// <summary> Queue a save for the next framework tick. </summary>
|
||||
public void QueueSave(ISavable value)
|
||||
{
|
||||
var file = value.ToFilename(FileNames);
|
||||
_framework.RegisterOnTick(value.GetType().Name + file, () =>
|
||||
{
|
||||
ImmediateSave(value);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary> Immediately trigger a save. </summary>
|
||||
public void ImmediateSave(ISavable value)
|
||||
{
|
||||
var name = value.ToFilename(FileNames);
|
||||
try
|
||||
{
|
||||
if (name.Length == 0)
|
||||
{
|
||||
throw new Exception("Invalid object returned empty filename.");
|
||||
}
|
||||
|
||||
_log.Debug($"Saving {value.TypeName} {value.LogName(name)}...");
|
||||
var file = new FileInfo(name);
|
||||
file.Directory?.Create();
|
||||
using var s = file.Exists ? file.Open(FileMode.Truncate) : file.Open(FileMode.CreateNew);
|
||||
using var w = new StreamWriter(s, Encoding.UTF8);
|
||||
value.Save(w);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.Error($"Could not save {value.GetType().Name} {value.LogName(name)}:\n{ex}");
|
||||
}
|
||||
}
|
||||
|
||||
public void ImmediateDelete(ISavable value)
|
||||
{
|
||||
var name = value.ToFilename(FileNames);
|
||||
try
|
||||
{
|
||||
if (name.Length == 0)
|
||||
{
|
||||
throw new Exception("Invalid object returned empty filename.");
|
||||
}
|
||||
|
||||
if (!File.Exists(name))
|
||||
return;
|
||||
|
||||
_log.Information($"Deleting {value.GetType().Name} {value.LogName(name)}...");
|
||||
File.Delete(name);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.Error($"Could not delete {value.GetType().Name} {value.LogName(name)}:\n{ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
80
GlamourerOld/Services/ServiceManager.cs
Normal file
80
GlamourerOld/Services/ServiceManager.cs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
using Dalamud.Plugin;
|
||||
using Glamourer.Api;
|
||||
using Glamourer.Designs;
|
||||
using Glamourer.Gui;
|
||||
using Glamourer.Interop;
|
||||
using Glamourer.State;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Log;
|
||||
|
||||
namespace Glamourer.Services;
|
||||
|
||||
public static class ServiceManager
|
||||
{
|
||||
public static ServiceProvider CreateProvider(DalamudPluginInterface pi, Logger log)
|
||||
{
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton(log)
|
||||
.AddDalamud(pi)
|
||||
.AddMeta()
|
||||
.AddConfig()
|
||||
.AddPenumbra()
|
||||
.AddInterop()
|
||||
.AddGameData()
|
||||
.AddDesigns()
|
||||
.AddInterface()
|
||||
.AddApi();
|
||||
|
||||
return services.BuildServiceProvider(new ServiceProviderOptions { ValidateOnBuild = true });
|
||||
}
|
||||
|
||||
private static IServiceCollection AddDalamud(this IServiceCollection services, DalamudPluginInterface pi)
|
||||
{
|
||||
new DalamudServices(pi).AddServices(services);
|
||||
return services;
|
||||
}
|
||||
|
||||
private static IServiceCollection AddMeta(this IServiceCollection services)
|
||||
=> services.AddSingleton<FilenameService>()
|
||||
.AddSingleton<SaveService>()
|
||||
.AddSingleton<FrameworkManager>()
|
||||
.AddSingleton<ChatService>();
|
||||
|
||||
private static IServiceCollection AddConfig(this IServiceCollection services)
|
||||
=> services.AddSingleton<Configuration>()
|
||||
.AddSingleton<BackupService>();
|
||||
|
||||
private static IServiceCollection AddPenumbra(this IServiceCollection services)
|
||||
=> services.AddSingleton<PenumbraAttach>();
|
||||
|
||||
private static IServiceCollection AddGameData(this IServiceCollection services)
|
||||
=> services.AddSingleton<IdentifierService>()
|
||||
.AddSingleton<ActorService>()
|
||||
.AddSingleton<ItemService>()
|
||||
.AddSingleton<ItemManager>()
|
||||
.AddSingleton<CustomizationService>();
|
||||
|
||||
private static IServiceCollection AddInterop(this IServiceCollection services)
|
||||
=> services.AddSingleton<ChangeCustomizeService>()
|
||||
.AddSingleton<JobService>()
|
||||
.AddSingleton<UpdateSlotService>()
|
||||
.AddSingleton<VisorService>()
|
||||
.AddSingleton<WeaponService>()
|
||||
.AddSingleton<ObjectManager>();
|
||||
|
||||
private static IServiceCollection AddDesigns(this IServiceCollection services)
|
||||
=> services.AddSingleton<DesignManager>()
|
||||
.AddSingleton<DesignFileSystem>()
|
||||
.AddSingleton<ActiveDesign.Manager>()
|
||||
.AddSingleton<FixedDesignManager>()
|
||||
.AddSingleton<RedrawManager>();
|
||||
|
||||
private static IServiceCollection AddInterface(this IServiceCollection services)
|
||||
=> services.AddSingleton<Interface>()
|
||||
.AddSingleton<GlamourerWindowSystem>();
|
||||
|
||||
private static IServiceCollection AddApi(this IServiceCollection services)
|
||||
=> services.AddSingleton<CommandService>()
|
||||
.AddSingleton<Glamourer.GlamourerIpc>();
|
||||
}
|
||||
105
GlamourerOld/Services/ServiceWrapper.cs
Normal file
105
GlamourerOld/Services/ServiceWrapper.cs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
using Dalamud.Data;
|
||||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.Gui;
|
||||
using Dalamud.Plugin;
|
||||
using Penumbra.GameData.Actors;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Dalamud.Game;
|
||||
using Glamourer.Api;
|
||||
using Glamourer.Customization;
|
||||
using Penumbra.GameData.Data;
|
||||
using Penumbra.GameData;
|
||||
|
||||
namespace Glamourer.Services;
|
||||
|
||||
public abstract class AsyncServiceWrapper<T>
|
||||
{
|
||||
public string Name { get; }
|
||||
public T? Service { get; private set; }
|
||||
|
||||
public T AwaitedService
|
||||
{
|
||||
get
|
||||
{
|
||||
_task?.Wait();
|
||||
return Service!;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Valid
|
||||
=> Service != null && !_isDisposed;
|
||||
|
||||
public event Action? FinishedCreation;
|
||||
private Task? _task;
|
||||
|
||||
private bool _isDisposed;
|
||||
|
||||
protected AsyncServiceWrapper(string name, Func<T> factory)
|
||||
{
|
||||
Name = name;
|
||||
_task = Task.Run(() =>
|
||||
{
|
||||
var service = factory();
|
||||
if (_isDisposed)
|
||||
{
|
||||
if (service is IDisposable d)
|
||||
d.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
Service = service;
|
||||
Glamourer.Log.Verbose($"[{Name}] Created.");
|
||||
_task = null;
|
||||
}
|
||||
});
|
||||
_task.ContinueWith((t, x) =>
|
||||
{
|
||||
if (!_isDisposed)
|
||||
FinishedCreation?.Invoke();
|
||||
}, null);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_isDisposed)
|
||||
return;
|
||||
|
||||
_isDisposed = true;
|
||||
_task = null;
|
||||
if (Service is IDisposable d)
|
||||
d.Dispose();
|
||||
Glamourer.Log.Verbose($"[{Name}] Disposed.");
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class IdentifierService : AsyncServiceWrapper<IObjectIdentifier>
|
||||
{
|
||||
public IdentifierService(DalamudPluginInterface pi, DataManager data)
|
||||
: base(nameof(IdentifierService), () => Penumbra.GameData.GameData.GetIdentifier(pi, data))
|
||||
{ }
|
||||
}
|
||||
|
||||
public sealed class ItemService : AsyncServiceWrapper<ItemData>
|
||||
{
|
||||
public ItemService(DalamudPluginInterface pi, DataManager gameData)
|
||||
: base(nameof(ItemService), () => new ItemData(pi, gameData, gameData.Language))
|
||||
{ }
|
||||
}
|
||||
|
||||
public sealed class ActorService : AsyncServiceWrapper<ActorManager>
|
||||
{
|
||||
public ActorService(DalamudPluginInterface pi, ObjectTable objects, ClientState clientState, Framework framework, DataManager gameData,
|
||||
GameGui gui, PenumbraAttach penumbra)
|
||||
: base(nameof(ActorService),
|
||||
() => new ActorManager(pi, objects, clientState, framework, gameData, gui, idx => (short)penumbra.CutsceneParent(idx)))
|
||||
{ }
|
||||
}
|
||||
|
||||
public sealed class CustomizationService : AsyncServiceWrapper<ICustomizationManager>
|
||||
{
|
||||
public CustomizationService(DalamudPluginInterface pi, DataManager gameData)
|
||||
: base(nameof(CustomizationService), () => CustomizationManager.Create(pi, gameData))
|
||||
{ }
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue