mirror of
https://github.com/sp-tarkov/loot-dump-processor.git
synced 2025-02-13 09:50:44 -05:00

* Improved thread safety and async processing in dump processor components * Removed unused _processedDumps field and simplified variable scope in QueuePipeline * Refactored service registration into dedicated extension methods * Added configuration binding and environment variables support * Refactored collector initialization to use dependency injection * Refactored data storage to use dependency injection * Refactored configuration models to use records and added validation * Refactored static loot configuration to use dependency injection The changes include: - Moved static weapon IDs and forced items from LootDumpProcessorContext to ForcedStatic record - Added ForcedStatic configuration injection in StaticLootProcessor and StaticContainerProcessor - Improved immutability by using read-only collections in ForcedStatic model - Simplified LootDumpProcessorContext by removing unused methods * Refactored configuration access to use dependency injection consistently * Fixed ForcedStatic configuration * Refactored forced items configuration to use async provider pattern The changes introduce a new `IForcedItemsProvider` abstraction to handle loading and caching of forced static and loose loot configurations. This improves the code by: 1. Making configuration loading asynchronous 2. Implementing caching of loaded configurations 3. Centralizing forced items configuration access 4. Removing direct file system dependencies from processors 5. Improving testability through dependency injection The change also updates related processors and interfaces to use async/await pattern consistently. * Refactored loose loot processor to use async forced items provider * Reorganized processor and service components into dedicated namespaces
87 lines
3.1 KiB
C#
87 lines
3.1 KiB
C#
using System.Collections.Concurrent;
|
|
using System.Text.Json;
|
|
using LootDumpProcessor.Model.Config;
|
|
using LootDumpProcessor.Model.Input;
|
|
using LootDumpProcessor.Model.Processing;
|
|
using LootDumpProcessor.Serializers.Json;
|
|
using LootDumpProcessor.Utils;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Options;
|
|
|
|
namespace LootDumpProcessor.Process.Reader.Intake;
|
|
|
|
public class JsonFileIntakeReader(ILogger<JsonFileIntakeReader> logger, IOptions<Config> config) : IIntakeReader
|
|
{
|
|
private readonly ILogger<JsonFileIntakeReader> _logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
|
|
|
private readonly Config _config = (config ?? throw new ArgumentNullException(nameof(config))).Value;
|
|
|
|
private HashSet<string> IgnoredLocations => _config
|
|
.ReaderConfig.IntakeReaderConfig.IgnoredDumpLocations.ToHashSet();
|
|
|
|
private readonly ConcurrentDictionary<string, int> _totalMapDumpsCounter = new();
|
|
|
|
public bool Read(string file, out BasicInfo basicInfo)
|
|
{
|
|
basicInfo = null;
|
|
string? fileData;
|
|
|
|
try
|
|
{
|
|
fileData = File.ReadAllText(file);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to read file: {File}", file);
|
|
return false;
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(fileData))
|
|
{
|
|
_logger.LogError("Could not parse data from file: {File}", file);
|
|
return false;
|
|
}
|
|
|
|
// If the file format changes, it may affect the date parser
|
|
if (!FileDateParser.TryParseFileDate(file, out var date))
|
|
_logger.LogError("Could not parse date from file: {File}", file);
|
|
|
|
var fi = JsonSerializer.Deserialize<RootData>(fileData, JsonSerializerSettings.Default);
|
|
if (fi?.Data.LocationLoot.Name != null && (!IgnoredLocations?.Contains(fi.Data.LocationLoot.Name) ?? true))
|
|
{
|
|
var mapName = fi.Data.LocationLoot.Name;
|
|
var mapId = fi.Data.LocationLoot.Id.ToLower();
|
|
|
|
var counter = _totalMapDumpsCounter.AddOrUpdate(mapName, 0, (_, current) => current);
|
|
|
|
var maxDumpsPerMap = _config
|
|
.ReaderConfig.IntakeReaderConfig?.MaxDumpsPerMap ?? 1500;
|
|
|
|
if (counter < maxDumpsPerMap)
|
|
{
|
|
basicInfo = new BasicInfo
|
|
{
|
|
Map = mapId,
|
|
FileHash = ProcessorUtil.HashFile(fileData),
|
|
Data = fi,
|
|
Date = date ?? DateTime.MinValue,
|
|
FileName = file
|
|
};
|
|
|
|
_totalMapDumpsCounter[mapName] += 1;
|
|
|
|
_logger.LogDebug("File {File} fully read, returning data", file);
|
|
return true;
|
|
}
|
|
|
|
// Map dump limit reached, exit
|
|
_logger.LogDebug("Ignoring file {File} as the file cap for map {MapId} has been reached", file, mapId);
|
|
return false;
|
|
}
|
|
|
|
_logger.LogWarning(
|
|
"File {File} was not eligible for dump data; it did not contain a location name or it was on the ignored locations config",
|
|
file);
|
|
return false;
|
|
}
|
|
} |