using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Threading.Tasks; using Dalamud.Plugin; using Dalamud.Plugin.Ipc; using Dalamud.Plugin.Ipc.Exceptions; using Dalamud.Plugin.Services; using Microsoft.Extensions.Logging; using Questionable.Controller; using Questionable.Data; namespace Questionable.External; internal sealed class PandorasBoxIpc : IDisposable { private static readonly ImmutableHashSet ConflictingFeatures = new HashSet { "Auto-Collect", "Auto-Cordial", "Auto-Meditation", "Auto-Motif (Out of Combat)", "Auto-Mount After Combat", "Auto-Mount after Gathering", "Auto-Mount on Zone Change", "Auto-Peleton", "Auto-Prospect/Triangulate", "Auto-Sprint in Sanctuaries", "Auto-Summon Chocobo", "Auto-Summon Fairy/Carbuncle", "Auto-Tank Stance", "Action Combat Targeting", "Auto-interact with Gathering Nodes", "FATE Targeting Mode", "Auto-Teleport to Map Coords", "Auto-select Turn-ins", "Auto-Equip Recommended Gear", "Auto-Sync FATEs", "Pandora Quick Gather", "Switch Gatherers Automatically" }.ToImmutableHashSet(); private const string AutoActiveTimeManeuverFeature = "Auto Active Time Maneuver"; private readonly Configuration _configuration; private readonly QuestController _questController; private readonly FateController _fateController; private readonly TerritoryData _territoryData; private readonly IClientState _clientState; private readonly IFramework _framework; private readonly ILogger _logger; private readonly ICallGateSubscriber _getFeatureEnabled; private readonly ICallGateSubscriber _setFeatureEnabled; private HashSet? _pausedFeatures; private bool _wasFateRunning; public PandorasBoxIpc(Configuration configuration, IDalamudPluginInterface pluginInterface, QuestController questController, FateController fateController, TerritoryData territoryData, IClientState clientState, IFramework framework, ILogger logger) { _configuration = configuration; _questController = questController; _fateController = fateController; _territoryData = territoryData; _clientState = clientState; _framework = framework; _logger = logger; _getFeatureEnabled = pluginInterface.GetIpcSubscriber("PandorasBox.GetFeatureEnabled"); _setFeatureEnabled = pluginInterface.GetIpcSubscriber("PandorasBox.SetFeatureEnabled"); _questController.AutomationTypeChanged += OnAutomationTypeChanged; _framework.Update += OnFrameworkUpdate; } private void OnAutomationTypeChanged(object sender, QuestController.EAutomationType automationType) { if (automationType != QuestController.EAutomationType.Manual && !_territoryData.IsDutyInstance(_clientState.TerritoryType)) { Task.Run((Action)DisableConflictingFeatures); } else if (!_fateController.IsRunning) { Task.Run((Action)RestoreConflictingFeatures); } } private void OnFrameworkUpdate(IFramework framework) { bool isRunning = _fateController.IsRunning; if (isRunning != _wasFateRunning) { _wasFateRunning = isRunning; if (isRunning && !_territoryData.IsDutyInstance(_clientState.TerritoryType)) { Task.Run((Action)DisableConflictingFeatures); } else if (_questController.AutomationType == QuestController.EAutomationType.Manual) { Task.Run((Action)RestoreConflictingFeatures); } } } public void Dispose() { _framework.Update -= OnFrameworkUpdate; _questController.AutomationTypeChanged -= OnAutomationTypeChanged; RestoreConflictingFeatures(); } private void DisableConflictingFeatures() { if (_pausedFeatures != null) { return; } _pausedFeatures = new HashSet(); foreach (string conflictingFeature in ConflictingFeatures) { TryDisableFeature(conflictingFeature); } if (_configuration.General.AutoSolveQte) { TryDisableFeature("Auto Active Time Maneuver"); } } private void TryDisableFeature(string feature) { try { if (_getFeatureEnabled.InvokeFunc(feature) == true) { _setFeatureEnabled.InvokeAction(feature, arg2: false); _pausedFeatures.Add(feature); _logger.LogInformation("Paused Pandora's Box feature: {Feature}", feature); } } catch (IpcError) { } } private void RestoreConflictingFeatures() { if (_pausedFeatures == null) { return; } foreach (string pausedFeature in _pausedFeatures) { try { _setFeatureEnabled.InvokeAction(pausedFeature, arg2: true); _logger.LogInformation("Restored Pandora's Box feature: {Feature}", pausedFeature); } catch (IpcError) { } } _pausedFeatures = null; } }