189 lines
5.9 KiB
C#
189 lines
5.9 KiB
C#
using System;
|
|
using Dalamud.Game.ClientState.Conditions;
|
|
using Dalamud.Plugin;
|
|
using Dalamud.Plugin.Ipc;
|
|
using Dalamud.Plugin.Ipc.Exceptions;
|
|
using Dalamud.Plugin.Services;
|
|
using Microsoft.Extensions.Logging;
|
|
using Questionable.Controller;
|
|
|
|
namespace Questionable.External;
|
|
|
|
internal sealed class TextAdvanceIpc : IDisposable
|
|
{
|
|
public sealed class ExternalTerritoryConfig
|
|
{
|
|
public bool? EnableQuestAccept;
|
|
|
|
public bool? EnableQuestComplete;
|
|
|
|
public bool? EnableRewardPick;
|
|
|
|
public bool? EnableRequestHandin;
|
|
|
|
public bool? EnableCutsceneEsc;
|
|
|
|
public bool? EnableCutsceneSkipConfirm;
|
|
|
|
public bool? EnableTalkSkip;
|
|
|
|
public bool? EnableRequestFill;
|
|
|
|
public bool? EnableAutoInteract;
|
|
}
|
|
|
|
private bool _isExternalControlActivated;
|
|
|
|
private long _ipcRetryAfter;
|
|
|
|
private bool _lastCinemaModeState;
|
|
|
|
private bool _lastInCutsceneState;
|
|
|
|
private bool _lastSuppressRequestState;
|
|
|
|
private readonly QuestController _questController;
|
|
|
|
private readonly FateController _fateController;
|
|
|
|
private readonly SeasonalDutyController _seasonalDutyController;
|
|
|
|
private readonly AttunementController _attunementController;
|
|
|
|
private readonly CustomDeliveryController _customDeliveryController;
|
|
|
|
private readonly Configuration _configuration;
|
|
|
|
private readonly ICondition _condition;
|
|
|
|
private readonly IFramework _framework;
|
|
|
|
private readonly ICallGateSubscriber<bool> _isInExternalControl;
|
|
|
|
private readonly ICallGateSubscriber<string, ExternalTerritoryConfig, bool> _enableExternalControl;
|
|
|
|
private readonly ICallGateSubscriber<string, bool> _disableExternalControl;
|
|
|
|
private readonly string _pluginName;
|
|
|
|
private readonly ILogger<TextAdvanceIpc> _logger;
|
|
|
|
public TextAdvanceIpc(IDalamudPluginInterface pluginInterface, IFramework framework, QuestController questController, FateController fateController, SeasonalDutyController seasonalDutyController, AttunementController attunementController, CustomDeliveryController customDeliveryController, Configuration configuration, ICondition condition, ILogger<TextAdvanceIpc> logger)
|
|
{
|
|
_framework = framework;
|
|
_questController = questController;
|
|
_fateController = fateController;
|
|
_seasonalDutyController = seasonalDutyController;
|
|
_attunementController = attunementController;
|
|
_customDeliveryController = customDeliveryController;
|
|
_configuration = configuration;
|
|
_condition = condition;
|
|
_logger = logger;
|
|
_isInExternalControl = pluginInterface.GetIpcSubscriber<bool>("TextAdvance.IsInExternalControl");
|
|
_enableExternalControl = pluginInterface.GetIpcSubscriber<string, ExternalTerritoryConfig, bool>("TextAdvance.EnableExternalControl");
|
|
_disableExternalControl = pluginInterface.GetIpcSubscriber<string, bool>("TextAdvance.DisableExternalControl");
|
|
_pluginName = pluginInterface.InternalName;
|
|
_framework.Update += OnUpdate;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_framework.Update -= OnUpdate;
|
|
if (_isExternalControlActivated)
|
|
{
|
|
try
|
|
{
|
|
_disableExternalControl.InvokeFunc(_pluginName);
|
|
}
|
|
catch (IpcError exception)
|
|
{
|
|
_logger.LogDebug(exception, "Failed to disable TextAdvance external control during dispose");
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnUpdate(IFramework framework)
|
|
{
|
|
if (Environment.TickCount64 < _ipcRetryAfter)
|
|
{
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
OnUpdateInner();
|
|
}
|
|
catch (IpcError exception)
|
|
{
|
|
_logger.LogDebug(exception, "TextAdvance IPC call failed");
|
|
_ipcRetryAfter = Environment.TickCount64 + 30000;
|
|
}
|
|
}
|
|
|
|
private void OnUpdateInner()
|
|
{
|
|
bool flag = _questController.IsRunning || _questController.AutomationType != QuestController.EAutomationType.Manual || _fateController.IsRunning || _seasonalDutyController.IsRunning || _attunementController.IsRunning || _customDeliveryController.IsRunning;
|
|
if (!_configuration.General.ConfigureTextAdvance || !flag)
|
|
{
|
|
if (!_isExternalControlActivated)
|
|
{
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
if (_disableExternalControl.InvokeFunc(_pluginName) || !_isInExternalControl.InvokeFunc())
|
|
{
|
|
_isExternalControlActivated = false;
|
|
}
|
|
return;
|
|
}
|
|
catch (IpcError)
|
|
{
|
|
_isExternalControlActivated = false;
|
|
return;
|
|
}
|
|
}
|
|
bool cinemaMode = _configuration.General.CinemaMode;
|
|
bool flag2 = _condition[ConditionFlag.OccupiedInCutSceneEvent] || _condition[ConditionFlag.WatchingCutscene] || _condition[ConditionFlag.WatchingCutscene78];
|
|
bool flag3 = _customDeliveryController.IsRunning && !_questController.IsRunning && _questController.AutomationType == QuestController.EAutomationType.Manual && !_fateController.IsRunning && !_seasonalDutyController.IsRunning && !_attunementController.IsRunning;
|
|
bool flag4 = cinemaMode != _lastCinemaModeState || (cinemaMode && flag2 != _lastInCutsceneState) || flag3 != _lastSuppressRequestState;
|
|
if (!_isExternalControlActivated)
|
|
{
|
|
if (!_isInExternalControl.InvokeFunc())
|
|
{
|
|
ExternalTerritoryConfig arg = CreateExternalTerritoryConfig(cinemaMode, flag2, flag3);
|
|
if (_enableExternalControl.InvokeFunc(_pluginName, arg))
|
|
{
|
|
_isExternalControlActivated = true;
|
|
_lastCinemaModeState = cinemaMode;
|
|
_lastInCutsceneState = flag2;
|
|
_lastSuppressRequestState = flag3;
|
|
}
|
|
}
|
|
}
|
|
else if (flag4)
|
|
{
|
|
ExternalTerritoryConfig arg2 = CreateExternalTerritoryConfig(cinemaMode, flag2, flag3);
|
|
_enableExternalControl.InvokeFunc(_pluginName, arg2);
|
|
_lastCinemaModeState = cinemaMode;
|
|
_lastInCutsceneState = flag2;
|
|
_lastSuppressRequestState = flag3;
|
|
}
|
|
}
|
|
|
|
private static ExternalTerritoryConfig CreateExternalTerritoryConfig(bool cinemaMode, bool inCutscene, bool suppressRequestHandling)
|
|
{
|
|
bool flag = cinemaMode && inCutscene;
|
|
return new ExternalTerritoryConfig
|
|
{
|
|
EnableQuestAccept = true,
|
|
EnableQuestComplete = true,
|
|
EnableRewardPick = true,
|
|
EnableRequestHandin = !suppressRequestHandling,
|
|
EnableCutsceneEsc = !cinemaMode,
|
|
EnableCutsceneSkipConfirm = !cinemaMode,
|
|
EnableTalkSkip = !flag,
|
|
EnableRequestFill = !suppressRequestHandling,
|
|
EnableAutoInteract = false
|
|
};
|
|
}
|
|
}
|