qstbak/Questionable/Questionable.External/QuestionableIpc.cs
2025-11-19 12:01:37 +10:00

420 lines
15 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Dalamud.Plugin;
using Dalamud.Plugin.Ipc;
using Questionable.Controller;
using Questionable.Controller.Steps;
using Questionable.Functions;
using Questionable.Model;
using Questionable.Model.Questing;
using Questionable.Windows;
using Questionable.Windows.QuestComponents;
namespace Questionable.External;
internal sealed class QuestionableIpc : IDisposable
{
public sealed class StepData
{
public required string QuestId { get; init; }
public required byte Sequence { get; init; }
public required int Step { get; init; }
public required string InteractionType { get; init; }
public required Vector3? Position { get; init; }
public required ushort TerritoryId { get; init; }
}
public sealed class TaskData
{
public required string TaskName { get; init; }
public required int RemainingTaskCount { get; init; }
}
private const string IpcIsRunning = "Questionable.IsRunning";
private const string IpcGetCurrentQuestId = "Questionable.GetCurrentQuestId";
private const string IpcGetCurrentStepData = "Questionable.GetCurrentStepData";
private const string IpcGetCurrentTask = "Questionable.GetCurrentTask";
private const string IpcGetCurrentlyActiveEventQuests = "Questionable.GetCurrentlyActiveEventQuests";
private const string IpcStartQuest = "Questionable.StartQuest";
private const string IpcStartSingleQuest = "Questionable.StartSingleQuest";
private const string IpcIsQuestLocked = "Questionable.IsQuestLocked";
private const string IpcIsQuestComplete = "Questionable.IsQuestComplete";
private const string IpcIsReadyToAcceptQuest = "Questionable.IsReadyToAcceptQuest";
private const string IpcIsQuestAccepted = "Questionable.IsQuestAccepted";
private const string IpcIsQuestUnobtainable = "Questionable.IsQuestUnobtainable";
private const string IpcImportQuestPriority = "Questionable.ImportQuestPriority";
private const string IpcClearQuestPriority = "Questionable.ClearQuestPriority";
private const string IpcAddQuestPriority = "Questionable.AddQuestPriority";
private const string IpcInsertQuestPriority = "Questionable.InsertQuestPriority";
private const string IpcExportQuestPriority = "Questionable.ExportQuestPriority";
private const string IpcGetDefaultDutyMode = "Questionable.GetDefaultDutyMode";
private const string IpcSetDefaultDutyMode = "Questionable.SetDefaultDutyMode";
private const string IpcGetDutyModeOverride = "Questionable.GetDutyModeOverride";
private const string IpcSetDutyModeOverride = "Questionable.SetDutyModeOverride";
private const string IpcClearDutyModeOverride = "Questionable.ClearDutyModeOverride";
private const string IpcClearAllDutyModeOverrides = "Questionable.ClearAllDutyModeOverrides";
private readonly QuestController _questController;
private readonly QuestRegistry _questRegistry;
private readonly QuestFunctions _questFunctions;
private readonly ManualPriorityComponent _manualPriorityComponent;
private readonly Configuration _configuration;
private readonly IDalamudPluginInterface _pluginInterface;
private readonly ICallGateProvider<bool> _isRunning;
private readonly ICallGateProvider<string?> _getCurrentQuestId;
private readonly ICallGateProvider<StepData?> _getCurrentStepData;
private readonly ICallGateProvider<TaskData?> _getCurrentTask;
private readonly ICallGateProvider<List<string>> _getCurrentlyActiveEventQuests;
private readonly ICallGateProvider<string, bool> _startQuest;
private readonly ICallGateProvider<string, bool> _startSingleQuest;
private readonly ICallGateProvider<string, bool> _isQuestLocked;
private readonly ICallGateProvider<string, bool> _IsQuestComplete;
private readonly ICallGateProvider<string, bool> _IsReadyToAcceptQuest;
private readonly ICallGateProvider<string, bool> _isQuestAccepted;
private readonly ICallGateProvider<string, bool> _isQuestUnobtainable;
private readonly ICallGateProvider<string, bool> _importQuestPriority;
private readonly ICallGateProvider<string, bool> _addQuestPriority;
private readonly ICallGateProvider<bool> _clearQuestPriority;
private readonly ICallGateProvider<int, string, bool> _insertQuestPriority;
private readonly ICallGateProvider<string> _exportQuestPriority;
private readonly ICallGateProvider<int> _getDefaultDutyMode;
private readonly ICallGateProvider<int, bool> _setDefaultDutyMode;
private readonly ICallGateProvider<uint, int> _getDutyModeOverride;
private readonly ICallGateProvider<uint, int, bool> _setDutyModeOverride;
private readonly ICallGateProvider<uint, bool> _clearDutyModeOverride;
private readonly ICallGateProvider<bool> _clearAllDutyModeOverrides;
public QuestionableIpc(QuestController questController, EventInfoComponent eventInfoComponent, QuestRegistry questRegistry, QuestFunctions questFunctions, ManualPriorityComponent manualPriorityComponent, Configuration configuration, IDalamudPluginInterface pluginInterface)
{
QuestionableIpc questionableIpc = this;
_questController = questController;
_questRegistry = questRegistry;
_questFunctions = questFunctions;
_manualPriorityComponent = manualPriorityComponent;
_configuration = configuration;
_pluginInterface = pluginInterface;
_isRunning = pluginInterface.GetIpcProvider<bool>("Questionable.IsRunning");
_isRunning.RegisterFunc(() => questController.AutomationType != QuestController.EAutomationType.Manual || questController.IsRunning);
_getCurrentQuestId = pluginInterface.GetIpcProvider<string>("Questionable.GetCurrentQuestId");
_getCurrentQuestId.RegisterFunc(() => questController.CurrentQuest?.Quest.Id.ToString());
_getCurrentStepData = pluginInterface.GetIpcProvider<StepData>("Questionable.GetCurrentStepData");
_getCurrentStepData.RegisterFunc(GetStepData);
_getCurrentTask = pluginInterface.GetIpcProvider<TaskData>("Questionable.GetCurrentTask");
_getCurrentTask.RegisterFunc(GetCurrentTask);
_getCurrentlyActiveEventQuests = pluginInterface.GetIpcProvider<List<string>>("Questionable.GetCurrentlyActiveEventQuests");
_getCurrentlyActiveEventQuests.RegisterFunc(() => (from q in eventInfoComponent.GetCurrentlyActiveEventQuests()
select q.ToString()).ToList());
_startQuest = pluginInterface.GetIpcProvider<string, bool>("Questionable.StartQuest");
_startQuest.RegisterFunc((string questId) => questionableIpc.StartQuest(questId, single: false));
_startSingleQuest = pluginInterface.GetIpcProvider<string, bool>("Questionable.StartSingleQuest");
_startSingleQuest.RegisterFunc((string questId) => questionableIpc.StartQuest(questId, single: true));
_isQuestLocked = pluginInterface.GetIpcProvider<string, bool>("Questionable.IsQuestLocked");
_isQuestLocked.RegisterFunc(IsQuestLocked);
_IsQuestComplete = pluginInterface.GetIpcProvider<string, bool>("Questionable.IsQuestComplete");
_IsQuestComplete.RegisterFunc(IsQuestComplete);
_IsReadyToAcceptQuest = pluginInterface.GetIpcProvider<string, bool>("Questionable.IsReadyToAcceptQuest");
_IsReadyToAcceptQuest.RegisterFunc(IsReadyToAcceptQuest);
_isQuestAccepted = pluginInterface.GetIpcProvider<string, bool>("Questionable.IsQuestAccepted");
_isQuestAccepted.RegisterFunc(IsQuestAccepted);
_isQuestUnobtainable = pluginInterface.GetIpcProvider<string, bool>("Questionable.IsQuestUnobtainable");
_isQuestUnobtainable.RegisterFunc(IsQuestUnobtainable);
_importQuestPriority = pluginInterface.GetIpcProvider<string, bool>("Questionable.ImportQuestPriority");
_importQuestPriority.RegisterFunc(ImportQuestPriority);
_addQuestPriority = pluginInterface.GetIpcProvider<string, bool>("Questionable.AddQuestPriority");
_addQuestPriority.RegisterFunc(AddQuestPriority);
_clearQuestPriority = pluginInterface.GetIpcProvider<bool>("Questionable.ClearQuestPriority");
_clearQuestPriority.RegisterFunc(ClearQuestPriority);
_insertQuestPriority = pluginInterface.GetIpcProvider<int, string, bool>("Questionable.InsertQuestPriority");
_insertQuestPriority.RegisterFunc(InsertQuestPriority);
_exportQuestPriority = pluginInterface.GetIpcProvider<string>("Questionable.ExportQuestPriority");
_exportQuestPriority.RegisterFunc(_manualPriorityComponent.EncodeQuestPriority);
_getDefaultDutyMode = pluginInterface.GetIpcProvider<int>("Questionable.GetDefaultDutyMode");
_getDefaultDutyMode.RegisterFunc(GetDefaultDutyMode);
_setDefaultDutyMode = pluginInterface.GetIpcProvider<int, bool>("Questionable.SetDefaultDutyMode");
_setDefaultDutyMode.RegisterFunc(SetDefaultDutyMode);
_getDutyModeOverride = pluginInterface.GetIpcProvider<uint, int>("Questionable.GetDutyModeOverride");
_getDutyModeOverride.RegisterFunc(GetDutyModeOverride);
_setDutyModeOverride = pluginInterface.GetIpcProvider<uint, int, bool>("Questionable.SetDutyModeOverride");
_setDutyModeOverride.RegisterFunc(SetDutyModeOverride);
_clearDutyModeOverride = pluginInterface.GetIpcProvider<uint, bool>("Questionable.ClearDutyModeOverride");
_clearDutyModeOverride.RegisterFunc(ClearDutyModeOverride);
_clearAllDutyModeOverrides = pluginInterface.GetIpcProvider<bool>("Questionable.ClearAllDutyModeOverrides");
_clearAllDutyModeOverrides.RegisterFunc(ClearAllDutyModeOverrides);
}
private bool StartQuest(string questId, bool single)
{
if (ElementId.TryFromString(questId, out ElementId elementId) && elementId != null && _questRegistry.TryGetQuest(elementId, out Quest quest))
{
_questController.SetNextQuest(quest);
if (single)
{
_questController.StartSingleQuest("IPCQuestSelection");
}
else
{
_questController.Start("IPCQuestSelection");
}
return true;
}
return false;
}
private StepData? GetStepData()
{
QuestController.QuestProgress currentQuest = _questController.CurrentQuest;
if (currentQuest == null)
{
return null;
}
string text = currentQuest.Quest.Id.ToString();
if (string.IsNullOrEmpty(text))
{
return null;
}
QuestStep questStep = currentQuest.Quest.FindSequence(currentQuest.Sequence)?.FindStep(currentQuest.Step);
if (questStep == null)
{
return null;
}
return new StepData
{
QuestId = text,
Sequence = currentQuest.Sequence,
Step = currentQuest.Step,
InteractionType = questStep.InteractionType.ToString(),
Position = questStep.Position,
TerritoryId = questStep.TerritoryId
};
}
private TaskData? GetCurrentTask()
{
ITask task = _questController.TaskQueue.CurrentTaskExecutor?.CurrentTask;
if (task == null)
{
return null;
}
int remainingTaskCount = _questController.TaskQueue.RemainingTasks.Count();
string taskName = task.ToString() ?? "Unknown";
return new TaskData
{
TaskName = taskName,
RemainingTaskCount = remainingTaskCount
};
}
private bool IsQuestLocked(string questId)
{
if (ElementId.TryFromString(questId, out ElementId elementId) && elementId != null && _questRegistry.TryGetQuest(elementId, out Quest _))
{
return _questFunctions.IsQuestLocked(elementId);
}
return true;
}
private bool IsQuestComplete(string questId)
{
if (ElementId.TryFromString(questId, out ElementId elementId) && elementId != null)
{
return _questFunctions.IsQuestComplete(elementId);
}
return false;
}
private bool IsReadyToAcceptQuest(string questId)
{
if (ElementId.TryFromString(questId, out ElementId elementId) && elementId != null)
{
return _questFunctions.IsReadyToAcceptQuest(elementId);
}
return false;
}
private bool IsQuestAccepted(string questId)
{
if (ElementId.TryFromString(questId, out ElementId elementId) && elementId != null)
{
return _questFunctions.IsQuestAccepted(elementId);
}
return false;
}
private bool IsQuestUnobtainable(string questId)
{
if (ElementId.TryFromString(questId, out ElementId elementId) && elementId != null)
{
return _questFunctions.IsQuestUnobtainable(elementId);
}
return false;
}
private bool ImportQuestPriority(string encodedQuestPriority)
{
List<ElementId> questElements = PriorityWindow.DecodeQuestPriority(encodedQuestPriority);
_questController.ImportQuestPriority(questElements);
return true;
}
private bool ClearQuestPriority()
{
_questController.ClearQuestPriority();
return true;
}
private bool AddQuestPriority(string questId)
{
if (ElementId.TryFromString(questId, out ElementId elementId) && elementId != null && _questRegistry.IsKnownQuest(elementId))
{
return _questController.AddQuestPriority(elementId);
}
return true;
}
private bool InsertQuestPriority(int index, string questId)
{
if (ElementId.TryFromString(questId, out ElementId elementId) && elementId != null && _questRegistry.IsKnownQuest(elementId))
{
return _questController.InsertQuestPriority(index, elementId);
}
return true;
}
private int GetDefaultDutyMode()
{
return (int)_configuration.Duties.DefaultDutyMode;
}
private bool SetDefaultDutyMode(int dutyMode)
{
if (!Enum.IsDefined(typeof(EDutyMode), dutyMode))
{
return false;
}
_configuration.Duties.DefaultDutyMode = (EDutyMode)dutyMode;
_pluginInterface.SavePluginConfig(_configuration);
return true;
}
private int GetDutyModeOverride(uint contentFinderConditionId)
{
if (_configuration.Duties.DutyModeOverrides.TryGetValue(contentFinderConditionId, out var value))
{
return (int)value;
}
return -1;
}
private bool SetDutyModeOverride(uint contentFinderConditionId, int dutyMode)
{
if (!Enum.IsDefined(typeof(EDutyMode), dutyMode))
{
return false;
}
_configuration.Duties.DutyModeOverrides[contentFinderConditionId] = (EDutyMode)dutyMode;
_pluginInterface.SavePluginConfig(_configuration);
return true;
}
private bool ClearDutyModeOverride(uint contentFinderConditionId)
{
bool num = _configuration.Duties.DutyModeOverrides.Remove(contentFinderConditionId);
if (num)
{
_pluginInterface.SavePluginConfig(_configuration);
}
return num;
}
private bool ClearAllDutyModeOverrides()
{
_configuration.Duties.DutyModeOverrides.Clear();
_pluginInterface.SavePluginConfig(_configuration);
return true;
}
public void Dispose()
{
_clearAllDutyModeOverrides.UnregisterFunc();
_clearDutyModeOverride.UnregisterFunc();
_setDutyModeOverride.UnregisterFunc();
_getDutyModeOverride.UnregisterFunc();
_setDefaultDutyMode.UnregisterFunc();
_getDefaultDutyMode.UnregisterFunc();
_exportQuestPriority.UnregisterFunc();
_insertQuestPriority.UnregisterFunc();
_clearQuestPriority.UnregisterFunc();
_addQuestPriority.UnregisterFunc();
_importQuestPriority.UnregisterFunc();
_isQuestUnobtainable.UnregisterFunc();
_isQuestAccepted.UnregisterFunc();
_IsReadyToAcceptQuest.UnregisterFunc();
_IsQuestComplete.UnregisterFunc();
_isQuestLocked.UnregisterFunc();
_startSingleQuest.UnregisterFunc();
_startQuest.UnregisterFunc();
_getCurrentlyActiveEventQuests.UnregisterFunc();
_getCurrentTask.UnregisterFunc();
_getCurrentStepData.UnregisterFunc();
_getCurrentQuestId.UnregisterFunc();
_isRunning.UnregisterFunc();
}
}