forked from liza/Questionable
Remove 'Automatically complete snipe tasks'
This commit is contained in:
parent
73e030b620
commit
0265fcc0ae
@ -7,7 +7,7 @@ namespace Questionable;
|
||||
|
||||
internal sealed class Configuration : IPluginConfiguration
|
||||
{
|
||||
public const int PluginSetupVersion = 1;
|
||||
public const int PluginSetupVersion = 2;
|
||||
|
||||
public int Version { get; set; } =1 ;
|
||||
public int PluginSetupCompleteVersion { get; set; }
|
||||
@ -28,7 +28,6 @@ internal sealed class Configuration : IPluginConfiguration
|
||||
public bool HideInAllInstances { get; set; } = true;
|
||||
public bool UseEscToCancelQuesting { get; set; } = true;
|
||||
public bool ShowIncompleteSeasonalEvents { get; set; } = true;
|
||||
public bool AutomaticallyCompleteSnipeTasks { get; set; }
|
||||
public bool ConfigureTextAdvance { get; set; } = true;
|
||||
}
|
||||
|
||||
|
@ -12,14 +12,14 @@ namespace Questionable.Controller.Steps.Common;
|
||||
internal static class SendNotification
|
||||
{
|
||||
internal sealed class Factory(
|
||||
Configuration configuration,
|
||||
AutomatonIpc automatonIpc,
|
||||
TerritoryData territoryData) : SimpleTaskFactory
|
||||
{
|
||||
public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
return step.InteractionType switch
|
||||
{
|
||||
EInteractionType.Snipe when !configuration.General.AutomaticallyCompleteSnipeTasks =>
|
||||
EInteractionType.Snipe when !automatonIpc.IsAutoSnipeEnabled =>
|
||||
new Task(step.InteractionType, step.Comment),
|
||||
EInteractionType.Duty =>
|
||||
new Task(step.InteractionType, step.ContentFinderConditionId.HasValue
|
||||
|
@ -8,6 +8,7 @@ using FFXIVClientStructs.FFXIV.Client.Game;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.Controller.Steps.Shared;
|
||||
using Questionable.Controller.Utils;
|
||||
using Questionable.External;
|
||||
using Questionable.Functions;
|
||||
using Questionable.Model;
|
||||
using Questionable.Model.Questing;
|
||||
@ -16,7 +17,7 @@ namespace Questionable.Controller.Steps.Interactions;
|
||||
|
||||
internal static class Interact
|
||||
{
|
||||
internal sealed class Factory(Configuration configuration) : ITaskFactory
|
||||
internal sealed class Factory(AutomatonIpc automatonIpc) : ITaskFactory
|
||||
{
|
||||
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
||||
{
|
||||
@ -43,7 +44,7 @@ internal static class Interact
|
||||
}
|
||||
else if (step.InteractionType == EInteractionType.Snipe)
|
||||
{
|
||||
if (!configuration.General.AutomaticallyCompleteSnipeTasks)
|
||||
if (!automatonIpc.IsAutoSnipeEnabled)
|
||||
yield break;
|
||||
}
|
||||
else if (step.InteractionType != EInteractionType.Interact)
|
||||
|
@ -1,48 +0,0 @@
|
||||
using System;
|
||||
using Dalamud.Hooking;
|
||||
using Dalamud.Plugin.Services;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Event;
|
||||
using FFXIVClientStructs.FFXIV.Common.Lua;
|
||||
|
||||
namespace Questionable.Controller.Utils;
|
||||
|
||||
internal sealed unsafe class AutoSnipeHandler : IDisposable
|
||||
{
|
||||
private readonly QuestController _questController;
|
||||
private readonly Configuration _configuration;
|
||||
private readonly Hook<EnqueueSnipeTaskDelegate> _enqueueSnipeTaskHook;
|
||||
|
||||
private delegate ulong EnqueueSnipeTaskDelegate(EventSceneModuleImplBase* scene, lua_State* state);
|
||||
|
||||
public AutoSnipeHandler(QuestController questController, Configuration configuration, IGameInteropProvider gameInteropProvider)
|
||||
{
|
||||
_questController = questController;
|
||||
_configuration = configuration;
|
||||
|
||||
_enqueueSnipeTaskHook =
|
||||
gameInteropProvider.HookFromSignature<EnqueueSnipeTaskDelegate>(
|
||||
"48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 50 48 8B F1 48 8D 4C 24 ?? E8 ?? ?? ?? ?? 48 8B 4C 24 ??",
|
||||
EnqueueSnipeTask);
|
||||
}
|
||||
|
||||
public void Enable() => _enqueueSnipeTaskHook.Enable();
|
||||
|
||||
private ulong EnqueueSnipeTask(EventSceneModuleImplBase* scene, lua_State* state)
|
||||
{
|
||||
if (_configuration.General.AutomaticallyCompleteSnipeTasks && _questController.IsRunning)
|
||||
{
|
||||
var val = state->top;
|
||||
val->tt = 3;
|
||||
val->value.n = 1;
|
||||
state->top += 1;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return _enqueueSnipeTaskHook.Original.Invoke(scene, state);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_enqueueSnipeTaskHook.Dispose();
|
||||
}
|
||||
}
|
40
Questionable/External/AutomatonIpc.cs
vendored
Normal file
40
Questionable/External/AutomatonIpc.cs
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
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 AutomatonIpc(IDalamudPluginInterface pluginInterface, ILogger<AutomatonIpc> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_isTweakEnabled = pluginInterface.GetIpcSubscriber<string, bool>("Automaton.IsTweakEnabled");
|
||||
logger.LogWarning("Automaton x {IsTweakEnabled}", IsAutoSnipeEnabled);
|
||||
}
|
||||
|
||||
public bool IsAutoSnipeEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return _isTweakEnabled.InvokeFunc("AutoSnipeQuests");
|
||||
}
|
||||
catch (IpcError e)
|
||||
{
|
||||
if (!_loggedIpcError)
|
||||
{
|
||||
_loggedIpcError = true;
|
||||
_logger.LogWarning(e, "Could not query automaton for tweak status, probably not installed");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -112,7 +112,6 @@ public sealed class QuestionablePlugin : IDalamudPlugin
|
||||
serviceCollection.AddSingleton<ChatFunctions>();
|
||||
serviceCollection.AddSingleton<QuestFunctions>();
|
||||
serviceCollection.AddSingleton<DalamudReflector>();
|
||||
serviceCollection.AddSingleton<AutoSnipeHandler>();
|
||||
|
||||
serviceCollection.AddSingleton<AetherCurrentData>();
|
||||
serviceCollection.AddSingleton<AetheryteData>();
|
||||
@ -128,6 +127,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin
|
||||
serviceCollection.AddSingleton<QuestionableIpc>();
|
||||
serviceCollection.AddSingleton<TextAdvanceIpc>();
|
||||
serviceCollection.AddSingleton<NotificationMasterIpc>();
|
||||
serviceCollection.AddSingleton<AutomatonIpc>();
|
||||
}
|
||||
|
||||
private static void AddTaskFactories(ServiceCollection serviceCollection)
|
||||
@ -300,8 +300,8 @@ public sealed class QuestionablePlugin : IDalamudPlugin
|
||||
serviceProvider.GetRequiredService<ShopController>();
|
||||
serviceProvider.GetRequiredService<QuestionableIpc>();
|
||||
serviceProvider.GetRequiredService<DalamudInitializer>();
|
||||
serviceProvider.GetRequiredService<AutoSnipeHandler>().Enable();
|
||||
serviceProvider.GetRequiredService<TextAdvanceIpc>();
|
||||
serviceProvider.GetRequiredService<AutomatonIpc>();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
@ -115,18 +115,6 @@ internal sealed class ConfigWindow : LWindow, IPersistableWindowConfig
|
||||
_configuration.General.ConfigureTextAdvance = configureTextAdvance;
|
||||
Save();
|
||||
}
|
||||
|
||||
if (ImGui.CollapsingHeader("Cheats"))
|
||||
{
|
||||
ImGui.TextColored(ImGuiColors.DalamudRed,
|
||||
"This setting will be removed in a future version, and will be\navailable through TextAdvance instead.");
|
||||
bool automaticallyCompleteSnipeTasks = _configuration.General.AutomaticallyCompleteSnipeTasks;
|
||||
if (ImGui.Checkbox("Automatically complete snipe tasks", ref automaticallyCompleteSnipeTasks))
|
||||
{
|
||||
_configuration.General.AutomaticallyCompleteSnipeTasks = automaticallyCompleteSnipeTasks;
|
||||
Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawNotificationsTab()
|
||||
|
@ -10,10 +10,11 @@ using ImGuiNET;
|
||||
using LLib;
|
||||
using LLib.ImGui;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.External;
|
||||
|
||||
namespace Questionable.Windows;
|
||||
|
||||
internal sealed class OneTimeSetupWindow : LWindow, IDisposable
|
||||
internal sealed class OneTimeSetupWindow : LWindow
|
||||
{
|
||||
private static readonly IReadOnlyList<PluginInfo> RequiredPlugins =
|
||||
[
|
||||
@ -22,35 +23,24 @@ internal sealed class OneTimeSetupWindow : LWindow, IDisposable
|
||||
vnavmesh handles the navigation within a zone, moving
|
||||
your character to the next quest-related objective.
|
||||
""",
|
||||
new Uri("https://github.com/awgil/ffxiv_navmesh/")),
|
||||
new Uri("https://github.com/awgil/ffxiv_navmesh/"),
|
||||
new Uri("https://puni.sh/api/repository/veyn")),
|
||||
new("Lifestream",
|
||||
"""
|
||||
Used to travel to aethernet shards in cities.
|
||||
""",
|
||||
new Uri("https://github.com/NightmareXIV/Lifestream")),
|
||||
new Uri("https://github.com/NightmareXIV/Lifestream"),
|
||||
new Uri("https://github.com/NightmareXIV/MyDalamudPlugins/raw/main/pluginmaster.json")),
|
||||
new("TextAdvance",
|
||||
"""
|
||||
Automatically accepts and turns in quests, skips cutscenes
|
||||
and dialogue.
|
||||
""",
|
||||
new Uri("https://github.com/NightmareXIV/TextAdvance")),
|
||||
new Uri("https://github.com/NightmareXIV/TextAdvance"),
|
||||
new Uri("https://github.com/NightmareXIV/MyDalamudPlugins/raw/main/pluginmaster.json")),
|
||||
];
|
||||
|
||||
private static readonly IReadOnlyList<PluginInfo> RecommendedPlugins =
|
||||
[
|
||||
new("Rotation Solver Reborn",
|
||||
"""
|
||||
Automatically handles most combat interactions you encounter
|
||||
during quests, including being interrupted by mobs.
|
||||
""",
|
||||
new Uri("https://github.com/FFXIV-CombatReborn/RotationSolverReborn")),
|
||||
new("NotificationMaster",
|
||||
"""
|
||||
Sends a configurable out-of-game notification if a quest
|
||||
requires manual actions.
|
||||
""",
|
||||
new Uri("https://github.com/NightmareXIV/NotificationMaster")),
|
||||
];
|
||||
private readonly IReadOnlyList<PluginInfo> _recommendedPlugins;
|
||||
|
||||
private readonly Configuration _configuration;
|
||||
private readonly IDalamudPluginInterface _pluginInterface;
|
||||
@ -59,7 +49,7 @@ internal sealed class OneTimeSetupWindow : LWindow, IDisposable
|
||||
private readonly ILogger<OneTimeSetupWindow> _logger;
|
||||
|
||||
public OneTimeSetupWindow(Configuration configuration, IDalamudPluginInterface pluginInterface, UiUtils uiUtils,
|
||||
DalamudReflector dalamudReflector, ILogger<OneTimeSetupWindow> logger)
|
||||
DalamudReflector dalamudReflector, ILogger<OneTimeSetupWindow> logger, AutomatonIpc automatonIpc)
|
||||
: base("Questionable Setup###QuestionableOneTimeSetup",
|
||||
ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoSavedSettings, true)
|
||||
{
|
||||
@ -69,6 +59,33 @@ internal sealed class OneTimeSetupWindow : LWindow, IDisposable
|
||||
_dalamudReflector = dalamudReflector;
|
||||
_logger = logger;
|
||||
|
||||
_recommendedPlugins =
|
||||
[
|
||||
new("Rotation Solver Reborn",
|
||||
"""
|
||||
Automatically handles most combat interactions you encounter
|
||||
during quests, including being interrupted by mobs.
|
||||
""",
|
||||
new Uri("https://github.com/FFXIV-CombatReborn/RotationSolverReborn"),
|
||||
new Uri(
|
||||
"https://raw.githubusercontent.com/FFXIV-CombatReborn/CombatRebornRepo/main/pluginmaster.json")),
|
||||
new PluginInfo("Automaton",
|
||||
"""
|
||||
Automaton is a collection of automation-related tweaks.
|
||||
The 'Sniper no sniping' tweak can complete snipe tasks automatically.
|
||||
""",
|
||||
new Uri("https://github.com/Jaksuhn/Automaton"),
|
||||
new Uri("https://puni.sh/api/repository/croizat"),
|
||||
[new PluginDetailInfo("'Sniper no sniping' enabled", () => automatonIpc.IsAutoSnipeEnabled)]),
|
||||
new("NotificationMaster",
|
||||
"""
|
||||
Sends a configurable out-of-game notification if a quest
|
||||
requires manual actions.
|
||||
""",
|
||||
new Uri("https://github.com/NightmareXIV/NotificationMaster"),
|
||||
null),
|
||||
];
|
||||
|
||||
RespectCloseHotkey = false;
|
||||
ShowCloseButton = false;
|
||||
AllowPinning = false;
|
||||
@ -101,7 +118,7 @@ internal sealed class OneTimeSetupWindow : LWindow, IDisposable
|
||||
ImGui.Text("The following plugins are recommended, but not required:");
|
||||
using (ImRaii.PushIndent())
|
||||
{
|
||||
foreach (var plugin in RecommendedPlugins)
|
||||
foreach (var plugin in _recommendedPlugins)
|
||||
DrawPlugin(plugin, checklistPadding);
|
||||
}
|
||||
|
||||
@ -149,8 +166,28 @@ internal sealed class OneTimeSetupWindow : LWindow, IDisposable
|
||||
using (ImRaii.PushIndent(checklistPadding))
|
||||
{
|
||||
ImGui.TextUnformatted(plugin.Details);
|
||||
if (!isInstalled && ImGui.Button("Open Repository"))
|
||||
Util.OpenLink(plugin.Uri.ToString());
|
||||
if (plugin.DetailsToCheck != null)
|
||||
{
|
||||
foreach (var detail in plugin.DetailsToCheck)
|
||||
_uiUtils.ChecklistItem(detail.DisplayName, isInstalled && detail.Predicate());
|
||||
}
|
||||
|
||||
ImGui.Spacing();
|
||||
|
||||
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Globe, "Open Website"))
|
||||
Util.OpenLink(plugin.WebsiteUri.ToString());
|
||||
|
||||
ImGui.SameLine();
|
||||
if (plugin.DalamudRepositoryUri != null)
|
||||
{
|
||||
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Code, "Open Repository"))
|
||||
Util.OpenLink(plugin.DalamudRepositoryUri.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGuiComponents.HelpMarker("Available on official Dalamud Repository");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,12 +199,12 @@ internal sealed class OneTimeSetupWindow : LWindow, IDisposable
|
||||
return _dalamudReflector.TryGetDalamudPlugin(internalName, out _, suppressErrors: true, ignoreCache: true);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
private sealed record PluginInfo(
|
||||
string DisplayName,
|
||||
string Details,
|
||||
Uri Uri);
|
||||
Uri WebsiteUri,
|
||||
Uri? DalamudRepositoryUri,
|
||||
List<PluginDetailInfo>? DetailsToCheck = null);
|
||||
|
||||
private sealed record PluginDetailInfo(string DisplayName, Func<bool> Predicate);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user