punish v6.8.18.0
This commit is contained in:
commit
cfb4dea47e
316 changed files with 554088 additions and 0 deletions
50
Questionable/Questionable.External/ArtisanIpc.cs
Normal file
50
Questionable/Questionable.External/ArtisanIpc.cs
Normal file
|
@ -0,0 +1,50 @@
|
|||
using Dalamud.Plugin;
|
||||
using Dalamud.Plugin.Ipc;
|
||||
using Dalamud.Plugin.Ipc.Exceptions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Questionable.External;
|
||||
|
||||
internal sealed class ArtisanIpc
|
||||
{
|
||||
private readonly ILogger<ArtisanIpc> _logger;
|
||||
|
||||
private readonly ICallGateSubscriber<ushort, int, object> _craftItem;
|
||||
|
||||
private readonly ICallGateSubscriber<bool> _getEnduranceStatus;
|
||||
|
||||
public ArtisanIpc(IDalamudPluginInterface pluginInterface, ILogger<ArtisanIpc> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_craftItem = pluginInterface.GetIpcSubscriber<ushort, int, object>("Artisan.CraftItem");
|
||||
_getEnduranceStatus = pluginInterface.GetIpcSubscriber<bool>("Artisan.GetEnduranceStatus");
|
||||
}
|
||||
|
||||
public bool CraftItem(ushort recipeId, int quantity)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Attempting to craft {Quantity} items with recipe {RecipeId} with Artisan", quantity, recipeId);
|
||||
_craftItem.InvokeAction(recipeId, quantity);
|
||||
return true;
|
||||
}
|
||||
catch (IpcError exception)
|
||||
{
|
||||
_logger.LogError(exception, "Unable to craft items");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCrafting()
|
||||
{
|
||||
try
|
||||
{
|
||||
return _getEnduranceStatus.InvokeFunc();
|
||||
}
|
||||
catch (IpcError exception)
|
||||
{
|
||||
_logger.LogError(exception, "Unable to check for Artisan endurance status");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
138
Questionable/Questionable.External/AutoDutyIpc.cs
Normal file
138
Questionable/Questionable.External/AutoDutyIpc.cs
Normal file
|
@ -0,0 +1,138 @@
|
|||
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<AutoDutyIpc> _logger;
|
||||
|
||||
private readonly ICallGateSubscriber<uint, bool> _contentHasPath;
|
||||
|
||||
private readonly ICallGateSubscriber<string, string, object> _setConfig;
|
||||
|
||||
private readonly ICallGateSubscriber<uint, int, bool, object> _run;
|
||||
|
||||
private readonly ICallGateSubscriber<bool> _isStopped;
|
||||
|
||||
private readonly ICallGateSubscriber<object> _stop;
|
||||
|
||||
public AutoDutyIpc(IDalamudPluginInterface pluginInterface, Configuration configuration, TerritoryData territoryData, ILogger<AutoDutyIpc> logger)
|
||||
{
|
||||
_configuration = configuration;
|
||||
_territoryData = territoryData;
|
||||
_logger = logger;
|
||||
_contentHasPath = pluginInterface.GetIpcSubscriber<uint, bool>("AutoDuty.ContentHasPath");
|
||||
_setConfig = pluginInterface.GetIpcSubscriber<string, string, object>("AutoDuty.SetConfig");
|
||||
_run = pluginInterface.GetIpcSubscriber<uint, int, bool, object>("AutoDuty.Run");
|
||||
_isStopped = pluginInterface.GetIpcSubscriber<bool>("AutoDuty.IsStopped");
|
||||
_stop = pluginInterface.GetIpcSubscriber<object>("AutoDuty.Stop");
|
||||
}
|
||||
|
||||
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 HasPath(uint cfcId)
|
||||
{
|
||||
if (!_territoryData.TryGetContentFinderCondition(cfcId, out TerritoryData.ContentFinderConditionData contentFinderConditionData))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
return _contentHasPath.InvokeFunc(contentFinderConditionData.TerritoryId);
|
||||
}
|
||||
catch (IpcError ipcError)
|
||||
{
|
||||
_logger.LogWarning("Unable to query AutoDuty for path in territory {TerritoryType}: {Message}", contentFinderConditionData.TerritoryId, ipcError.Message);
|
||||
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("Unsynced", $"{dutyMode == DutyMode.UnsyncRegular}");
|
||||
ICallGateSubscriber<string, string, object> 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 IsStopped()
|
||||
{
|
||||
try
|
||||
{
|
||||
return _isStopped.InvokeFunc();
|
||||
}
|
||||
catch (IpcError)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Calling AutoDuty.Stop");
|
||||
_stop.InvokeAction();
|
||||
}
|
||||
catch (IpcError ipcError)
|
||||
{
|
||||
throw new TaskException("Unable to stop AutoDuty: " + ipcError.Message, ipcError);
|
||||
}
|
||||
}
|
||||
}
|
42
Questionable/Questionable.External/AutomatonIpc.cs
Normal file
42
Questionable/Questionable.External/AutomatonIpc.cs
Normal file
|
@ -0,0 +1,42 @@
|
|||
using Dalamud.Plugin;
|
||||
using Dalamud.Plugin.Ipc;
|
||||
using Dalamud.Plugin.Ipc.Exceptions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Questionable.External;
|
||||
|
||||
internal sealed class AutomatonIpc
|
||||
{
|
||||
private readonly ILogger<AutomatonIpc> _logger;
|
||||
|
||||
private readonly ICallGateSubscriber<string, bool> _isTweakEnabled;
|
||||
|
||||
private bool _loggedIpcError;
|
||||
|
||||
public bool IsAutoSnipeEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return _isTweakEnabled.InvokeFunc("AutoSnipeQuests");
|
||||
}
|
||||
catch (IpcError exception)
|
||||
{
|
||||
if (!_loggedIpcError)
|
||||
{
|
||||
_loggedIpcError = true;
|
||||
_logger.LogWarning(exception, "Could not query automaton for tweak status, probably not installed");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AutomatonIpc(IDalamudPluginInterface pluginInterface, ILogger<AutomatonIpc> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_isTweakEnabled = pluginInterface.GetIpcSubscriber<string, bool>("Automaton.IsTweakEnabled");
|
||||
logger.LogInformation("Automaton auto-snipe enabled: {IsTweakEnabled}", IsAutoSnipeEnabled);
|
||||
}
|
||||
}
|
150
Questionable/Questionable.External/BossModIpc.cs
Normal file
150
Questionable/Questionable.External/BossModIpc.cs
Normal file
|
@ -0,0 +1,150 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Plugin.Ipc;
|
||||
using Dalamud.Plugin.Ipc.Exceptions;
|
||||
using Dalamud.Plugin.Services;
|
||||
using Questionable.Data;
|
||||
using Questionable.Model.Questing;
|
||||
|
||||
namespace Questionable.External;
|
||||
|
||||
internal sealed class BossModIpc
|
||||
{
|
||||
public enum EPreset
|
||||
{
|
||||
Overworld,
|
||||
QuestBattle
|
||||
}
|
||||
|
||||
private sealed class PresetDefinition
|
||||
{
|
||||
public string Name { get; }
|
||||
|
||||
public string Content { get; }
|
||||
|
||||
public PresetDefinition(string name, string fileName)
|
||||
{
|
||||
Name = name;
|
||||
Content = LoadPreset(fileName);
|
||||
base._002Ector();
|
||||
}
|
||||
|
||||
private static string LoadPreset(string name)
|
||||
{
|
||||
using StreamReader streamReader = new StreamReader(typeof(BossModIpc).Assembly.GetManifestResourceStream("Questionable.Controller.CombatModules.BossModPreset." + name) ?? throw new InvalidOperationException("Preset " + name + " was not found"));
|
||||
return streamReader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
private const string PluginName = "BossMod";
|
||||
|
||||
private static readonly ReadOnlyDictionary<EPreset, PresetDefinition> PresetDefinitions = new Dictionary<EPreset, PresetDefinition>
|
||||
{
|
||||
{
|
||||
EPreset.Overworld,
|
||||
new PresetDefinition("Questionable", "Overworld")
|
||||
},
|
||||
{
|
||||
EPreset.QuestBattle,
|
||||
new PresetDefinition("Questionable - Quest Battles", "QuestBattle")
|
||||
}
|
||||
}.AsReadOnly();
|
||||
|
||||
private readonly Configuration _configuration;
|
||||
|
||||
private readonly ICommandManager _commandManager;
|
||||
|
||||
private readonly TerritoryData _territoryData;
|
||||
|
||||
private readonly ICallGateSubscriber<string, string?> _getPreset;
|
||||
|
||||
private readonly ICallGateSubscriber<string, bool, bool> _createPreset;
|
||||
|
||||
private readonly ICallGateSubscriber<string, bool> _setPreset;
|
||||
|
||||
private readonly ICallGateSubscriber<bool> _clearPreset;
|
||||
|
||||
public BossModIpc(IDalamudPluginInterface pluginInterface, Configuration configuration, ICommandManager commandManager, TerritoryData territoryData)
|
||||
{
|
||||
_configuration = configuration;
|
||||
_commandManager = commandManager;
|
||||
_territoryData = territoryData;
|
||||
_getPreset = pluginInterface.GetIpcSubscriber<string, string>("BossMod.Presets.Get");
|
||||
_createPreset = pluginInterface.GetIpcSubscriber<string, bool, bool>("BossMod.Presets.Create");
|
||||
_setPreset = pluginInterface.GetIpcSubscriber<string, bool>("BossMod.Presets.SetActive");
|
||||
_clearPreset = pluginInterface.GetIpcSubscriber<bool>("BossMod.Presets.ClearActive");
|
||||
}
|
||||
|
||||
public bool IsSupported()
|
||||
{
|
||||
try
|
||||
{
|
||||
return _getPreset.HasFunction;
|
||||
}
|
||||
catch (IpcError)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPreset(EPreset preset)
|
||||
{
|
||||
PresetDefinition presetDefinition = PresetDefinitions[preset];
|
||||
if (_getPreset.InvokeFunc(presetDefinition.Name) == null)
|
||||
{
|
||||
_createPreset.InvokeFunc(presetDefinition.Content, arg2: true);
|
||||
}
|
||||
_setPreset.InvokeFunc(presetDefinition.Name);
|
||||
}
|
||||
|
||||
public void ClearPreset()
|
||||
{
|
||||
_clearPreset.InvokeFunc();
|
||||
}
|
||||
|
||||
public void EnableAi(bool passive)
|
||||
{
|
||||
_commandManager.ProcessCommand("/vbmai on");
|
||||
_commandManager.ProcessCommand("/vbm cfg ZoneModuleConfig EnableQuestBattles true");
|
||||
SetPreset((!passive) ? EPreset.QuestBattle : EPreset.Overworld);
|
||||
}
|
||||
|
||||
public void DisableAi()
|
||||
{
|
||||
_commandManager.ProcessCommand("/vbmai off");
|
||||
_commandManager.ProcessCommand("/vbm cfg ZoneModuleConfig EnableQuestBattles false");
|
||||
ClearPreset();
|
||||
}
|
||||
|
||||
public bool IsConfiguredToRunSoloInstance(ElementId questId, SinglePlayerDutyOptions? dutyOptions)
|
||||
{
|
||||
if (!IsSupported())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!_configuration.SinglePlayerDuties.RunSoloInstancesWithBossMod)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (dutyOptions == null)
|
||||
{
|
||||
dutyOptions = new SinglePlayerDutyOptions();
|
||||
}
|
||||
if (!_territoryData.TryGetContentFinderConditionForSoloInstance(questId, dutyOptions.Index, out TerritoryData.ContentFinderConditionData contentFinderConditionData))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (_configuration.SinglePlayerDuties.BlacklistedSinglePlayerDutyCfcIds.Contains(contentFinderConditionData.ContentFinderConditionId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (_configuration.SinglePlayerDuties.WhitelistedSinglePlayerDutyCfcIds.Contains(contentFinderConditionData.ContentFinderConditionId))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return dutyOptions.Enabled;
|
||||
}
|
||||
}
|
45
Questionable/Questionable.External/LifestreamIpc.cs
Normal file
45
Questionable/Questionable.External/LifestreamIpc.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Plugin.Ipc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.Model.Common;
|
||||
|
||||
namespace Questionable.External;
|
||||
|
||||
internal sealed class LifestreamIpc
|
||||
{
|
||||
private readonly ILogger<LifestreamIpc> _logger;
|
||||
|
||||
private readonly ICallGateSubscriber<uint, bool> _aethernetTeleportByPlaceNameId;
|
||||
|
||||
private readonly ICallGateSubscriber<uint, bool> _aethernetTeleportById;
|
||||
|
||||
private readonly ICallGateSubscriber<bool> _aethernetTeleportToFirmament;
|
||||
|
||||
public LifestreamIpc(IDalamudPluginInterface pluginInterface, ILogger<LifestreamIpc> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_aethernetTeleportByPlaceNameId = pluginInterface.GetIpcSubscriber<uint, bool>("Lifestream.AethernetTeleportByPlaceNameId");
|
||||
_aethernetTeleportById = pluginInterface.GetIpcSubscriber<uint, bool>("Lifestream.AethernetTeleportById");
|
||||
_aethernetTeleportToFirmament = pluginInterface.GetIpcSubscriber<bool>("Lifestream.AethernetTeleportToFirmament");
|
||||
}
|
||||
|
||||
public bool Teleport(EAetheryteLocation aetheryteLocation)
|
||||
{
|
||||
_logger.LogInformation("Teleporting to '{Name}'", aetheryteLocation);
|
||||
return aetheryteLocation switch
|
||||
{
|
||||
EAetheryteLocation.IshgardFirmament => _aethernetTeleportToFirmament.InvokeFunc(),
|
||||
EAetheryteLocation.FirmamentMendicantsCourt => _aethernetTeleportByPlaceNameId.InvokeFunc(3436u),
|
||||
EAetheryteLocation.FirmamentMattock => _aethernetTeleportByPlaceNameId.InvokeFunc(3473u),
|
||||
EAetheryteLocation.FirmamentNewNest => _aethernetTeleportByPlaceNameId.InvokeFunc(3475u),
|
||||
EAetheryteLocation.FirmanentSaintRoellesDais => _aethernetTeleportByPlaceNameId.InvokeFunc(3474u),
|
||||
EAetheryteLocation.FirmamentFeatherfall => _aethernetTeleportByPlaceNameId.InvokeFunc(3525u),
|
||||
EAetheryteLocation.FirmamentHoarfrostHall => _aethernetTeleportByPlaceNameId.InvokeFunc(3528u),
|
||||
EAetheryteLocation.FirmamentWesternRisensongQuarter => _aethernetTeleportByPlaceNameId.InvokeFunc(3646u),
|
||||
EAetheryteLocation.FIrmamentEasternRisensongQuarter => _aethernetTeleportByPlaceNameId.InvokeFunc(3645u),
|
||||
EAetheryteLocation.None => throw new ArgumentOutOfRangeException("aetheryteLocation"),
|
||||
_ => _aethernetTeleportById.InvokeFunc((uint)aetheryteLocation),
|
||||
};
|
||||
}
|
||||
}
|
161
Questionable/Questionable.External/NavmeshIpc.cs
Normal file
161
Questionable/Questionable.External/NavmeshIpc.cs
Normal file
|
@ -0,0 +1,161 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Plugin.Ipc;
|
||||
using Dalamud.Plugin.Ipc.Exceptions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Questionable.External;
|
||||
|
||||
internal sealed class NavmeshIpc
|
||||
{
|
||||
private readonly ILogger<NavmeshIpc> _logger;
|
||||
|
||||
private readonly ICallGateSubscriber<bool> _isNavReady;
|
||||
|
||||
private readonly ICallGateSubscriber<Vector3, Vector3, bool, CancellationToken, Task<List<Vector3>>> _navPathfind;
|
||||
|
||||
private readonly ICallGateSubscriber<List<Vector3>, bool, object> _pathMoveTo;
|
||||
|
||||
private readonly ICallGateSubscriber<object> _pathStop;
|
||||
|
||||
private readonly ICallGateSubscriber<bool> _pathIsRunning;
|
||||
|
||||
private readonly ICallGateSubscriber<List<Vector3>> _pathListWaypoints;
|
||||
|
||||
private readonly ICallGateSubscriber<float, object> _pathSetTolerance;
|
||||
|
||||
private readonly ICallGateSubscriber<Vector3, bool, float, Vector3?> _queryPointOnFloor;
|
||||
|
||||
private readonly ICallGateSubscriber<float> _buildProgress;
|
||||
|
||||
public bool IsReady
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return _isNavReady.InvokeFunc();
|
||||
}
|
||||
catch (IpcError)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPathRunning
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return _pathIsRunning.InvokeFunc();
|
||||
}
|
||||
catch (IpcError)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public NavmeshIpc(IDalamudPluginInterface pluginInterface, ILogger<NavmeshIpc> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_isNavReady = pluginInterface.GetIpcSubscriber<bool>("vnavmesh.Nav.IsReady");
|
||||
_navPathfind = pluginInterface.GetIpcSubscriber<Vector3, Vector3, bool, CancellationToken, Task<List<Vector3>>>("vnavmesh.Nav.PathfindCancelable");
|
||||
_pathMoveTo = pluginInterface.GetIpcSubscriber<List<Vector3>, bool, object>("vnavmesh.Path.MoveTo");
|
||||
_pathStop = pluginInterface.GetIpcSubscriber<object>("vnavmesh.Path.Stop");
|
||||
_pathIsRunning = pluginInterface.GetIpcSubscriber<bool>("vnavmesh.Path.IsRunning");
|
||||
_pathListWaypoints = pluginInterface.GetIpcSubscriber<List<Vector3>>("vnavmesh.Path.ListWaypoints");
|
||||
_pathSetTolerance = pluginInterface.GetIpcSubscriber<float, object>("vnavmesh.Path.SetTolerance");
|
||||
_queryPointOnFloor = pluginInterface.GetIpcSubscriber<Vector3, bool, float, Vector3?>("vnavmesh.Query.Mesh.PointOnFloor");
|
||||
_buildProgress = pluginInterface.GetIpcSubscriber<float>("vnavmesh.Nav.BuildProgress");
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
_pathStop.InvokeAction();
|
||||
}
|
||||
catch (IpcError exception)
|
||||
{
|
||||
_logger.LogWarning(exception, "Could not stop navigating via navmesh");
|
||||
}
|
||||
}
|
||||
|
||||
public Task<List<Vector3>> Pathfind(Vector3 localPlayerPosition, Vector3 targetPosition, bool fly, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
_pathSetTolerance.InvokeAction(0.25f);
|
||||
return _navPathfind.InvokeFunc(localPlayerPosition, targetPosition, fly, cancellationToken);
|
||||
}
|
||||
catch (IpcError exception)
|
||||
{
|
||||
_logger.LogWarning(exception, "Could not pathfind via navmesh");
|
||||
return Task.FromException<List<Vector3>>(exception);
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveTo(List<Vector3> position, bool fly)
|
||||
{
|
||||
Stop();
|
||||
try
|
||||
{
|
||||
_pathMoveTo.InvokeAction(position, fly);
|
||||
}
|
||||
catch (IpcError exception)
|
||||
{
|
||||
_logger.LogWarning(exception, "Could not move via navmesh");
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3? GetPointOnFloor(Vector3 position, bool unlandable)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _queryPointOnFloor.InvokeFunc(position, unlandable, 0.2f);
|
||||
}
|
||||
catch (IpcError)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Vector3> GetWaypoints()
|
||||
{
|
||||
if (IsPathRunning)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _pathListWaypoints.InvokeFunc();
|
||||
}
|
||||
catch (IpcError)
|
||||
{
|
||||
return new List<Vector3>();
|
||||
}
|
||||
}
|
||||
return new List<Vector3>();
|
||||
}
|
||||
|
||||
public int GetBuildProgress()
|
||||
{
|
||||
try
|
||||
{
|
||||
float num = _buildProgress.InvokeFunc();
|
||||
if (num < 0f)
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
return (int)(num * 100f);
|
||||
}
|
||||
catch (IpcError)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
34
Questionable/Questionable.External/NotificationMasterIpc.cs
Normal file
34
Questionable/Questionable.External/NotificationMasterIpc.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
using Dalamud.Plugin;
|
||||
using NotificationMasterAPI;
|
||||
|
||||
namespace Questionable.External;
|
||||
|
||||
internal sealed class NotificationMasterIpc
|
||||
{
|
||||
private readonly NotificationMasterApi _api;
|
||||
|
||||
public bool Enabled => _api.IsIPCReady();
|
||||
|
||||
public NotificationMasterIpc(IDalamudPluginInterface pluginInterface, Configuration configuration)
|
||||
{
|
||||
_003Cconfiguration_003EP = configuration;
|
||||
_api = new NotificationMasterApi(pluginInterface);
|
||||
base._002Ector();
|
||||
}
|
||||
|
||||
public void Notify(string message)
|
||||
{
|
||||
Configuration.NotificationConfiguration notifications = _003Cconfiguration_003EP.Notifications;
|
||||
if (notifications.Enabled)
|
||||
{
|
||||
if (notifications.ShowTrayMessage)
|
||||
{
|
||||
_api.DisplayTrayNotification("Questionable", message);
|
||||
}
|
||||
if (notifications.FlashTaskbar)
|
||||
{
|
||||
_api.FlashTaskbarIcon();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
132
Questionable/Questionable.External/PandorasBoxIpc.cs
Normal file
132
Questionable/Questionable.External/PandorasBoxIpc.cs
Normal file
|
@ -0,0 +1,132 @@
|
|||
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<string> ConflictingFeatures = new HashSet<string> { "Auto-Meditation", "Auto-Motif (Out of Combat)", "Auto-Mount after Combat", "Auto-Mount after Gathering", "Auto-Peleton", "Auto-Spring in Sanctuaries", "Auto-select Turn-ins", "Auto-Sync FATEs", "Auto-interact with Gathering Nodes", "Pandora Quick Gather" }.ToImmutableHashSet();
|
||||
|
||||
private readonly IFramework _framework;
|
||||
|
||||
private readonly QuestController _questController;
|
||||
|
||||
private readonly TerritoryData _territoryData;
|
||||
|
||||
private readonly IClientState _clientState;
|
||||
|
||||
private readonly ILogger<PandorasBoxIpc> _logger;
|
||||
|
||||
private readonly ICallGateSubscriber<string, bool?> _getFeatureEnabled;
|
||||
|
||||
private readonly ICallGateSubscriber<string, bool, object?> _setFeatureEnabled;
|
||||
|
||||
private bool _loggedIpcError;
|
||||
|
||||
private HashSet<string>? _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<PandorasBoxIpc> logger)
|
||||
{
|
||||
_framework = framework;
|
||||
_questController = questController;
|
||||
_territoryData = territoryData;
|
||||
_clientState = clientState;
|
||||
_logger = logger;
|
||||
_getFeatureEnabled = pluginInterface.GetIpcSubscriber<string, bool?>("PandorasBox.GetFeatureEnabled");
|
||||
_setFeatureEnabled = pluginInterface.GetIpcSubscriber<string, bool, object>("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<string>();
|
||||
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;
|
||||
}
|
||||
}
|
221
Questionable/Questionable.External/QuestionableIpc.cs
Normal file
221
Questionable/Questionable.External/QuestionableIpc.cs
Normal file
|
@ -0,0 +1,221 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Plugin.Ipc;
|
||||
using Questionable.Controller;
|
||||
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; }
|
||||
}
|
||||
|
||||
private const string IpcIsRunning = "Questionable.IsRunning";
|
||||
|
||||
private const string IpcGetCurrentQuestId = "Questionable.GetCurrentQuestId";
|
||||
|
||||
private const string IpcGetCurrentStepData = "Questionable.GetCurrentStepData";
|
||||
|
||||
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 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 readonly QuestController _questController;
|
||||
|
||||
private readonly QuestRegistry _questRegistry;
|
||||
|
||||
private readonly QuestFunctions _questFunctions;
|
||||
|
||||
private readonly ICallGateProvider<bool> _isRunning;
|
||||
|
||||
private readonly ICallGateProvider<string?> _getCurrentQuestId;
|
||||
|
||||
private readonly ICallGateProvider<StepData?> _getCurrentStepData;
|
||||
|
||||
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> _importQuestPriority;
|
||||
|
||||
private readonly ICallGateProvider<string, bool> _addQuestPriority;
|
||||
|
||||
private readonly ICallGateProvider<bool> _clearQuestPriority;
|
||||
|
||||
private readonly ICallGateProvider<int, string, bool> _insertQuestPriority;
|
||||
|
||||
private readonly ICallGateProvider<string> _exportQuestPriority;
|
||||
|
||||
public QuestionableIpc(QuestController questController, EventInfoComponent eventInfoComponent, QuestRegistry questRegistry, QuestFunctions questFunctions, PriorityWindow priorityWindow, IDalamudPluginInterface pluginInterface)
|
||||
{
|
||||
QuestionableIpc questionableIpc = this;
|
||||
_questController = questController;
|
||||
_questRegistry = questRegistry;
|
||||
_questFunctions = questFunctions;
|
||||
_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);
|
||||
_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);
|
||||
_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(priorityWindow.EncodeQuestPriority);
|
||||
}
|
||||
|
||||
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 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 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;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_exportQuestPriority.UnregisterFunc();
|
||||
_insertQuestPriority.UnregisterFunc();
|
||||
_clearQuestPriority.UnregisterFunc();
|
||||
_addQuestPriority.UnregisterFunc();
|
||||
_importQuestPriority.UnregisterFunc();
|
||||
_isQuestLocked.UnregisterFunc();
|
||||
_startSingleQuest.UnregisterFunc();
|
||||
_startQuest.UnregisterFunc();
|
||||
_getCurrentlyActiveEventQuests.UnregisterFunc();
|
||||
_getCurrentStepData.UnregisterFunc();
|
||||
_getCurrentQuestId.UnregisterFunc();
|
||||
_isRunning.UnregisterFunc();
|
||||
}
|
||||
}
|
86
Questionable/Questionable.External/TextAdvanceIpc.cs
Normal file
86
Questionable/Questionable.External/TextAdvanceIpc.cs
Normal file
|
@ -0,0 +1,86 @@
|
|||
using System;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Plugin.Ipc;
|
||||
using Dalamud.Plugin.Services;
|
||||
using Questionable.Controller;
|
||||
|
||||
namespace Questionable.External;
|
||||
|
||||
internal sealed class TextAdvanceIpc : IDisposable
|
||||
{
|
||||
public sealed class ExternalTerritoryConfig
|
||||
{
|
||||
public bool? EnableQuestAccept = true;
|
||||
|
||||
public bool? EnableQuestComplete = true;
|
||||
|
||||
public bool? EnableRewardPick = true;
|
||||
|
||||
public bool? EnableRequestHandin = true;
|
||||
|
||||
public bool? EnableCutsceneEsc = true;
|
||||
|
||||
public bool? EnableCutsceneSkipConfirm = true;
|
||||
|
||||
public bool? EnableTalkSkip = true;
|
||||
|
||||
public bool? EnableRequestFill = true;
|
||||
|
||||
public bool? EnableAutoInteract = false;
|
||||
}
|
||||
|
||||
private bool _isExternalControlActivated;
|
||||
|
||||
private readonly QuestController _questController;
|
||||
|
||||
private readonly Configuration _configuration;
|
||||
|
||||
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 ExternalTerritoryConfig _externalTerritoryConfig = new ExternalTerritoryConfig();
|
||||
|
||||
public TextAdvanceIpc(IDalamudPluginInterface pluginInterface, IFramework framework, QuestController questController, Configuration configuration)
|
||||
{
|
||||
_framework = framework;
|
||||
_questController = questController;
|
||||
_configuration = configuration;
|
||||
_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)
|
||||
{
|
||||
_disableExternalControl.InvokeFunc(_pluginName);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnUpdate(IFramework framework)
|
||||
{
|
||||
bool flag = _questController.IsRunning || _questController.AutomationType != QuestController.EAutomationType.Manual;
|
||||
if (_configuration.General.ConfigureTextAdvance && flag)
|
||||
{
|
||||
if (!_isInExternalControl.InvokeFunc() && _enableExternalControl.InvokeFunc(_pluginName, _externalTerritoryConfig))
|
||||
{
|
||||
_isExternalControlActivated = true;
|
||||
}
|
||||
}
|
||||
else if (_isExternalControlActivated && (_disableExternalControl.InvokeFunc(_pluginName) || !_isInExternalControl.InvokeFunc()))
|
||||
{
|
||||
_isExternalControlActivated = false;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue