forked from aly/qstbak
muffin v7.4.18
This commit is contained in:
parent
53aa9fdee8
commit
f82b9ce2a2
50 changed files with 142364 additions and 230361 deletions
|
|
@ -515,9 +515,7 @@ internal sealed class CombatController : IDisposable
|
|||
int num4 = 1;
|
||||
List<Vector3> list = new List<Vector3>(num4);
|
||||
CollectionsMarshal.SetCount(list, num4);
|
||||
Span<Vector3> span = CollectionsMarshal.AsSpan(list);
|
||||
int index = 0;
|
||||
span[index] = gameObject.Position;
|
||||
CollectionsMarshal.AsSpan(list)[0] = gameObject.Position;
|
||||
movementController.NavigateTo(EMovementType.Combat, null, list, fly: false, sprint: false, num3 + num - 0.25f, float.MaxValue);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Dalamud.Game.Command;
|
||||
using Dalamud.Plugin.Services;
|
||||
using Questionable.Functions;
|
||||
|
|
@ -36,8 +37,12 @@ internal sealed class CommandHandler : IDisposable
|
|||
|
||||
private readonly FateController _fateController;
|
||||
|
||||
private readonly SeasonalDutyController _seasonalDutyController;
|
||||
|
||||
private readonly FateSelectionWindow _fateSelectionWindow;
|
||||
|
||||
private readonly SeasonalDutySelectionWindow _seasonalDutySelectionWindow;
|
||||
|
||||
private readonly ITargetManager _targetManager;
|
||||
|
||||
private readonly IClientState _clientState;
|
||||
|
|
@ -46,13 +51,14 @@ internal sealed class CommandHandler : IDisposable
|
|||
|
||||
private readonly ChangelogWindow _changelogWindow;
|
||||
|
||||
public CommandHandler(ICommandManager commandManager, IChatGui chatGui, QuestController questController, MovementController movementController, FateController fateController, QuestRegistry questRegistry, ConfigWindow configWindow, DebugOverlay debugOverlay, OneTimeSetupWindow oneTimeSetupWindow, QuestWindow questWindow, QuestSelectionWindow questSelectionWindow, QuestSequenceWindow questSequenceWindow, JournalProgressWindow journalProgressWindow, PriorityWindow priorityWindow, FateSelectionWindow fateSelectionWindow, ITargetManager targetManager, QuestFunctions questFunctions, GameFunctions gameFunctions, AetheryteFunctions aetheryteFunctions, IDataManager dataManager, IClientState clientState, IObjectTable objectTable, Configuration configuration, ChangelogWindow changelogWindow)
|
||||
public CommandHandler(ICommandManager commandManager, IChatGui chatGui, QuestController questController, MovementController movementController, FateController fateController, SeasonalDutyController seasonalDutyController, QuestRegistry questRegistry, ConfigWindow configWindow, DebugOverlay debugOverlay, OneTimeSetupWindow oneTimeSetupWindow, QuestWindow questWindow, QuestSelectionWindow questSelectionWindow, QuestSequenceWindow questSequenceWindow, JournalProgressWindow journalProgressWindow, PriorityWindow priorityWindow, FateSelectionWindow fateSelectionWindow, SeasonalDutySelectionWindow seasonalDutySelectionWindow, ITargetManager targetManager, QuestFunctions questFunctions, GameFunctions gameFunctions, AetheryteFunctions aetheryteFunctions, IDataManager dataManager, IClientState clientState, IObjectTable objectTable, Configuration configuration, ChangelogWindow changelogWindow)
|
||||
{
|
||||
_commandManager = commandManager;
|
||||
_chatGui = chatGui;
|
||||
_questController = questController;
|
||||
_movementController = movementController;
|
||||
_fateController = fateController;
|
||||
_seasonalDutyController = seasonalDutyController;
|
||||
_configWindow = configWindow;
|
||||
_oneTimeSetupWindow = oneTimeSetupWindow;
|
||||
_questWindow = questWindow;
|
||||
|
|
@ -61,6 +67,7 @@ internal sealed class CommandHandler : IDisposable
|
|||
_journalProgressWindow = journalProgressWindow;
|
||||
_priorityWindow = priorityWindow;
|
||||
_fateSelectionWindow = fateSelectionWindow;
|
||||
_seasonalDutySelectionWindow = seasonalDutySelectionWindow;
|
||||
_targetManager = targetManager;
|
||||
_clientState = clientState;
|
||||
_configuration = configuration;
|
||||
|
|
@ -69,15 +76,15 @@ internal sealed class CommandHandler : IDisposable
|
|||
ICommandManager commandManager2 = _commandManager;
|
||||
CommandInfo commandInfo = new CommandInfo(ProcessCommand);
|
||||
string separator = Environment.NewLine + "\t";
|
||||
_003C_003Ey__InlineArray7<string> buffer = default(_003C_003Ey__InlineArray7<string>);
|
||||
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<_003C_003Ey__InlineArray7<string>, string>(ref buffer, 0) = "Opens the Questing window";
|
||||
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<_003C_003Ey__InlineArray7<string>, string>(ref buffer, 1) = "/qst help - displays simplified commands";
|
||||
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<_003C_003Ey__InlineArray7<string>, string>(ref buffer, 2) = "/qst help-all - displays all available commands";
|
||||
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<_003C_003Ey__InlineArray7<string>, string>(ref buffer, 3) = "/qst config - opens the configuration window";
|
||||
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<_003C_003Ey__InlineArray7<string>, string>(ref buffer, 4) = "/qst changelog - opens the changelog window";
|
||||
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<_003C_003Ey__InlineArray7<string>, string>(ref buffer, 5) = "/qst start - starts doing quests";
|
||||
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<_003C_003Ey__InlineArray7<string>, string>(ref buffer, 6) = "/qst stop - stops doing quests";
|
||||
commandInfo.HelpMessage = string.Join(separator, global::_003CPrivateImplementationDetails_003E.InlineArrayAsReadOnlySpan<_003C_003Ey__InlineArray7<string>, string>(in buffer, 7));
|
||||
InlineArray7<string> buffer = default(InlineArray7<string>);
|
||||
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray7<string>, string>(ref buffer, 0) = "Opens the Questing window";
|
||||
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray7<string>, string>(ref buffer, 1) = "/qst help - displays simplified commands";
|
||||
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray7<string>, string>(ref buffer, 2) = "/qst help-all - displays all available commands";
|
||||
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray7<string>, string>(ref buffer, 3) = "/qst config - opens the configuration window";
|
||||
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray7<string>, string>(ref buffer, 4) = "/qst changelog - opens the changelog window";
|
||||
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray7<string>, string>(ref buffer, 5) = "/qst start - starts doing quests";
|
||||
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray7<string>, string>(ref buffer, 6) = "/qst stop - stops doing quests";
|
||||
commandInfo.HelpMessage = string.Join(separator, global::_003CPrivateImplementationDetails_003E.InlineArrayAsReadOnlySpan<InlineArray7<string>, string>(in buffer, 7));
|
||||
commandManager2.AddHandler("/qst", commandInfo);
|
||||
}
|
||||
|
||||
|
|
@ -99,7 +106,7 @@ internal sealed class CommandHandler : IDisposable
|
|||
_chatGui.Print("/qst start - starts doing quests", "Questionable", 576);
|
||||
_chatGui.Print("/qst stop - stops doing quests", "Questionable", 576);
|
||||
_chatGui.Print("/qst reload - reload all quest data", "Questionable", 576);
|
||||
_chatGui.Print("/qst fate - toggles the FATE farming window", "Questionable", 576);
|
||||
_chatGui.Print("/qst fate / duty - toggles the farming window", "Questionable", 576);
|
||||
break;
|
||||
case "ha":
|
||||
case "help-all":
|
||||
|
|
@ -116,7 +123,7 @@ internal sealed class CommandHandler : IDisposable
|
|||
_chatGui.Print("/qst zone - shows all quests starting in the current zone (only includes quests with a known quest path, and currently visible unaccepted quests)", "Questionable", 576);
|
||||
_chatGui.Print("/qst journal - toggles the Journal Progress window", "Questionable", 576);
|
||||
_chatGui.Print("/qst priority - toggles the Priority window", "Questionable", 576);
|
||||
_chatGui.Print("/qst fate - toggles the FATE farming window", "Questionable", 576);
|
||||
_chatGui.Print("/qst fate / duty - toggles the farming window", "Questionable", 576);
|
||||
_chatGui.Print("/qst handle-interrupt - makes Questionable handle queued interrupts immediately (useful if you manually start combat)", "Questionable", 576);
|
||||
break;
|
||||
case "c":
|
||||
|
|
@ -135,6 +142,7 @@ internal sealed class CommandHandler : IDisposable
|
|||
_movementController.Stop();
|
||||
_questController.Stop("Stop command");
|
||||
_fateController.Stop("Stop command");
|
||||
_seasonalDutyController.Stop("Stop command");
|
||||
break;
|
||||
case "reload":
|
||||
_questWindow.Reload();
|
||||
|
|
@ -158,6 +166,10 @@ internal sealed class CommandHandler : IDisposable
|
|||
case "fate":
|
||||
_fateSelectionWindow.ToggleOrUncollapse();
|
||||
break;
|
||||
case "d":
|
||||
case "duty":
|
||||
_seasonalDutySelectionWindow.ToggleOrUncollapse();
|
||||
break;
|
||||
case "handle-interrupt":
|
||||
_questController.InterruptQueueWithCombat();
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -200,9 +200,7 @@ internal sealed class ContextMenuController : IDisposable
|
|||
int num = 1;
|
||||
List<GatheredItem> list = new List<GatheredItem>(num);
|
||||
CollectionsMarshal.SetCount(list, num);
|
||||
Span<GatheredItem> span = CollectionsMarshal.AsSpan(list);
|
||||
int index = 0;
|
||||
span[index] = new GatheredItem
|
||||
CollectionsMarshal.AsSpan(list)[0] = new GatheredItem
|
||||
{
|
||||
ItemId = itemId,
|
||||
ItemCount = quantity,
|
||||
|
|
|
|||
|
|
@ -179,9 +179,7 @@ internal abstract class MiniTaskController<T> : IDisposable
|
|||
int num = 1;
|
||||
List<ITask> list2 = new List<ITask>(num);
|
||||
CollectionsMarshal.SetCount(list2, num);
|
||||
Span<ITask> span = CollectionsMarshal.AsSpan(list2);
|
||||
int index = 0;
|
||||
span[index] = new WaitAtEnd.WaitDelay();
|
||||
CollectionsMarshal.AsSpan(list2)[0] = new WaitAtEnd.WaitDelay();
|
||||
taskQueue.InterruptWith(list2);
|
||||
}
|
||||
LogTasksAfterInterruption();
|
||||
|
|
@ -196,9 +194,7 @@ internal abstract class MiniTaskController<T> : IDisposable
|
|||
int num = 1;
|
||||
List<ITask> list = new List<ITask>(num);
|
||||
CollectionsMarshal.SetCount(list, num);
|
||||
Span<ITask> span = CollectionsMarshal.AsSpan(list);
|
||||
int index = 0;
|
||||
span[index] = new WaitAtEnd.WaitDelay();
|
||||
CollectionsMarshal.AsSpan(list)[0] = new WaitAtEnd.WaitDelay();
|
||||
taskQueue.InterruptWith(list);
|
||||
LogTasksAfterInterruption();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -431,9 +431,7 @@ internal sealed class MovementController : IDisposable
|
|||
int num = 1;
|
||||
List<Vector3> list = new List<Vector3>(num);
|
||||
CollectionsMarshal.SetCount(list, num);
|
||||
Span<Vector3> span = CollectionsMarshal.AsSpan(list);
|
||||
int index = 0;
|
||||
span[index] = destination.Position;
|
||||
CollectionsMarshal.AsSpan(list)[0] = destination.Position;
|
||||
NavigateTo(EMovementType.None, dataId, list, fly: false, sprint: false, destination.StopDistance, destination.VerticalStopDistance);
|
||||
}
|
||||
|
||||
|
|
|
|||
151
Questionable/Questionable.Controller/SeasonalDutyController.cs
Normal file
151
Questionable/Questionable.Controller/SeasonalDutyController.cs
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Plugin.Services;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.Controller.Steps;
|
||||
using Questionable.Controller.Steps.Common;
|
||||
using Questionable.Controller.Steps.Interactions;
|
||||
using Questionable.Controller.Steps.Movement;
|
||||
using Questionable.Controller.Steps.Shared;
|
||||
using Questionable.Model.Questing;
|
||||
|
||||
namespace Questionable.Controller;
|
||||
|
||||
internal sealed class SeasonalDutyController : MiniTaskController<SeasonalDutyController>
|
||||
{
|
||||
private readonly MovementController _movementController;
|
||||
|
||||
private readonly IClientState _clientState;
|
||||
|
||||
private readonly ILogger<SeasonalDutyController> _logger;
|
||||
|
||||
private SeasonalDutyDefinition? _currentDuty;
|
||||
|
||||
private int _completedCycles;
|
||||
|
||||
private int? _cycleLimit;
|
||||
|
||||
private DateTime _startTime;
|
||||
|
||||
public bool IsRunning => _currentDuty != null;
|
||||
|
||||
public SeasonalDutyDefinition? CurrentDuty => _currentDuty;
|
||||
|
||||
public int CompletedCycles => _completedCycles;
|
||||
|
||||
public int? CycleLimit => _cycleLimit;
|
||||
|
||||
public TimeSpan ElapsedTime
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsRunning)
|
||||
{
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
return DateTime.UtcNow - _startTime;
|
||||
}
|
||||
}
|
||||
|
||||
public SeasonalDutyController(IChatGui chatGui, ICondition condition, IServiceProvider serviceProvider, InterruptHandler interruptHandler, IDataManager dataManager, ILogger<SeasonalDutyController> logger, MovementController movementController, IClientState clientState)
|
||||
: base(chatGui, condition, serviceProvider, interruptHandler, dataManager, logger)
|
||||
{
|
||||
_movementController = movementController;
|
||||
_clientState = clientState;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void Start(SeasonalDutyDefinition duty, int? cycleLimit = null)
|
||||
{
|
||||
_currentDuty = duty;
|
||||
_completedCycles = 0;
|
||||
_cycleLimit = cycleLimit;
|
||||
_startTime = DateTime.UtcNow;
|
||||
_logger.LogInformation("Starting seasonal duty farming: {DutyName} (limit: {Limit})", duty.Name, cycleLimit?.ToString(CultureInfo.InvariantCulture) ?? "unlimited");
|
||||
EnqueueDutyCycle();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (_currentDuty == null || _movementController.IsPathfinding || _movementController.IsPathRunning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_taskQueue.AllTasksComplete)
|
||||
{
|
||||
_completedCycles++;
|
||||
if (_cycleLimit.HasValue && _completedCycles >= _cycleLimit.Value)
|
||||
{
|
||||
_logger.LogInformation("Seasonal duty cycle limit reached ({Cycles}/{Limit})", _completedCycles, _cycleLimit.Value);
|
||||
Stop("Cycle limit reached");
|
||||
return;
|
||||
}
|
||||
EnqueueDutyCycle();
|
||||
}
|
||||
UpdateCurrentTask();
|
||||
}
|
||||
|
||||
private void EnqueueDutyCycle()
|
||||
{
|
||||
if (_currentDuty != null)
|
||||
{
|
||||
SeasonalDutyDefinition currentDuty = _currentDuty;
|
||||
_logger.LogInformation("Enqueuing seasonal duty cycle for {DutyName}", currentDuty.Name);
|
||||
if (_clientState.TerritoryType != currentDuty.TerritoryId && _clientState.TerritoryType != currentDuty.DutyTerritoryId)
|
||||
{
|
||||
_taskQueue.Enqueue(new AetheryteShortcut.Task(null, null, currentDuty.Aetheryte, currentDuty.TerritoryId));
|
||||
}
|
||||
if (currentDuty.AethernetShortcut != null)
|
||||
{
|
||||
_taskQueue.Enqueue(new AethernetShortcut.Task(currentDuty.AethernetShortcut.From, currentDuty.AethernetShortcut.To));
|
||||
}
|
||||
_taskQueue.Enqueue(new MoveTask(currentDuty.TerritoryId, currentDuty.NpcPosition, null, 3f));
|
||||
_taskQueue.Enqueue(new Mount.UnmountTask());
|
||||
_taskQueue.Enqueue(new Interact.Task(currentDuty.NpcDataId, null, EInteractionType.Interact, SkipMarkerCheck: true));
|
||||
_taskQueue.Enqueue(new WaitCondition.Task(() => _clientState.TerritoryType == _currentDuty.DutyTerritoryId, $"Wait(territory: {currentDuty.DutyTerritoryId})"));
|
||||
_taskQueue.Enqueue(new ClearObjectsWithAction.ClearTask(currentDuty.DataIds, currentDuty.Action, currentDuty.DutyTerritoryId, currentDuty.StopDistance, currentDuty.WaypointPositions));
|
||||
_taskQueue.Enqueue(new WaitCondition.Task(() => _clientState.TerritoryType != _currentDuty.DutyTerritoryId, "Wait(duty end)"));
|
||||
_taskQueue.Enqueue(new WaitAtEnd.WaitDelay(TimeSpan.FromSeconds(3L)));
|
||||
}
|
||||
}
|
||||
|
||||
public override void Stop(string label)
|
||||
{
|
||||
if (_currentDuty != null)
|
||||
{
|
||||
_logger.LogInformation("Stopping seasonal duty farming: {Label} (completed {Cycles} cycles)", label, _completedCycles);
|
||||
_currentDuty = null;
|
||||
_completedCycles = 0;
|
||||
_cycleLimit = null;
|
||||
_taskQueue.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
public override IList<string> GetRemainingTaskNames()
|
||||
{
|
||||
ITask task = _taskQueue.CurrentTaskExecutor?.CurrentTask;
|
||||
if (task != null)
|
||||
{
|
||||
string text = task.ToString() ?? "?";
|
||||
IList<string> remainingTaskNames = base.GetRemainingTaskNames();
|
||||
int num = 1 + remainingTaskNames.Count;
|
||||
List<string> list = new List<string>(num);
|
||||
CollectionsMarshal.SetCount(list, num);
|
||||
Span<string> span = CollectionsMarshal.AsSpan(list);
|
||||
int num2 = 0;
|
||||
span[num2] = text;
|
||||
num2++;
|
||||
{
|
||||
foreach (string item in remainingTaskNames)
|
||||
{
|
||||
span[num2] = item;
|
||||
num2++;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
return base.GetRemainingTaskNames();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
#define RELEASE
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using Dalamud.Plugin;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.Model.Questing;
|
||||
using Questionable.SeasonalDutyPaths;
|
||||
using Questionable.Windows.QuestComponents;
|
||||
|
||||
namespace Questionable.Controller;
|
||||
|
||||
internal sealed class SeasonalDutyDefinitionRegistry
|
||||
{
|
||||
private readonly IDalamudPluginInterface _pluginInterface;
|
||||
|
||||
private readonly ILogger<SeasonalDutyDefinitionRegistry> _logger;
|
||||
|
||||
private readonly Dictionary<ushort, SeasonalDutyDefinition> _definitions = new Dictionary<ushort, SeasonalDutyDefinition>();
|
||||
|
||||
public IReadOnlyDictionary<ushort, SeasonalDutyDefinition> Definitions => _definitions;
|
||||
|
||||
public SeasonalDutyDefinitionRegistry(IDalamudPluginInterface pluginInterface, ILogger<SeasonalDutyDefinitionRegistry> logger)
|
||||
{
|
||||
_pluginInterface = pluginInterface;
|
||||
_logger = logger;
|
||||
Reload();
|
||||
}
|
||||
|
||||
public void Reload()
|
||||
{
|
||||
_definitions.Clear();
|
||||
LoadFromAssembly();
|
||||
try
|
||||
{
|
||||
LoadFromDirectory(new DirectoryInfo(Path.Combine(_pluginInterface.ConfigDirectory.FullName, "SeasonalDutyDefinitions")));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.LogError(exception, "Failed to load seasonal duty definitions from user directory (some may have been successfully loaded)");
|
||||
}
|
||||
RemoveExpiredDefinitions();
|
||||
_logger.LogInformation("Loaded {Count} seasonal duty definitions in total", _definitions.Count);
|
||||
}
|
||||
|
||||
[Conditional("RELEASE")]
|
||||
private void LoadFromAssembly()
|
||||
{
|
||||
_logger.LogInformation("Loading seasonal duty definitions from assembly");
|
||||
IReadOnlyDictionary<ushort, SeasonalDutyDefinition> definitions = AssemblySeasonalDutyDefinitionLoader.GetDefinitions();
|
||||
_logger.LogInformation("AssemblySeasonalDutyDefinitionLoader returned {Count} definitions", definitions.Count);
|
||||
foreach (var (key, value) in definitions)
|
||||
{
|
||||
_definitions[key] = value;
|
||||
}
|
||||
_logger.LogInformation("Loaded {Count} seasonal duty definitions from assembly", _definitions.Count);
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void LoadFromProjectDirectory()
|
||||
{
|
||||
DirectoryInfo directoryInfo = _pluginInterface.AssemblyLocation.Directory?.Parent?.Parent;
|
||||
if (directoryInfo == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
DirectoryInfo directoryInfo2 = new DirectoryInfo(Path.Combine(directoryInfo.FullName, "SeasonalDutyPaths"));
|
||||
if (directoryInfo2.Exists)
|
||||
{
|
||||
try
|
||||
{
|
||||
LoadFromDirectory(directoryInfo2);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_definitions.Clear();
|
||||
_logger.LogError(exception, "Failed to load seasonal duty definitions from project directory");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadFromDirectory(DirectoryInfo directory)
|
||||
{
|
||||
if (!directory.Exists)
|
||||
{
|
||||
_logger.LogInformation("Not loading seasonal duty definitions from {DirectoryName} (doesn't exist)", directory);
|
||||
return;
|
||||
}
|
||||
FileInfo[] files = directory.GetFiles("*.json");
|
||||
foreach (FileInfo fileInfo in files)
|
||||
{
|
||||
try
|
||||
{
|
||||
ushort? num = ExtractIdFromName(fileInfo.Name);
|
||||
if (!num.HasValue)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
using FileStream utf8Json = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read);
|
||||
SeasonalDutyDefinition seasonalDutyDefinition = JsonSerializer.Deserialize<SeasonalDutyDefinition>(utf8Json);
|
||||
if (seasonalDutyDefinition != null)
|
||||
{
|
||||
_definitions[num.Value] = seasonalDutyDefinition;
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.LogError(exception, "Unable to load seasonal duty definition file {FileName}", fileInfo.FullName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveExpiredDefinitions()
|
||||
{
|
||||
foreach (ushort item in (from kvp in _definitions.Where<KeyValuePair<ushort, SeasonalDutyDefinition>>(delegate(KeyValuePair<ushort, SeasonalDutyDefinition> kvp)
|
||||
{
|
||||
DateTime? eventExpiry = kvp.Value.EventExpiry;
|
||||
if (eventExpiry.HasValue)
|
||||
{
|
||||
DateTime valueOrDefault = eventExpiry.GetValueOrDefault();
|
||||
return EventInfoComponent.NormalizeExpiry(valueOrDefault) < DateTime.UtcNow;
|
||||
}
|
||||
return false;
|
||||
})
|
||||
select kvp.Key).ToList())
|
||||
{
|
||||
_logger.LogInformation("Removing expired seasonal duty definition {Id} '{Name}'", item, _definitions[item].Name);
|
||||
_definitions.Remove(item);
|
||||
}
|
||||
}
|
||||
|
||||
private static ushort? ExtractIdFromName(string fileName)
|
||||
{
|
||||
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
|
||||
if (!fileNameWithoutExtension.Contains('_', StringComparison.Ordinal))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (ushort.TryParse(fileNameWithoutExtension.Split('_', 2)[0], out var result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue