using System; using System.Collections.Generic; using System.Collections.Immutable; 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-Meditation", "Auto-Motif (Out of Combat)", "Auto-Mount after Combat", "Auto-Mount after Gathering", "Auto-Peleton", "Auto-Sprint in Sanctuaries", "Auto-interact with Gathering Nodes", "Auto-select Turn-ins", "Auto-Sync FATEs", "Pandora Quick Gather" }.ToImmutableHashSet(); private readonly IFramework _framework; private readonly QuestController _questController; private readonly TerritoryData _territoryData; private readonly IClientState _clientState; private readonly ILogger _logger; private readonly ICallGateSubscriber _getFeatureEnabled; private readonly ICallGateSubscriber _setFeatureEnabled; private bool _loggedIpcError; private HashSet? _pausedFeatures; public bool IsAutoActiveTimeManeuverEnabled { get { try { return _getFeatureEnabled.InvokeFunc("Auto Active Time Maneuver") == true; } catch (IpcError exception) { if (!_loggedIpcError) { _loggedIpcError = true; _logger.LogWarning(exception, "Could not query pandora's box for feature status, probably not installed"); } return false; } } } public PandorasBoxIpc(IDalamudPluginInterface pluginInterface, IFramework framework, QuestController questController, TerritoryData territoryData, IClientState clientState, ILogger logger) { _framework = framework; _questController = questController; _territoryData = territoryData; _clientState = clientState; _logger = logger; _getFeatureEnabled = pluginInterface.GetIpcSubscriber("PandorasBox.GetFeatureEnabled"); _setFeatureEnabled = pluginInterface.GetIpcSubscriber("PandorasBox.SetFeatureEnabled"); logger.LogInformation("Pandora's Box auto active time maneuver enabled: {IsAtmEnabled}", IsAutoActiveTimeManeuverEnabled); _framework.Update += OnUpdate; } private void OnUpdate(IFramework framework) { if ((_questController.IsRunning || _questController.AutomationType != QuestController.EAutomationType.Manual) && !_territoryData.IsDutyInstance(_clientState.TerritoryType)) { DisableConflictingFeatures(); } else { RestoreConflictingFeatures(); } } public void Dispose() { _framework.Update -= OnUpdate; RestoreConflictingFeatures(); } private void DisableConflictingFeatures() { if (_pausedFeatures != null) { return; } _pausedFeatures = new HashSet(); foreach (string conflictingFeature in ConflictingFeatures) { try { if (_getFeatureEnabled.InvokeFunc(conflictingFeature) == true) { _setFeatureEnabled.InvokeAction(conflictingFeature, arg2: false); _pausedFeatures.Add(conflictingFeature); _logger.LogInformation("Paused Pandora's Box feature: {Feature}", conflictingFeature); } } catch (IpcError exception) { _logger.LogWarning(exception, "Failed to pause Pandora's Box feature: {Feature}", conflictingFeature); } } } 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 exception) { _logger.LogWarning(exception, "Failed to restore Pandora's Box feature: {Feature}", pausedFeature); } } _pausedFeatures = null; } }