1
0
Fork 0
forked from aly/qstbak
qstbak/Questionable/Questionable/QuestionablePlugin.cs
2026-08-19 13:19:57 +10:00

674 lines
37 KiB
C#

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Dalamud.Interface.Windowing;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using LLib;
using LLib.GameData;
using LLib.Gear;
using LLib.Logging;
using LLib.Notifications;
using LLib.Shop;
using Lumina.Data;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Questionable.Controller;
using Questionable.Controller.CombatModules;
using Questionable.Controller.CustomDelivery;
using Questionable.Controller.GameUi;
using Questionable.Controller.NavigationOverrides;
using Questionable.Controller.Steps;
using Questionable.Controller.Steps.Common;
using Questionable.Controller.Steps.Gathering;
using Questionable.Controller.Steps.Interactions;
using Questionable.Controller.Steps.Movement;
using Questionable.Controller.Steps.Shared;
using Questionable.Controller.Utils;
using Questionable.Data;
using Questionable.External;
using Questionable.FatePaths;
using Questionable.Functions;
using Questionable.GatheringPaths;
using Questionable.Model.Changelog;
using Questionable.Navigation;
using Questionable.Notifications;
using Questionable.QuestPaths;
using Questionable.SeasonalDutyPaths;
using Questionable.Validation;
using Questionable.Validation.Validators;
using Questionable.Windows;
using Questionable.Windows.ConfigComponents;
using Questionable.Windows.JournalComponents;
using Questionable.Windows.QuestComponents;
using Questionable.Windows.Setup;
using Questionable.Windows.Utils;
using SmartNav;
using SmartNav.Data;
namespace Questionable;
[Obfuscation(Feature = "-ctrl flow", Exclude = false, ApplyToMembers = true)]
public sealed class QuestionablePlugin : IAsyncDalamudPlugin, IAsyncDisposable
{
private ServiceProvider? _serviceProvider;
private readonly IDalamudPluginInterface _pluginInterface;
private readonly IClientState _clientState;
private readonly ITargetManager _targetManager;
private readonly IFramework _framework;
private readonly IGameGui _gameGui;
private readonly IDataManager _dataManager;
private readonly ISigScanner _sigScanner;
private readonly IObjectTable _objectTable;
private readonly IPluginLog _pluginLog;
private readonly ICondition _condition;
private readonly IChatGui _chatGui;
private readonly ICommandManager _commandManager;
private readonly IAddonLifecycle _addonLifecycle;
private readonly IKeyState _keyState;
private readonly IContextMenu _contextMenu;
private readonly IToastGui _toastGui;
private readonly IGameInteropProvider _gameInteropProvider;
private readonly IAetheryteList _aetheryteList;
private readonly IGameConfig _gameConfig;
private readonly ITextureProvider _textureProvider;
public QuestionablePlugin(IDalamudPluginInterface pluginInterface, IClientState clientState, ITargetManager targetManager, IFramework framework, IGameGui gameGui, IDataManager dataManager, ISigScanner sigScanner, IObjectTable objectTable, IPluginLog pluginLog, ICondition condition, IChatGui chatGui, ICommandManager commandManager, IAddonLifecycle addonLifecycle, IKeyState keyState, IContextMenu contextMenu, IToastGui toastGui, IGameInteropProvider gameInteropProvider, IAetheryteList aetheryteList, IGameConfig gameConfig, ITextureProvider textureProvider)
{
ArgumentNullException.ThrowIfNull(pluginInterface, "pluginInterface");
ArgumentNullException.ThrowIfNull(chatGui, "chatGui");
_pluginInterface = pluginInterface;
_clientState = clientState;
_targetManager = targetManager;
_framework = framework;
_gameGui = gameGui;
_dataManager = dataManager;
_sigScanner = sigScanner;
_objectTable = objectTable;
_pluginLog = pluginLog;
_condition = condition;
_chatGui = chatGui;
_commandManager = commandManager;
_addonLifecycle = addonLifecycle;
_keyState = keyState;
_contextMenu = contextMenu;
_toastGui = toastGui;
_gameInteropProvider = gameInteropProvider;
_aetheryteList = aetheryteList;
_gameConfig = gameConfig;
_textureProvider = textureProvider;
}
public async Task LoadAsync(CancellationToken cancellationToken)
{
try
{
Stopwatch totalStopwatch = Stopwatch.StartNew();
Task.Run(delegate
{
try
{
AssemblyQuestLoader.GetQuests();
AssemblyGatheringLocationLoader.GetLocations();
AssemblyFateDefinitionLoader.GetDefinitions();
AssemblySeasonalDutyDefinitionLoader.GetDefinitions();
}
catch (Exception)
{
}
}, cancellationToken);
ServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddLogging(delegate(ILoggingBuilder builder)
{
builder.SetMinimumLevel(LogLevel.Trace).ClearProviders().AddProvider(new DalamudLoggerProvider(_pluginLog, (string t) => t?.Substring(t.LastIndexOf('.') + 1)));
});
serviceCollection.AddSingleton(_pluginInterface);
serviceCollection.AddSingleton(_clientState);
serviceCollection.AddSingleton(_targetManager);
serviceCollection.AddSingleton(_framework);
serviceCollection.AddSingleton(_gameGui);
serviceCollection.AddSingleton(_dataManager);
serviceCollection.AddSingleton(_sigScanner);
serviceCollection.AddSingleton(_objectTable);
serviceCollection.AddSingleton(_pluginLog);
serviceCollection.AddSingleton(_condition);
serviceCollection.AddSingleton(_chatGui);
serviceCollection.AddSingleton(_commandManager);
serviceCollection.AddSingleton(_addonLifecycle);
serviceCollection.AddSingleton(_keyState);
serviceCollection.AddSingleton(_contextMenu);
serviceCollection.AddSingleton(_toastGui);
serviceCollection.AddSingleton(_gameInteropProvider);
serviceCollection.AddSingleton(_aetheryteList);
serviceCollection.AddSingleton(_gameConfig);
serviceCollection.AddSingleton(_textureProvider);
serviceCollection.AddSingleton(new WindowSystem("Questionable"));
Configuration configuration = ((Configuration)_pluginInterface.GetPluginConfig()) ?? new Configuration();
bool flag = configuration.Version != 3;
if (flag)
{
BackupConfig(configuration.Version);
configuration.Version = 3;
}
if (ConfigMigration.Run(configuration) || flag)
{
_pluginInterface.SavePluginConfig(configuration);
}
serviceCollection.AddSingleton(configuration);
MigrateLegacyConfigDirectoryFiles();
AddBasicFunctionsAndData(serviceCollection);
AddTaskFactories(serviceCollection);
AddControllers(serviceCollection);
AddWindows(serviceCollection);
AddQuestValidators(serviceCollection);
serviceCollection.AddSingleton<CommandHandler>();
serviceCollection.AddSingleton<DalamudInitializer>();
Stopwatch providerStopwatch = Stopwatch.StartNew();
_serviceProvider = serviceCollection.BuildServiceProvider();
providerStopwatch.Stop();
await Task.Run(delegate
{
Initialize(_serviceProvider);
}, cancellationToken);
_serviceProvider.GetRequiredService<ILogger<QuestionablePlugin>>().LogDebug("Load complete in {Total}ms (provider build {Provider}ms); bundle decode off critical path: quest {Quest}ms, gathering {Gathering}ms, fate {Fate}ms, seasonal {Seasonal}ms", totalStopwatch.ElapsedMilliseconds, providerStopwatch.ElapsedMilliseconds, DecodeMs(() => AssemblyQuestLoader.DecodeDuration), DecodeMs(() => AssemblyGatheringLocationLoader.DecodeDuration), DecodeMs(() => AssemblyFateDefinitionLoader.DecodeDuration), DecodeMs(() => AssemblySeasonalDutyDefinitionLoader.DecodeDuration));
}
catch (Exception)
{
_chatGui.PrintError("Unable to load plugin, check /xllog for details", "Questionable");
throw;
}
}
private void BackupConfig(int oldVersion)
{
try
{
if (_pluginInterface.ConfigFile.Exists)
{
_pluginInterface.ConfigFile.CopyTo($"{_pluginInterface.ConfigFile.FullName}.v{oldVersion}.bak", overwrite: true);
}
}
catch (Exception exception)
{
_pluginLog.Warning(exception, "Unable to back up configuration file");
}
}
private void MigrateLegacyConfigDirectoryFiles()
{
string[] obj = new string[5] { "npc-position-cache.bin", "zone-boundary-cache.bin", "lgb-worker-manifest.json", "npc-position-cache.bin.tmp", "zone-boundary-cache.bin.tmp" };
bool flag = false;
string[] array = obj;
foreach (string path in array)
{
try
{
FileInfo fileInfo = new FileInfo(Path.Combine(_pluginInterface.ConfigDirectory.FullName, path));
if (fileInfo.Exists)
{
fileInfo.Delete();
flag = true;
}
}
catch (Exception)
{
}
}
if (flag)
{
_pluginLog.Debug("Deleted legacy LGB worker cache files from the config directory");
}
string text = Path.Combine(_pluginInterface.ConfigDirectory.FullName, "nav-overrides");
array = new string[2] { "warp-destinations.json", "teleport-tickets.json" };
foreach (string path2 in array)
{
try
{
FileInfo fileInfo2 = new FileInfo(Path.Combine(_pluginInterface.ConfigDirectory.FullName, path2));
if (fileInfo2.Exists)
{
string text2 = Path.Combine(text, path2);
if (File.Exists(text2))
{
_pluginLog.Warning($"Not moving legacy override file {fileInfo2.FullName}: {text2} already exists");
}
else
{
string fullName = fileInfo2.FullName;
Directory.CreateDirectory(text);
fileInfo2.MoveTo(text2);
_pluginLog.Debug("Moved legacy override file " + fullName + " to " + text2);
}
}
}
catch (Exception)
{
}
}
}
private static void AddBasicFunctionsAndData(ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<AetheryteFunctions>();
serviceCollection.AddSingleton<AethernetTeleportService>();
serviceCollection.AddSingleton<ExcelFunctions>();
serviceCollection.AddSingleton<GameStateHelper>();
serviceCollection.AddSingleton<PublicEventHelper>();
serviceCollection.AddSingleton<GameFunctions>();
serviceCollection.AddSingleton<ChatFunctions>();
serviceCollection.AddSingleton<QuestFunctions>();
serviceCollection.AddSingleton<AlliedSocietyQuestFunctions>();
serviceCollection.AddSingleton<DalamudReflector>();
serviceCollection.AddSingleton<PluginInstaller>();
serviceCollection.AddSingleton<Mount.MountEvaluator>();
serviceCollection.AddSingleton<AetherCurrentData>();
serviceCollection.AddSingleton<AetheryteData>();
serviceCollection.AddSingleton<AlliedSocietyData>();
serviceCollection.AddSingleton<DutyUnlockData>();
serviceCollection.AddSingleton<FishingData>();
serviceCollection.AddSingleton<GatheringData>();
serviceCollection.AddSingleton<JournalData>();
serviceCollection.AddSingleton<MenderDataService>();
serviceCollection.AddSingleton<GearRepairService>();
serviceCollection.AddSingleton<QuestData>();
serviceCollection.AddSingleton<QuestChainBuilder>();
serviceCollection.AddSingleton<TerritoryData>();
serviceCollection.AddSingleton<NavmeshIpc>();
serviceCollection.AddSingleton<WigglyNavIpc>();
serviceCollection.AddSingleton<WigglyNavAvailability>();
serviceCollection.AddSingleton<ArtisanIpc>();
serviceCollection.AddSingleton<AutoHookIpc>();
serviceCollection.AddSingleton<QuestionableIpc>();
serviceCollection.AddSingleton<TextAdvanceIpc>();
serviceCollection.AddSingleton<AutoDutyIpc>();
serviceCollection.AddSingleton<BossModIpc>();
serviceCollection.AddSingleton<PandorasBoxIpc>();
serviceCollection.AddSingleton<AutomatonIpc>();
serviceCollection.AddSingleton<OutOfGameNotifier>();
serviceCollection.AddSingleton<NotificationService>();
serviceCollection.AddSingleton<GearStatsCalculator>();
serviceCollection.AddSingleton<BestItemFinder>();
serviceCollection.AddSingleton(delegate(IServiceProvider sp)
{
IDalamudPluginInterface requiredService = sp.GetRequiredService<IDalamudPluginInterface>();
DirectoryInfo devSourceDirectory = null;
sp.GetRequiredService<IDataManager>().GameData.Repositories.TryGetValue("ffxiv", out Repository value);
return new SmartNavDataOptions(new DirectoryInfo(Path.Combine(requiredService.ConfigDirectory.FullName, "nav-overrides")), devSourceDirectory, value?.Version);
});
serviceCollection.AddSingleton<WarpDataService>();
serviceCollection.AddSingleton<TaxiStandDataService>();
serviceCollection.AddSingleton<ZoneSubRegionService>();
serviceCollection.AddSingleton<TeleportTicketService>();
serviceCollection.AddSingleton((IServiceProvider sp) => new LgbZoneBoundarySource(sp.GetRequiredService<ILogger<LgbZoneBoundarySource>>(), sp.GetRequiredService<SmartNavDataOptions>()));
((IServiceCollection)serviceCollection).AddSingleton((Func<IServiceProvider, IZoneBoundarySource>)((IServiceProvider sp) => sp.GetRequiredService<LgbZoneBoundarySource>()));
((IServiceCollection)serviceCollection).AddSingleton((Func<IServiceProvider, ITerritoryInfo>)((IServiceProvider sp) => sp.GetRequiredService<TerritoryData>()));
serviceCollection.AddSingleton<IPlayerContext, QuestionablePlayerContext>();
serviceCollection.AddSingleton<CostCalculator>();
serviceCollection.AddSingleton<NavGraphBuilder>();
serviceCollection.AddSingleton<NavGraphView>();
serviceCollection.AddSingleton<NavRouter>();
serviceCollection.AddSingleton<PlayerNavStateBuilder>();
serviceCollection.AddSingleton<RouteInstructionBuilder>();
serviceCollection.AddSingleton<ReRoutePolicy>();
serviceCollection.AddSingleton<SmartNavTaskMapper>();
serviceCollection.AddSingleton<WarpRecordingService>();
serviceCollection.AddSingleton<SmartNavReRouteService>();
serviceCollection.AddSingleton<SmartNavRouteEnqueuer>();
serviceCollection.AddSingleton<WarpFailureTracker>();
}
private static void AddTaskFactories(ServiceCollection serviceCollection)
{
serviceCollection.AddTaskFactory<QuestCleanUp.CheckAlliedSocietyMount>();
serviceCollection.AddTaskFactoryAndExecutor<QuestCleanUp.CloseGatheringAddonTask, QuestCleanUp.CloseGatheringAddonFactory, QuestCleanUp.DoCloseAddon>();
serviceCollection.AddTaskExecutor<MoveToLandingLocation.Task, MoveToLandingLocation.MoveToLandingLocationExecutor>();
serviceCollection.AddTaskFactoryAndExecutor<RedeemRewardItems.Task, RedeemRewardItems.Factory, RedeemRewardItems.Executor>();
serviceCollection.AddTaskExecutor<DoGather.Task, DoGather.GatherExecutor>();
serviceCollection.AddTaskExecutor<DoGatherCollectable.Task, DoGatherCollectable.GatherCollectableExecutor>();
serviceCollection.AddTaskFactoryAndExecutor<SwitchClassJob.Task, SwitchClassJob.Factory, SwitchClassJob.SwitchClassJobExecutor>();
serviceCollection.AddTaskExecutor<Mount.MountTask, Mount.MountExecutor>();
serviceCollection.AddTaskExecutor<Mount.UnmountTask, Mount.UnmountExecutor>();
serviceCollection.AddTaskExecutor<RepairGear.SelfRepairTask, RepairGear.SelfRepairExecutor>();
serviceCollection.AddTaskExecutor<RepairGear.MenderRepairTask, RepairGear.MenderRepairExecutor>();
serviceCollection.AddTaskExecutor<SatisfactionSupplyTurnInTask, SatisfactionSupplyTurnInExecutor>();
serviceCollection.AddTaskExecutor<DeliveryNpcApproachTask, DeliveryNpcApproachExecutor>();
serviceCollection.AddTaskExecutor<VendorPurchaseTask, VendorPurchaseExecutor>();
serviceCollection.AddTaskFactoryAndExecutor<StepDisabled.SkipRemainingTasks, StepDisabled.Factory, StepDisabled.SkipDisabledStepsExecutor>();
serviceCollection.AddTaskFactoryAndExecutor<SkipCondition.SkipTask, SkipCondition.Factory, SkipCondition.CheckSkip>();
serviceCollection.AddTaskExecutor<SkipMissingObject.Task, SkipMissingObject.Executor>();
serviceCollection.AddTaskFactory<EquipRecommended.BeforeDutyOrInstance>();
serviceCollection.AddTaskExecutor<Gather.SkipMarker, Gather.DoSkip>();
serviceCollection.AddTaskFactory<SmartNavStep.Factory>();
serviceCollection.AddTaskExecutor<WarpInteract.Task, WarpInteract.DoWarpInteract>();
serviceCollection.AddTaskExecutor<TaxiInteract.Task, TaxiInteract.DoTaxiInteract>();
serviceCollection.AddTaskExecutor<SubRegionTransport.Task, SubRegionTransport.DoSubRegionTransport>();
serviceCollection.AddTaskExecutor<TicketTeleport.Task, TicketTeleport.UseTicketExecutor>();
serviceCollection.AddTaskExecutor<AetheryteTeleport.Task, AetheryteTeleport.AetheryteTeleportExecutor>();
serviceCollection.AddTaskExecutor<AetheryteTeleport.MoveAwayFromAetheryte, AetheryteTeleport.MoveAwayFromAetheryteExecutor>();
serviceCollection.AddTaskFactoryAndExecutor<Gather.GatheringTask, Gather.Factory, Gather.StartGathering>();
serviceCollection.AddTaskExecutor<Gather.DelayedGatheringTask, Gather.DelayedGatheringExecutor>();
serviceCollection.AddTaskExecutor<AethernetRide.Task, AethernetRide.AethernetRideExecutor>();
serviceCollection.AddTaskFactoryAndExecutor<WaitAtStart.WaitDelay, WaitAtStart.Factory, WaitAtStart.WaitDelayExecutor>();
serviceCollection.AddTaskFactoryAndExecutor<MoveTask, MoveTo.Factory, MoveExecutor>();
serviceCollection.AddTaskExecutor<WaitForNearDataId, WaitForNearDataIdExecutor>();
serviceCollection.AddTaskExecutor<MoveToObject, MoveToObjectExecutor>();
serviceCollection.AddTaskExecutor<LandTask, LandExecutor>();
serviceCollection.AddTaskFactoryAndExecutor<SendNotification.Task, SendNotification.Factory, SendNotification.Executor>();
serviceCollection.AddTaskFactoryAndExecutor<NextQuest.SetQuestTask, NextQuest.Factory, NextQuest.NextQuestExecutor>();
serviceCollection.AddTaskFactoryAndExecutor<AetherCurrent.Attune, AetherCurrent.Factory, AetherCurrent.DoAttune>();
serviceCollection.AddTaskFactoryAndExecutor<AethernetShard.Attune, AethernetShard.Factory, AethernetShard.DoAttune>();
serviceCollection.AddTaskFactoryAndExecutor<Aetheryte.Attune, Aetheryte.Factory, Aetheryte.DoAttune>();
serviceCollection.AddTaskFactoryAndExecutor<AetheryteFreeOrFavored.Register, AetheryteFreeOrFavored.Factory, AetheryteFreeOrFavored.DoRegister>();
serviceCollection.AddTaskFactoryAndExecutor<Combat.Task, Combat.Factory, Combat.HandleCombat>();
serviceCollection.AddTaskFactoryAndExecutor<Duty.OpenDutyFinderTask, Duty.Factory, Duty.OpenDutyFinderExecutor>();
serviceCollection.AddTaskExecutor<Duty.WaitForPartyTask, Duty.WaitForPartyExecutor>();
serviceCollection.AddTaskExecutor<Duty.EnableBossModForDutyTask, Duty.EnableBossModForDutyExecutor>();
serviceCollection.AddTaskExecutor<Duty.EnableBossModPassiveForDutyTask, Duty.EnableBossModPassiveForDutyExecutor>();
serviceCollection.AddTaskExecutor<Duty.EnableRsrForDutyTask, Duty.EnableRsrForDutyExecutor>();
serviceCollection.AddTaskExecutor<Duty.EnableWrathForDutyTask, Duty.EnableWrathForDutyExecutor>();
serviceCollection.AddTaskExecutor<Duty.StartAutoDutyTask, Duty.StartAutoDutyExecutor>();
serviceCollection.AddTaskExecutor<Duty.WaitAutoDutyTask, Duty.WaitAutoDutyExecutor>();
serviceCollection.AddTaskExecutor<Duty.DisableCombatPluginsForDutyTask, Duty.DisableCombatPluginsForDutyExecutor>();
serviceCollection.AddTaskExecutor<Duty.StartLevelingModeTask, Duty.StartLevelingModeExecutor>();
serviceCollection.AddTaskExecutor<Duty.WaitLevelingModeTask, Duty.WaitLevelingModeExecutor>();
serviceCollection.AddTaskFactory<Emote.Factory>();
serviceCollection.AddTaskExecutor<Emote.UseOnObject, Emote.UseOnObjectExecutor>();
serviceCollection.AddTaskExecutor<Emote.UseOnSelf, Emote.UseOnSelfExecutor>();
serviceCollection.AddTaskFactoryAndExecutor<ClearObjectsWithAction.ClearTask, ClearObjectsWithAction.Factory, ClearObjectsWithAction.ClearTaskExecutor>();
serviceCollection.AddTaskFactoryAndExecutor<Questionable.Controller.Steps.Interactions.Action.UseOnObject, Questionable.Controller.Steps.Interactions.Action.Factory, Questionable.Controller.Steps.Interactions.Action.UseOnObjectExecutor>();
serviceCollection.AddTaskExecutor<Questionable.Controller.Steps.Interactions.Action.UseMudraOnObject, Questionable.Controller.Steps.Interactions.Action.UseMudraOnObjectExecutor>();
serviceCollection.AddTaskExecutor<Questionable.Controller.Steps.Interactions.Action.TriggerStatusIfMissing, Questionable.Controller.Steps.Interactions.Action.TriggerStatusIfMissingExecutor>();
serviceCollection.AddTaskFactoryAndExecutor<FateAction.UseOnTargets, FateAction.Factory, FateAction.UseOnTargetsExecutor>();
serviceCollection.AddTaskExecutor<FateFarming.WaitForFateTargets, FateFarming.WaitForFateTargetsExecutor>();
serviceCollection.AddTaskExecutor<FateFarming.SyncFateLevel, FateFarming.SyncFateLevelExecutor>();
serviceCollection.AddTaskExecutor<FateFarming.FateActionLoop, FateFarming.FateActionLoopExecutor>();
serviceCollection.AddTaskFactoryAndExecutor<CriticalEncounter.WaitForCriticalEncounter, CriticalEncounter.Factory, CriticalEncounter.WaitForCriticalEncounterExecutor>();
serviceCollection.AddTaskFactoryAndExecutor<StatusOff.Task, StatusOff.Factory, StatusOff.DoStatusOff>();
serviceCollection.AddTaskFactoryAndExecutor<Interact.Task, Interact.Factory, Interact.DoInteract>();
serviceCollection.AddTaskFactory<AutoVendorPurchase.Factory>();
serviceCollection.AddTaskFactory<Jump.Factory>();
serviceCollection.AddTaskExecutor<Jump.SingleJumpTask, Jump.DoSingleJump>();
serviceCollection.AddTaskExecutor<Jump.RepeatedJumpTask, Jump.DoRepeatedJumps>();
serviceCollection.AddTaskFactoryAndExecutor<Dive.Task, Dive.Factory, Dive.DoDive>();
serviceCollection.AddTaskFactoryAndExecutor<Say.Task, Say.Factory, Say.UseChat>();
serviceCollection.AddTaskFactory<UseItem.Factory>();
serviceCollection.AddTaskExecutor<UseItem.UseOnGround, UseItem.UseOnGroundExecutor>();
serviceCollection.AddTaskExecutor<UseItem.UseOnPosition, UseItem.UseOnPositionExecutor>();
serviceCollection.AddTaskExecutor<UseItem.UseOnObject, UseItem.UseOnObjectExecutor>();
serviceCollection.AddTaskExecutor<UseItem.UseOnSelf, UseItem.UseOnSelfExecutor>();
serviceCollection.AddTaskFactoryAndExecutor<EquipItem.Task, EquipItem.Factory, EquipItem.DoEquip>();
serviceCollection.AddTaskFactoryAndExecutor<UnequipItem.Task, UnequipItem.Factory, UnequipItem.DoUnequip>();
serviceCollection.AddTaskFactoryAndExecutor<EquipRecommended.EquipTask, EquipRecommended.Factory, EquipRecommended.DoEquipRecommended>();
serviceCollection.AddTaskFactoryAndExecutor<Craft.CraftTask, Craft.Factory, Craft.DoCraft>();
serviceCollection.AddTaskFactoryAndExecutor<Fish.FishTask, Fish.Factory, Fish.DoFish>();
serviceCollection.AddTaskFactoryAndExecutor<MeldMateria.MeldTask, MeldMateria.Factory, MeldMateria.DoMeld>();
serviceCollection.AddSingleton<DutyRetryState>();
serviceCollection.AddTaskFactory<SinglePlayerDuty.Factory>();
serviceCollection.AddTaskExecutor<SinglePlayerDuty.StartSinglePlayerDuty, SinglePlayerDuty.StartSinglePlayerDutyExecutor>();
serviceCollection.AddTaskExecutor<SinglePlayerDuty.EnableAi, SinglePlayerDuty.EnableAiExecutor>();
serviceCollection.AddTaskExecutor<SinglePlayerDuty.WaitSinglePlayerDuty, SinglePlayerDuty.WaitSinglePlayerDutyExecutor>();
serviceCollection.AddTaskExecutor<SinglePlayerDuty.DisableAi, SinglePlayerDuty.DisableAiExecutor>();
serviceCollection.AddTaskExecutor<SinglePlayerDuty.SetTarget, SinglePlayerDuty.SetTargetExecutor>();
serviceCollection.AddTaskExecutor<SinglePlayerDuty.CheckDutyOutcome, SinglePlayerDuty.CheckDutyOutcomeExecutor>();
serviceCollection.AddTaskExecutor<WaitCondition.Task, WaitCondition.WaitConditionExecutor>();
serviceCollection.AddTaskExecutor<WaitNavmesh.Task, WaitNavmesh.Executor>();
serviceCollection.AddTaskFactoryAndExecutor<RedeemRewardItems.ScanAfterQuestCompletion, RedeemRewardItems.CompletionFactory, RedeemRewardItems.ScanAfterQuestCompletionExecutor>();
serviceCollection.AddTaskFactory<WaitAtEnd.Factory>();
serviceCollection.AddTaskExecutor<WaitAtEnd.WaitDelay, WaitAtEnd.WaitDelayExecutor>();
serviceCollection.AddTaskExecutor<WaitAtEnd.WaitNextStepOrSequence, WaitAtEnd.WaitNextStepOrSequenceExecutor>();
serviceCollection.AddTaskExecutor<WaitAtEnd.WaitManualDuty, WaitAtEnd.WaitManualDutyExecutor>();
serviceCollection.AddTaskExecutor<WaitAtEnd.WaitForCompletionFlags, WaitAtEnd.WaitForCompletionFlagsExecutor>();
serviceCollection.AddTaskExecutor<WaitAtEnd.WaitObjectAtPosition, WaitAtEnd.WaitObjectAtPositionExecutor>();
serviceCollection.AddTaskExecutor<WaitAtEnd.WaitQuestAccepted, WaitAtEnd.WaitQuestAcceptedExecutor>();
serviceCollection.AddTaskExecutor<WaitAtEnd.WaitQuestCompleted, WaitAtEnd.WaitQuestCompletedExecutor>();
serviceCollection.AddTaskExecutor<WaitAtEnd.NextStep, WaitAtEnd.NextStepExecutor>();
serviceCollection.AddTaskExecutor<WaitAtEnd.EndAutomation, WaitAtEnd.EndAutomationExecutor>();
serviceCollection.AddSingleton<TaskCreator>();
serviceCollection.AddSingleton<ExtraConditionUtils>();
serviceCollection.AddSingleton<ClassJobUtils>();
}
private static void AddControllers(ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<MovementController>();
serviceCollection.AddSingleton<MovementOverrideController>();
serviceCollection.AddSingleton<FateDefinitionRegistry>();
serviceCollection.AddSingleton<GatheringPointRegistry>();
serviceCollection.AddSingleton<QuestRegistry>();
serviceCollection.AddSingleton<QuestPriorityResolver>();
serviceCollection.AddSingleton<QuestController>();
serviceCollection.AddSingleton<CombatController>();
serviceCollection.AddSingleton<GatheringController>();
serviceCollection.AddSingleton<SatisfactionSupplyHelper>();
serviceCollection.AddSingleton(delegate(IServiceProvider sp)
{
sp.GetRequiredService<IDataManager>().GameData.Repositories.TryGetValue("ffxiv", out Repository value);
return new NpcPositionCacheOptions
{
GameVersion = value?.Version
};
});
serviceCollection.AddSingleton<NpcPositionCache>();
serviceCollection.AddSingleton<VendorResolver>();
serviceCollection.AddSingleton<VendorResolverService>();
serviceCollection.AddSingleton<DeliveryPlannerService>();
serviceCollection.AddSingleton<DeliveryRewardCalculator>();
serviceCollection.AddSingleton<CustomDeliveryNpcData>();
serviceCollection.AddSingleton<CustomDeliveryController>();
serviceCollection.AddSingleton<FishingController>();
serviceCollection.AddSingleton<FateController>();
serviceCollection.AddSingleton<SeasonalDutyDefinitionRegistry>();
serviceCollection.AddSingleton<SeasonalDutyController>();
serviceCollection.AddSingleton<AttunementController>();
serviceCollection.AddSingleton<ContextMenuController>();
serviceCollection.AddSingleton<ShopController>();
serviceCollection.AddSingleton<InterruptHandler>();
serviceCollection.AddSingleton<PartyWatchdog>();
serviceCollection.AddSingleton<AutoSnipeHandler>();
serviceCollection.AddSingleton<CraftworksSupplyController>();
serviceCollection.AddSingleton<CreditsController>();
serviceCollection.AddSingleton<HelpUiController>();
serviceCollection.AddSingleton<InteractionUiController>();
serviceCollection.AddSingleton<QteController>();
serviceCollection.AddSingleton<GrandCompanyShop>();
serviceCollection.AddSingleton<GCShopHandler>();
serviceCollection.AddSingleton<ChocoboNameHandler>();
serviceCollection.AddSingleton<WrathComboModule>();
serviceCollection.AddSingleton<ICombatModule, Mount128Module>();
serviceCollection.AddSingleton<ICombatModule, Mount147Module>();
serviceCollection.AddSingleton<ICombatModule, ItemUseModule>();
((IServiceCollection)serviceCollection).AddSingleton((Func<IServiceProvider, ICombatModule>)((IServiceProvider sp) => sp.GetRequiredService<WrathComboModule>()));
serviceCollection.AddSingleton<ICombatModule, BossModModule>();
serviceCollection.AddSingleton<RotationSolverRebornModule>();
((IServiceCollection)serviceCollection).AddSingleton((Func<IServiceProvider, ICombatModule>)((IServiceProvider sp) => sp.GetRequiredService<RotationSolverRebornModule>()));
}
private static void AddWindows(ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<UiUtils>();
serviceCollection.AddTransient<QuestSelector>();
serviceCollection.AddSingleton<ActiveQuestComponent>();
serviceCollection.AddSingleton<ARealmRebornComponent>();
serviceCollection.AddSingleton<CreationUtilsComponent>();
serviceCollection.AddSingleton<EventInfoComponent>();
serviceCollection.AddSingleton<ManualPriorityComponent>();
serviceCollection.AddSingleton<SavedPresetsComponent>();
serviceCollection.AddSingleton<QuestTooltipComponent>();
serviceCollection.AddSingleton<NavigationBarComponent>();
serviceCollection.AddSingleton<QuickAccessButtonsComponent>();
serviceCollection.AddSingleton<QuestValidationComponent>();
serviceCollection.AddSingleton<RemainingTasksComponent>();
serviceCollection.AddSingleton<QuestJournalUtils>();
serviceCollection.AddSingleton<QuestJournalComponent>();
serviceCollection.AddSingleton<QuestRewardComponent>();
serviceCollection.AddSingleton<GatheringJournalComponent>();
serviceCollection.AddSingleton<AlliedSocietyJournalComponent>();
serviceCollection.AddSingleton<CustomDeliveryJournalComponent>();
serviceCollection.AddSingleton<DutyJournalComponent>();
serviceCollection.AddSingleton<QuestMapComponent>();
serviceCollection.AddSingleton<QuestChainComponent>();
serviceCollection.AddSingleton<AttunementJournalComponent>();
serviceCollection.AddSingleton<WelcomeStep>();
serviceCollection.AddSingleton<PluginsStep>();
serviceCollection.AddSingleton<EssentialSettingsStep>();
serviceCollection.AddSingleton<ReadyStep>();
serviceCollection.AddSingleton<OneTimeSetupWindow>();
serviceCollection.AddSingleton<QuestWindow>();
serviceCollection.AddSingleton<ConfigWindow>();
serviceCollection.AddSingleton<QuestSelectionWindow>();
serviceCollection.AddSingleton<QuestSequenceWindow>();
serviceCollection.AddSingleton<QuestValidationWindow>();
serviceCollection.AddSingleton<JournalProgressWindow>();
serviceCollection.AddSingleton<FateSelectionWindow>();
serviceCollection.AddSingleton<SeasonalDutySelectionWindow>();
serviceCollection.AddSingleton<GeneralConfigComponent>();
serviceCollection.AddSingleton<QuestsConfigComponent>();
serviceCollection.AddSingleton<PluginConfigComponent>();
serviceCollection.AddSingleton<DutyConfigComponent>();
serviceCollection.AddSingleton<SinglePlayerDutyConfigComponent>();
serviceCollection.AddSingleton<StopConditionComponent>();
serviceCollection.AddSingleton<BlacklistConfigComponent>();
serviceCollection.AddSingleton<NavigationConfigComponent>();
serviceCollection.AddSingleton<NotificationConfigComponent>();
serviceCollection.AddSingleton<DebugConfigComponent>();
serviceCollection.AddSingleton<ChangelogWindow>();
serviceCollection.AddSingleton<GameSequenceChainComponent>();
serviceCollection.AddSingleton<QuestSequenceComponent>();
}
private static void AddQuestValidators(ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<SchemaRegistrar>();
serviceCollection.AddSingleton<QuestValidator>();
serviceCollection.AddSingleton<IQuestValidator, QuestDisabledValidator>();
serviceCollection.AddSingleton<IQuestValidator, BasicSequenceValidator>();
serviceCollection.AddSingleton<IQuestValidator, GameSequenceCoverageValidator>();
serviceCollection.AddSingleton<IQuestValidator, UniqueStartStopValidator>();
serviceCollection.AddSingleton<IQuestValidator, NextQuestValidator>();
serviceCollection.AddSingleton<IQuestValidator, CompletionFlagsValidator>();
serviceCollection.AddSingleton<IQuestValidator, DialogueChoiceValidator>();
serviceCollection.AddSingleton<IQuestValidator, SinglePlayerInstanceValidator>();
serviceCollection.AddSingleton<IQuestValidator, UniqueSinglePlayerInstanceValidator>();
serviceCollection.AddSingleton<IQuestValidator, SayValidator>();
serviceCollection.AddSingleton<IQuestValidator, LandingZoneValidator>();
serviceCollection.AddSingleton<JsonSchemaValidator>();
((IServiceCollection)serviceCollection).AddSingleton((Func<IServiceProvider, IQuestValidator>)((IServiceProvider sp) => sp.GetRequiredService<JsonSchemaValidator>()));
serviceCollection.AddSingleton<FateSchemaValidator>();
serviceCollection.AddSingleton<GatheringSchemaValidator>();
serviceCollection.AddSingleton<SeasonalDutySchemaValidator>();
}
private static long DecodeMs(Func<TimeSpan?> duration)
{
return (long)duration().GetValueOrDefault().TotalMilliseconds;
}
private static void Initialize(IServiceProvider serviceProvider)
{
ILogger<QuestionablePlugin> requiredService = serviceProvider.GetRequiredService<ILogger<QuestionablePlugin>>();
Stopwatch stopwatch = Stopwatch.StartNew();
try
{
Stopwatch stopwatch2 = Stopwatch.StartNew();
bool flag;
using (Stream stream = AssemblyLgbCacheLoader.OpenNpcPositionCache())
{
flag = serviceProvider.GetRequiredService<NpcPositionCache>().TryLoadFromStream(stream, acceptStaleVersion: true);
}
if (flag)
{
requiredService.LogInformation("NPC position cache hydrated in {Duration}ms", (long)stopwatch2.Elapsed.TotalMilliseconds);
}
else
{
requiredService.LogError("Embedded NPC position cache was rejected (bad magic, version or truncated) - derived warp sources, mender and vendor resolution are unavailable this session");
}
}
catch (Exception exception)
{
requiredService.LogError(exception, "Unable to hydrate the embedded NPC position cache");
}
InlineArray12<Task> buffer = default(InlineArray12<Task>);
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray12<Task>, Task>(ref buffer, 0) = Task.Run(() => serviceProvider.GetRequiredService<QuestData>());
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray12<Task>, Task>(ref buffer, 1) = Task.Run(() => serviceProvider.GetRequiredService<TerritoryData>());
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray12<Task>, Task>(ref buffer, 2) = Task.Run(() => serviceProvider.GetRequiredService<GatheringData>());
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray12<Task>, Task>(ref buffer, 3) = Task.Run(() => serviceProvider.GetRequiredService<AetheryteData>());
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray12<Task>, Task>(ref buffer, 4) = Task.Run(() => serviceProvider.GetRequiredService<AetherCurrentData>());
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray12<Task>, Task>(ref buffer, 5) = Task.Run(() => serviceProvider.GetRequiredService<DutyUnlockData>());
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray12<Task>, Task>(ref buffer, 6) = Task.Run(() => serviceProvider.GetRequiredService<FishingData>());
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray12<Task>, Task>(ref buffer, 7) = Task.Run(() => serviceProvider.GetRequiredService<AlliedSocietyData>());
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray12<Task>, Task>(ref buffer, 8) = Task.Run(() => serviceProvider.GetRequiredService<WarpDataService>());
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray12<Task>, Task>(ref buffer, 9) = Task.Run(() => serviceProvider.GetRequiredService<TaxiStandDataService>());
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray12<Task>, Task>(ref buffer, 10) = Task.Run(() => serviceProvider.GetRequiredService<ZoneSubRegionService>());
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray12<Task>, Task>(ref buffer, 11) = Task.Run(() => serviceProvider.GetRequiredService<GameStateHelper>());
Task.WaitAll(global::_003CPrivateImplementationDetails_003E.InlineArrayAsReadOnlySpan<InlineArray12<Task>, Task>(in buffer, 12));
TimeSpan elapsed = stopwatch.Elapsed;
stopwatch.Restart();
serviceProvider.GetRequiredService<QuestRegistry>().Reload();
TimeSpan elapsed2 = stopwatch.Elapsed;
stopwatch.Restart();
serviceProvider.GetRequiredService<GatheringPointRegistry>().Reload();
TimeSpan elapsed3 = stopwatch.Elapsed;
stopwatch.Restart();
serviceProvider.GetRequiredService<QuestController>().LoadPriorityQuests();
serviceProvider.GetRequiredService<CommandHandler>();
serviceProvider.GetRequiredService<ContextMenuController>();
serviceProvider.GetRequiredService<AutoSnipeHandler>();
serviceProvider.GetRequiredService<CraftworksSupplyController>();
serviceProvider.GetRequiredService<CreditsController>();
serviceProvider.GetRequiredService<HelpUiController>();
serviceProvider.GetRequiredService<QteController>();
serviceProvider.GetRequiredService<PandorasBoxIpc>();
serviceProvider.GetRequiredService<AutomatonIpc>();
serviceProvider.GetRequiredService<ShopController>();
serviceProvider.GetRequiredService<QuestionableIpc>();
serviceProvider.GetRequiredService<GCShopHandler>();
serviceProvider.GetRequiredService<ChocoboNameHandler>();
serviceProvider.GetRequiredService<DalamudInitializer>();
serviceProvider.GetRequiredService<TextAdvanceIpc>();
ChangelogWindow requiredService2 = serviceProvider.GetRequiredService<ChangelogWindow>();
Configuration requiredService3 = serviceProvider.GetRequiredService<Configuration>();
if (requiredService3.IsPluginSetupComplete() && requiredService3.General.ShowChangelogOnUpdate)
{
ChangelogEntry changelogEntry = ChangelogData.Changelogs.FirstOrDefault();
if (changelogEntry != null && changelogEntry.IsNewVersion(requiredService3.LastViewedChangelogVersion, ChangelogData.Changelogs))
{
requiredService2.IsOpenAndUncollapsed = true;
}
}
requiredService.LogDebug("Initialize phases: data warm-up {Warmup}ms, quest reload {Quest}ms, gathering reload {Gathering}ms, init tail {Tail}ms", (long)elapsed.TotalMilliseconds, (long)elapsed2.TotalMilliseconds, (long)elapsed3.TotalMilliseconds, (long)stopwatch.Elapsed.TotalMilliseconds);
}
public async ValueTask DisposeAsync()
{
if (_serviceProvider != null)
{
await _serviceProvider.DisposeAsync();
}
}
}