using System; using System.Collections.Generic; using Dalamud.Plugin; using Dalamud.Plugin.Ipc; using Dalamud.Plugin.Ipc.Exceptions; using Microsoft.Extensions.Logging; namespace LLib.External; public sealed class PluginFeaturePauser : IDisposable { private readonly ICallGateSubscriber _getEnabled; private readonly ICallGateSubscriber _setEnabled; private readonly ILogger _logger; private HashSet? _pausedFeatures; public bool IsPaused => _pausedFeatures != null; public PluginFeaturePauser(IDalamudPluginInterface pluginInterface, string getEnabledEndpoint, string setEnabledEndpoint, ILogger logger) { ArgumentNullException.ThrowIfNull(pluginInterface, "pluginInterface"); ArgumentException.ThrowIfNullOrEmpty(getEnabledEndpoint, "getEnabledEndpoint"); ArgumentException.ThrowIfNullOrEmpty(setEnabledEndpoint, "setEnabledEndpoint"); ArgumentNullException.ThrowIfNull(logger, "logger"); _getEnabled = pluginInterface.GetIpcSubscriber(getEnabledEndpoint); _setEnabled = pluginInterface.GetIpcSubscriber(setEnabledEndpoint); _logger = logger; } public void Disable(IEnumerable features) { if (_pausedFeatures == null) { _pausedFeatures = new HashSet(); } foreach (string feature in features) { if (_pausedFeatures.Contains(feature)) { continue; } try { if (_getEnabled.InvokeFunc(feature) == true) { _setEnabled.InvokeAction(feature, arg2: false); _pausedFeatures.Add(feature); _logger.LogInformation("Paused external feature: {Feature}", feature); } } catch (Exception ex) { if (!(ex is IpcError)) { _logger.LogWarning(ex, "Failed to pause external feature {Feature}", feature); } } } } public void Restore() { if (_pausedFeatures == null) { return; } HashSet hashSet = new HashSet(); foreach (string pausedFeature in _pausedFeatures) { try { _setEnabled.InvokeAction(pausedFeature, arg2: true); _logger.LogInformation("Restored external feature: {Feature}", pausedFeature); } catch (Exception exception) { hashSet.Add(pausedFeature); _logger.LogWarning(exception, "Failed to restore external feature {Feature}, keeping it for retry", pausedFeature); } } _pausedFeatures = ((hashSet.Count == 0) ? null : hashSet); } public void Dispose() { Restore(); } }