using System; using Dalamud.Plugin; using Dalamud.Plugin.Ipc; using Dalamud.Plugin.Ipc.Exceptions; using Microsoft.Extensions.Logging; using Questionable.Controller.Steps; using Questionable.Data; using Questionable.Model.Questing; namespace Questionable.External; internal sealed class AutoDutyIpc { public enum DutyMode { Support = 1, UnsyncRegular } private readonly Configuration _configuration; private readonly TerritoryData _territoryData; private readonly ILogger _logger; private readonly ICallGateSubscriber _contentHasPath; private readonly ICallGateSubscriber _setConfig; private readonly ICallGateSubscriber _run; private readonly ICallGateSubscriber _isStopped; private readonly ICallGateSubscriber _stop; private bool _loggedContentHasPathQueryWarning; private bool _loggedLevelingModeWarning; public const int MinimumLevelForLevelingMode = 15; public AutoDutyIpc(IDalamudPluginInterface pluginInterface, Configuration configuration, TerritoryData territoryData, ILogger logger) { _configuration = configuration; _territoryData = territoryData; _logger = logger; _contentHasPath = pluginInterface.GetIpcSubscriber("AutoDuty.ContentHasPath"); _setConfig = pluginInterface.GetIpcSubscriber("AutoDuty.SetConfig"); _run = pluginInterface.GetIpcSubscriber("AutoDuty.Run"); _isStopped = pluginInterface.GetIpcSubscriber("AutoDuty.IsStopped"); _stop = pluginInterface.GetIpcSubscriber("AutoDuty.Stop"); _loggedContentHasPathQueryWarning = false; _loggedLevelingModeWarning = false; } public bool IsConfiguredToRunContent(DutyOptions? dutyOptions) { if (dutyOptions == null || dutyOptions.ContentFinderConditionId == 0) { return false; } if (!_configuration.Duties.RunInstancedContentWithAutoDuty) { return false; } if (_configuration.Duties.BlacklistedDutyCfcIds.Contains(dutyOptions.ContentFinderConditionId)) { return false; } if (_configuration.Duties.WhitelistedDutyCfcIds.Contains(dutyOptions.ContentFinderConditionId) && _territoryData.TryGetContentFinderCondition(dutyOptions.ContentFinderConditionId, out TerritoryData.ContentFinderConditionData _)) { return true; } if (dutyOptions.Enabled) { return HasPath(dutyOptions.ContentFinderConditionId); } return false; } public bool IsConfiguredToRunLevelingMode() { return _configuration.Duties.RunLevelingModeWhenUnderleveled; } public bool IsConfiguredToRunLevelingMode(int currentPlayerLevel) { if (!_configuration.Duties.RunLevelingModeWhenUnderleveled) { return false; } if (currentPlayerLevel < 15) { return false; } return true; } public bool HasPath(uint cfcId) { if (!_territoryData.TryGetContentFinderCondition(cfcId, out TerritoryData.ContentFinderConditionData contentFinderConditionData)) { return false; } try { return _contentHasPath.InvokeFunc(contentFinderConditionData.TerritoryId); } catch (IpcError ipcError) { if (!_loggedContentHasPathQueryWarning) { _logger.LogWarning("Unable to query AutoDuty for path in territory {TerritoryType}: {Message}", contentFinderConditionData.TerritoryId, ipcError.Message); _loggedContentHasPathQueryWarning = true; } return false; } } public void StartInstance(uint cfcId, DutyMode dutyMode) { if (!_territoryData.TryGetContentFinderCondition(cfcId, out TerritoryData.ContentFinderConditionData contentFinderConditionData)) { throw new TaskException($"Unknown ContentFinderConditionId {cfcId}"); } try { _setConfig.InvokeAction("leveling", "None"); _setConfig.InvokeAction("Unsynced", $"{dutyMode == DutyMode.UnsyncRegular}"); ICallGateSubscriber setConfig = _setConfig; setConfig.InvokeAction("dutyModeEnum", dutyMode switch { DutyMode.Support => "Support", DutyMode.UnsyncRegular => "Regular", _ => throw new ArgumentOutOfRangeException("dutyMode", dutyMode, null), }); _run.InvokeAction(contentFinderConditionData.TerritoryId, 1, !_configuration.Advanced.DisableAutoDutyBareMode); } catch (IpcError ipcError) { throw new TaskException("Unable to run content with AutoDuty: " + ipcError.Message, ipcError); } } public bool StartLevelingMode() { try { if (!IsStopped()) { _logger.LogDebug("AutoDuty is already running, not starting leveling mode again"); return true; } _logger.LogInformation("Starting AutoDuty Leveling mode (Support) - AutoDuty will select the best dungeon"); _setConfig.InvokeAction("leveling", "Support"); _run.InvokeAction(0u, 1, !_configuration.Advanced.DisableAutoDutyBareMode); return true; } catch (IpcError ipcError) { if (!_loggedLevelingModeWarning) { _logger.LogWarning("Unable to start AutoDuty Leveling mode: {Message}", ipcError.Message); _loggedLevelingModeWarning = true; } return false; } catch (Exception exception) { if (!_loggedLevelingModeWarning) { _logger.LogWarning(exception, "Unable to start AutoDuty Leveling mode"); _loggedLevelingModeWarning = true; } return false; } } public bool IsStopped() { try { return _isStopped.InvokeFunc(); } catch (IpcError) { return true; } } public void DisableLevelingMode() { try { _logger.LogInformation("Disabling AutoDuty leveling mode"); _setConfig.InvokeAction("leveling", "None"); } catch (IpcError ipcError) { _logger.LogWarning("Unable to disable AutoDuty leveling mode: {Message}", ipcError.Message); } } public void Stop() { try { _logger.LogInformation("Calling AutoDuty.Stop"); try { _setConfig.InvokeAction("leveling", "None"); } catch (IpcError) { } _stop.InvokeAction(); } catch (IpcError ipcError2) { throw new TaskException("Unable to stop AutoDuty: " + ipcError2.Message, ipcError2); } } }