using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Plugin; using System; using System.Collections.Generic; using System.Linq; using Glamourer.Automation; using Glamourer.Designs; using Glamourer.Events; using Glamourer.Interop; using Glamourer.Services; using Glamourer.State; using Penumbra.Api.Helpers; using Penumbra.GameData.Actors; using Penumbra.String; namespace Glamourer.Api; public partial class GlamourerIpc : IDisposable { public const int CurrentApiVersionMajor = 0; public const int CurrentApiVersionMinor = 4; private readonly StateManager _stateManager; private readonly ObjectManager _objects; private readonly ActorService _actors; private readonly DesignConverter _designConverter; private readonly AutoDesignApplier _autoDesignApplier; public GlamourerIpc(DalamudPluginInterface pi, StateManager stateManager, ObjectManager objects, ActorService actors, DesignConverter designConverter, StateChanged stateChangedEvent, GPoseService gPose, AutoDesignApplier autoDesignApplier) { _stateManager = stateManager; _objects = objects; _actors = actors; _designConverter = designConverter; _autoDesignApplier = autoDesignApplier; _gPose = gPose; _stateChangedEvent = stateChangedEvent; _apiVersionProvider = new FuncProvider(pi, LabelApiVersion, ApiVersion); _apiVersionsProvider = new FuncProvider<(int Major, int Minor)>(pi, LabelApiVersions, ApiVersions); _getAllCustomizationProvider = new FuncProvider(pi, LabelGetAllCustomization, GetAllCustomization); _getAllCustomizationFromCharacterProvider = new FuncProvider(pi, LabelGetAllCustomizationFromCharacter, GetAllCustomizationFromCharacter); _applyAllProvider = new ActionProvider(pi, LabelApplyAll, ApplyAll); _applyAllToCharacterProvider = new ActionProvider(pi, LabelApplyAllToCharacter, ApplyAllToCharacter); _applyOnlyEquipmentProvider = new ActionProvider(pi, LabelApplyOnlyEquipment, ApplyOnlyEquipment); _applyOnlyEquipmentToCharacterProvider = new ActionProvider(pi, LabelApplyOnlyEquipmentToCharacter, ApplyOnlyEquipmentToCharacter); _applyOnlyCustomizationProvider = new ActionProvider(pi, LabelApplyOnlyCustomization, ApplyOnlyCustomization); _applyOnlyCustomizationToCharacterProvider = new ActionProvider(pi, LabelApplyOnlyCustomizationToCharacter, ApplyOnlyCustomizationToCharacter); _applyAllProviderLock = new ActionProvider(pi, LabelApplyAllLock, ApplyAllLock); _applyAllToCharacterProviderLock = new ActionProvider(pi, LabelApplyAllToCharacterLock, ApplyAllToCharacterLock); _applyOnlyEquipmentProviderLock = new ActionProvider(pi, LabelApplyOnlyEquipmentLock, ApplyOnlyEquipmentLock); _applyOnlyEquipmentToCharacterProviderLock = new ActionProvider(pi, LabelApplyOnlyEquipmentToCharacterLock, ApplyOnlyEquipmentToCharacterLock); _applyOnlyCustomizationProviderLock = new ActionProvider(pi, LabelApplyOnlyCustomizationLock, ApplyOnlyCustomizationLock); _applyOnlyCustomizationToCharacterProviderLock = new ActionProvider(pi, LabelApplyOnlyCustomizationToCharacterLock, ApplyOnlyCustomizationToCharacterLock); _revertProvider = new ActionProvider(pi, LabelRevert, Revert); _revertCharacterProvider = new ActionProvider(pi, LabelRevertCharacter, RevertCharacter); _revertProviderLock = new ActionProvider(pi, LabelRevertLock, RevertLock); _revertCharacterProviderLock = new ActionProvider(pi, LabelRevertCharacterLock, RevertCharacterLock); _unlockNameProvider = new FuncProvider(pi, LabelUnlockName, Unlock); _unlockProvider = new FuncProvider(pi, LabelUnlock, Unlock); _revertToAutomationProvider = new FuncProvider(pi, LabelRevertToAutomation, RevertToAutomation); _revertToAutomationCharacterProvider = new FuncProvider(pi, LabelRevertToAutomationCharacter, RevertToAutomation); _stateChangedProvider = new EventProvider>(pi, LabelStateChanged); _gPoseChangedProvider = new EventProvider(pi, LabelGPoseChanged); _stateChangedEvent.Subscribe(OnStateChanged, StateChanged.Priority.GlamourerIpc); _gPose.Subscribe(OnGPoseChanged, GPoseService.Priority.GlamourerIpc); } public void Dispose() { _apiVersionProvider.Dispose(); _apiVersionsProvider.Dispose(); _getAllCustomizationProvider.Dispose(); _getAllCustomizationFromCharacterProvider.Dispose(); _applyAllProvider.Dispose(); _applyAllToCharacterProvider.Dispose(); _applyOnlyEquipmentProvider.Dispose(); _applyOnlyEquipmentToCharacterProvider.Dispose(); _applyOnlyCustomizationProvider.Dispose(); _applyOnlyCustomizationToCharacterProvider.Dispose(); _applyAllProviderLock.Dispose(); _applyAllToCharacterProviderLock.Dispose(); _applyOnlyEquipmentProviderLock.Dispose(); _applyOnlyEquipmentToCharacterProviderLock.Dispose(); _applyOnlyCustomizationProviderLock.Dispose(); _applyOnlyCustomizationToCharacterProviderLock.Dispose(); _revertProvider.Dispose(); _revertCharacterProvider.Dispose(); _revertProviderLock.Dispose(); _revertCharacterProviderLock.Dispose(); _unlockNameProvider.Dispose(); _unlockProvider.Dispose(); _revertToAutomationProvider.Dispose(); _revertToAutomationCharacterProvider.Dispose(); _stateChangedEvent.Unsubscribe(OnStateChanged); _stateChangedProvider.Dispose(); _gPose.Unsubscribe(OnGPoseChanged); _gPoseChangedProvider.Dispose(); } private IEnumerable FindActors(string actorName) { if (actorName.Length == 0 || !ByteString.FromString(actorName, out var byteString)) return Array.Empty(); _objects.Update(); return _objects.Where(i => i.Key is { IsValid: true, Type: IdentifierType.Player } && i.Key.PlayerName == byteString) .Select(i => i.Key); } private IEnumerable FindActorsRevert(string actorName) { if (actorName.Length == 0 || !ByteString.FromString(actorName, out var byteString)) yield break; _objects.Update(); foreach (var id in _objects.Where(i => i.Key is { IsValid: true, Type: IdentifierType.Player } && i.Key.PlayerName == byteString) .Select(i => i.Key)) yield return id; foreach (var id in _stateManager.Keys.Where(s => s.Type is IdentifierType.Player && s.PlayerName == byteString)) yield return id; } private IEnumerable FindActors(Character? character) { var id = _actors.AwaitedService.FromObject(character, true, true, false); if (!id.IsValid) yield break; yield return id; } }