muffin v7.4.18

This commit is contained in:
alydev 2026-03-26 14:56:12 +10:00
parent 53aa9fdee8
commit f82b9ce2a2
50 changed files with 142364 additions and 230361 deletions

View file

@ -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;
}
}