mirror of
https://github.com/sp-tarkov/loot-dump-processor.git
synced 2025-02-13 07:30:44 -05:00
Refactored key generation and improved type safety across storage components
This commit is contained in:
parent
02802ddc10
commit
9e9933bd32
@ -1,6 +1,3 @@
|
|||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
|
|
||||||
namespace LootDumpProcessor.Model.Config;
|
namespace LootDumpProcessor.Model.Config;
|
||||||
|
|
||||||
public class ReaderConfig
|
public class ReaderConfig
|
||||||
|
@ -1,22 +1,24 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using LootDumpProcessor.Storage;
|
using LootDumpProcessor.Storage;
|
||||||
using LootDumpProcessor.Utils;
|
|
||||||
|
|
||||||
|
|
||||||
namespace LootDumpProcessor.Model.Processing;
|
namespace LootDumpProcessor.Model.Processing;
|
||||||
|
|
||||||
public class LooseLootCounts : IKeyable
|
public class LooseLootCounts : IKeyable
|
||||||
{
|
{
|
||||||
[JsonPropertyName("__id__")] public string __ID { get; set; } = KeyGenerator.GetNextKey();
|
[JsonPropertyName("__id__")] private string Id { get; set; }
|
||||||
|
|
||||||
public IKey Counts { get; set; }
|
public IKey Counts { get; set; }
|
||||||
|
|
||||||
// public IKey Items { get; set; }
|
|
||||||
public IKey ItemProperties { get; set; }
|
public IKey ItemProperties { get; set; }
|
||||||
public List<int> MapSpawnpointCount { get; set; } = new();
|
public List<int> MapSpawnpointCount { get; set; } = new();
|
||||||
|
|
||||||
public IKey GetKey()
|
public LooseLootCounts(string id, IKey counts, IKey itemProperties)
|
||||||
{
|
{
|
||||||
return new FlatUniqueKey(new[] { __ID });
|
ArgumentException.ThrowIfNullOrWhiteSpace(id);
|
||||||
|
Id = id;
|
||||||
|
Counts = counts ?? throw new ArgumentNullException(nameof(counts));
|
||||||
|
ItemProperties = itemProperties ?? throw new ArgumentNullException(nameof(itemProperties));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IKey GetKey() => new FlatUniqueKey([Id]);
|
||||||
}
|
}
|
@ -7,70 +7,63 @@ namespace LootDumpProcessor.Model;
|
|||||||
|
|
||||||
public class Template : IKeyable, ICloneable
|
public class Template : IKeyable, ICloneable
|
||||||
{
|
{
|
||||||
[JsonIgnore] public string __ID { get; } = KeyGenerator.GetNextKey();
|
[JsonIgnore] public string internalId { get; }
|
||||||
|
public string Id { get; set; }
|
||||||
|
public bool IsContainer { get; set; }
|
||||||
|
public bool UseGravity { get; set; }
|
||||||
|
public bool RandomRotation { get; set; }
|
||||||
|
public Vector3 Position { get; set; }
|
||||||
|
public Vector3 Rotation { get; set; }
|
||||||
|
public bool IsGroupPosition { get; set; }
|
||||||
|
public List<GroupPosition> GroupPositions { get; set; }
|
||||||
|
public bool IsAlwaysSpawn { get; set; }
|
||||||
|
public string Root { get; set; }
|
||||||
|
public List<Item> Items { get; set; }
|
||||||
|
|
||||||
|
public Template(string internalId, string id, bool isContainer, bool useGravity, bool randomRotation,
|
||||||
|
Vector3 position, Vector3 rotation, bool isGroupPosition, List<GroupPosition> groupPositions,
|
||||||
|
bool isAlwaysSpawn, string root, List<Item> items)
|
||||||
|
{
|
||||||
|
this.internalId = internalId;
|
||||||
|
Id = id;
|
||||||
|
IsContainer = isContainer;
|
||||||
|
UseGravity = useGravity;
|
||||||
|
RandomRotation = randomRotation;
|
||||||
|
Position = position;
|
||||||
|
Rotation = rotation;
|
||||||
|
IsGroupPosition = isGroupPosition;
|
||||||
|
GroupPositions = groupPositions;
|
||||||
|
IsAlwaysSpawn = isAlwaysSpawn;
|
||||||
|
Root = root;
|
||||||
|
Items = items;
|
||||||
|
}
|
||||||
|
|
||||||
public string? Id { get; set; }
|
private bool Equals(Template other) => Id == other.Id;
|
||||||
|
|
||||||
|
|
||||||
public bool? IsContainer { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public bool? UseGravity { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public bool? RandomRotation { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public Vector3? Position { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public Vector3? Rotation { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public bool? IsGroupPosition { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public List<GroupPosition>? GroupPositions { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public bool? IsAlwaysSpawn { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public string? Root { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public required List<Item> Items { get; set; }
|
|
||||||
|
|
||||||
protected bool Equals(Template other) => Id == other.Id;
|
|
||||||
|
|
||||||
public override bool Equals(object? obj)
|
public override bool Equals(object? obj)
|
||||||
{
|
{
|
||||||
if (ReferenceEquals(null, obj)) return false;
|
if (ReferenceEquals(null, obj)) return false;
|
||||||
if (ReferenceEquals(this, obj)) return true;
|
if (ReferenceEquals(this, obj)) return true;
|
||||||
if (obj.GetType() != GetType()) return false;
|
return obj.GetType() == GetType() && Equals((Template)obj);
|
||||||
return Equals((Template)obj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode() => Id != null ? Id.GetHashCode() : 0;
|
public override int GetHashCode() => Id != null ? Id.GetHashCode() : 0;
|
||||||
|
|
||||||
public IKey GetKey()
|
public IKey GetKey() => new FlatUniqueKey([internalId]);
|
||||||
{
|
|
||||||
return new FlatUniqueKey(new[] { __ID });
|
|
||||||
}
|
|
||||||
|
|
||||||
public object Clone() => new Template
|
public object Clone() => new Template
|
||||||
{
|
(
|
||||||
Id = Id,
|
internalId,
|
||||||
IsContainer = IsContainer,
|
Id,
|
||||||
UseGravity = UseGravity,
|
IsContainer,
|
||||||
RandomRotation = RandomRotation,
|
UseGravity,
|
||||||
Position = ProcessorUtil.Copy(Position),
|
RandomRotation,
|
||||||
Rotation = ProcessorUtil.Copy(Rotation),
|
ProcessorUtil.Copy(Position),
|
||||||
IsGroupPosition = IsGroupPosition,
|
ProcessorUtil.Copy(Rotation),
|
||||||
GroupPositions = ProcessorUtil.Copy(GroupPositions),
|
IsGroupPosition,
|
||||||
IsAlwaysSpawn = IsAlwaysSpawn,
|
ProcessorUtil.Copy(GroupPositions),
|
||||||
Root = Root,
|
IsAlwaysSpawn,
|
||||||
Items = ProcessorUtil.Copy(Items)
|
Root,
|
||||||
};
|
ProcessorUtil.Copy(Items)
|
||||||
|
);
|
||||||
}
|
}
|
@ -1,15 +1,19 @@
|
|||||||
using LootDumpProcessor.Model;
|
using System.Globalization;
|
||||||
|
using LootDumpProcessor.Model;
|
||||||
using LootDumpProcessor.Model.Processing;
|
using LootDumpProcessor.Model.Processing;
|
||||||
using LootDumpProcessor.Utils;
|
|
||||||
|
|
||||||
namespace LootDumpProcessor.Process;
|
namespace LootDumpProcessor.Process;
|
||||||
|
|
||||||
public class ComposedKeyGenerator(ITarkovItemsProvider tarkovItemsProvider) : IComposedKeyGenerator
|
public class ComposedKeyGenerator(ITarkovItemsProvider tarkovItemsProvider, IKeyGenerator keyGenerator)
|
||||||
|
: IComposedKeyGenerator
|
||||||
{
|
{
|
||||||
private readonly ITarkovItemsProvider _tarkovItemsProvider =
|
private readonly ITarkovItemsProvider _tarkovItemsProvider =
|
||||||
tarkovItemsProvider ?? throw new ArgumentNullException(nameof(tarkovItemsProvider));
|
tarkovItemsProvider ?? throw new ArgumentNullException(nameof(tarkovItemsProvider));
|
||||||
|
|
||||||
public ComposedKey Generate(IEnumerable<Item> items)
|
private readonly IKeyGenerator
|
||||||
|
_keyGenerator = keyGenerator ?? throw new ArgumentNullException(nameof(keyGenerator));
|
||||||
|
|
||||||
|
public ComposedKey Generate(IReadOnlyList<Item>? items)
|
||||||
{
|
{
|
||||||
var key = items?.Select(i => i.Tpl)
|
var key = items?.Select(i => i.Tpl)
|
||||||
.Where(i => !string.IsNullOrEmpty(i) &&
|
.Where(i => !string.IsNullOrEmpty(i) &&
|
||||||
@ -17,8 +21,9 @@ public class ComposedKeyGenerator(ITarkovItemsProvider tarkovItemsProvider) : IC
|
|||||||
.Cast<string>()
|
.Cast<string>()
|
||||||
.Select(i => (double)i.GetHashCode())
|
.Select(i => (double)i.GetHashCode())
|
||||||
.Sum()
|
.Sum()
|
||||||
.ToString() ?? KeyGenerator.GetNextKey();
|
.ToString(CultureInfo.InvariantCulture) ?? _keyGenerator.Generate();
|
||||||
var firstItem = items?.FirstOrDefault();
|
var firstItem = items?[0];
|
||||||
|
|
||||||
return new ComposedKey(key, firstItem);
|
return new ComposedKey(key, firstItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,5 +4,5 @@ namespace LootDumpProcessor.Process;
|
|||||||
|
|
||||||
public interface IComposedKeyGenerator
|
public interface IComposedKeyGenerator
|
||||||
{
|
{
|
||||||
ComposedKey Generate(IEnumerable<Item> items);
|
ComposedKey Generate(IReadOnlyList<Item>? items);
|
||||||
}
|
}
|
6
source/LootDumpProcessor/Process/IKeyGenerator.cs
Normal file
6
source/LootDumpProcessor/Process/IKeyGenerator.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace LootDumpProcessor.Process;
|
||||||
|
|
||||||
|
public interface IKeyGenerator
|
||||||
|
{
|
||||||
|
string Generate();
|
||||||
|
}
|
13
source/LootDumpProcessor/Process/NumericKeyGenerator.cs
Normal file
13
source/LootDumpProcessor/Process/NumericKeyGenerator.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
namespace LootDumpProcessor.Process;
|
||||||
|
|
||||||
|
public class NumericKeyGenerator : IKeyGenerator
|
||||||
|
{
|
||||||
|
private ulong _currentKey;
|
||||||
|
|
||||||
|
public string Generate()
|
||||||
|
{
|
||||||
|
var key = _currentKey;
|
||||||
|
Interlocked.Increment(ref _currentKey);
|
||||||
|
return key.ToString();
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,7 @@ public class MultithreadSteppedDumpProcessor(
|
|||||||
IStaticContainersProcessor staticContainersProcessor,
|
IStaticContainersProcessor staticContainersProcessor,
|
||||||
IAmmoProcessor ammoProcessor,
|
IAmmoProcessor ammoProcessor,
|
||||||
ILooseLootProcessor looseLootProcessor,
|
ILooseLootProcessor looseLootProcessor,
|
||||||
ILogger<MultithreadSteppedDumpProcessor> logger
|
ILogger<MultithreadSteppedDumpProcessor> logger, IKeyGenerator keyGenerator
|
||||||
)
|
)
|
||||||
: IDumpProcessor
|
: IDumpProcessor
|
||||||
{
|
{
|
||||||
@ -43,6 +43,9 @@ public class MultithreadSteppedDumpProcessor(
|
|||||||
private readonly ILogger<MultithreadSteppedDumpProcessor> _logger =
|
private readonly ILogger<MultithreadSteppedDumpProcessor> _logger =
|
||||||
logger ?? throw new ArgumentNullException(nameof(logger));
|
logger ?? throw new ArgumentNullException(nameof(logger));
|
||||||
|
|
||||||
|
private readonly IKeyGenerator
|
||||||
|
_keyGenerator = keyGenerator ?? throw new ArgumentNullException(nameof(keyGenerator));
|
||||||
|
|
||||||
private static readonly IDataStorage _dataStorage = DataStorageFactory.GetInstance();
|
private static readonly IDataStorage _dataStorage = DataStorageFactory.GetInstance();
|
||||||
|
|
||||||
public Dictionary<OutputFileType, object> ProcessDumps(List<PartialData> dumps)
|
public Dictionary<OutputFileType, object> ProcessDumps(List<PartialData> dumps)
|
||||||
@ -225,17 +228,17 @@ public class MultithreadSteppedDumpProcessor(
|
|||||||
|
|
||||||
var lockObjectContainerCounts = new object();
|
var lockObjectContainerCounts = new object();
|
||||||
var lockObjectCounts = new object();
|
var lockObjectCounts = new object();
|
||||||
var looseLootCounts = new LooseLootCounts();
|
|
||||||
|
|
||||||
var lockObjectDictionaryCounts = new object();
|
var lockObjectDictionaryCounts = new object();
|
||||||
var dictionaryCounts = new FlatKeyableDictionary<string, int>();
|
var dictionaryCounts = new FlatKeyableDictionary<string, int>(_keyGenerator.Generate());
|
||||||
looseLootCounts.Counts = dictionaryCounts.GetKey();
|
|
||||||
|
|
||||||
var lockObjectDictionaryItemProperties = new object();
|
var lockObjectDictionaryItemProperties = new object();
|
||||||
var dictionaryItemProperties = new FlatKeyableDictionary<string, FlatKeyableList<Template>>();
|
var dictionaryItemProperties =
|
||||||
|
new FlatKeyableDictionary<string, FlatKeyableList<Template>>(_keyGenerator.Generate());
|
||||||
|
|
||||||
var actualDictionaryItemProperties = new FlatKeyableDictionary<string, IKey>();
|
var actualDictionaryItemProperties = new FlatKeyableDictionary<string, IKey>(_keyGenerator.Generate());
|
||||||
looseLootCounts.ItemProperties = actualDictionaryItemProperties.GetKey();
|
var looseLootCounts = new LooseLootCounts(_keyGenerator.Generate(), dictionaryCounts.GetKey(),
|
||||||
|
actualDictionaryItemProperties.GetKey());
|
||||||
|
|
||||||
dumpProcessData.LooseLootCounts.Add(mapName, looseLootCounts.GetKey());
|
dumpProcessData.LooseLootCounts.Add(mapName, looseLootCounts.GetKey());
|
||||||
|
|
||||||
@ -316,7 +319,7 @@ public class MultithreadSteppedDumpProcessor(
|
|||||||
{
|
{
|
||||||
if (!dictionaryItemProperties.TryGetValue(uniqueKey, out var values))
|
if (!dictionaryItemProperties.TryGetValue(uniqueKey, out var values))
|
||||||
{
|
{
|
||||||
values = new FlatKeyableList<Template>();
|
values = new FlatKeyableList<Template>(_keyGenerator.Generate());
|
||||||
dictionaryItemProperties.Add(uniqueKey, values);
|
dictionaryItemProperties.Add(uniqueKey, values);
|
||||||
actualDictionaryItemProperties.Add(uniqueKey, values.GetKey());
|
actualDictionaryItemProperties.Add(uniqueKey, values.GetKey());
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ public class FileProcessor : IFileProcessor
|
|||||||
var staticLoot = new List<Template>();
|
var staticLoot = new List<Template>();
|
||||||
|
|
||||||
foreach (var item in parsedData.Data.Data.LocationLoot.Loot)
|
foreach (var item in parsedData.Data.Data.LocationLoot.Loot)
|
||||||
if (item.IsContainer ?? false) staticLoot.Add(item);
|
if (item.IsContainer) staticLoot.Add(item);
|
||||||
else looseLoot.Add(item);
|
else looseLoot.Add(item);
|
||||||
|
|
||||||
parsedData.Data = null;
|
parsedData.Data = null;
|
||||||
|
@ -11,7 +11,7 @@ namespace LootDumpProcessor.Process.Processor.v2.LooseLootProcessor;
|
|||||||
|
|
||||||
public class LooseLootProcessor(
|
public class LooseLootProcessor(
|
||||||
ILogger<LooseLootProcessor> logger, IDataStorage dataStorage, ITarkovItemsProvider tarkovItemsProvider,
|
ILogger<LooseLootProcessor> logger, IDataStorage dataStorage, ITarkovItemsProvider tarkovItemsProvider,
|
||||||
IComposedKeyGenerator composedKeyGenerator
|
IComposedKeyGenerator composedKeyGenerator, IKeyGenerator keyGenerator
|
||||||
)
|
)
|
||||||
: ILooseLootProcessor
|
: ILooseLootProcessor
|
||||||
{
|
{
|
||||||
@ -27,6 +27,9 @@ public class LooseLootProcessor(
|
|||||||
private readonly IComposedKeyGenerator _composedKeyGenerator =
|
private readonly IComposedKeyGenerator _composedKeyGenerator =
|
||||||
composedKeyGenerator ?? throw new ArgumentNullException(nameof(composedKeyGenerator));
|
composedKeyGenerator ?? throw new ArgumentNullException(nameof(composedKeyGenerator));
|
||||||
|
|
||||||
|
private readonly IKeyGenerator
|
||||||
|
_keyGenerator = keyGenerator ?? throw new ArgumentNullException(nameof(keyGenerator));
|
||||||
|
|
||||||
public PreProcessedLooseLoot PreProcessLooseLoot(List<Template> looseLoot)
|
public PreProcessedLooseLoot PreProcessLooseLoot(List<Template> looseLoot)
|
||||||
{
|
{
|
||||||
var preProcessedLoot = new PreProcessedLooseLoot
|
var preProcessedLoot = new PreProcessedLooseLoot
|
||||||
@ -34,7 +37,8 @@ public class LooseLootProcessor(
|
|||||||
Counts = new Dictionary<string, int>()
|
Counts = new Dictionary<string, int>()
|
||||||
};
|
};
|
||||||
|
|
||||||
var itemPropertiesDictionary = new SubdivisionedKeyableDictionary<string, List<Template>>();
|
var itemPropertiesDictionary =
|
||||||
|
new SubdivisionedKeyableDictionary<string, List<Template>>(_keyGenerator.Generate());
|
||||||
preProcessedLoot.ItemProperties = (AbstractKey)itemPropertiesDictionary.GetKey();
|
preProcessedLoot.ItemProperties = (AbstractKey)itemPropertiesDictionary.GetKey();
|
||||||
preProcessedLoot.MapSpawnpointCount = looseLoot.Count;
|
preProcessedLoot.MapSpawnpointCount = looseLoot.Count;
|
||||||
|
|
||||||
@ -55,7 +59,7 @@ public class LooseLootProcessor(
|
|||||||
|
|
||||||
if (!itemPropertiesDictionary.TryGetValue(sanitizedId, out var templates))
|
if (!itemPropertiesDictionary.TryGetValue(sanitizedId, out var templates))
|
||||||
{
|
{
|
||||||
templates = new FlatKeyableList<Template>();
|
templates = new FlatKeyableList<Template>(_keyGenerator.Generate());
|
||||||
itemPropertiesDictionary.Add(sanitizedId, templates);
|
itemPropertiesDictionary.Add(sanitizedId, templates);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ public class StaticContainersProcessor : IStaticContainersProcessor
|
|||||||
var locationLoot = rawMapDump.Data.LocationLoot;
|
var locationLoot = rawMapDump.Data.LocationLoot;
|
||||||
var mapId = locationLoot.Id.ToLower();
|
var mapId = locationLoot.Id.ToLower();
|
||||||
var staticLootPositions = locationLoot.Loot
|
var staticLootPositions = locationLoot.Loot
|
||||||
.Where(loot => loot.IsContainer.GetValueOrDefault())
|
.Where(loot => loot.IsContainer)
|
||||||
.OrderBy(loot => loot.Id)
|
.OrderBy(loot => loot.Id)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
@ -44,7 +44,8 @@ public class StaticContainersProcessor : IStaticContainersProcessor
|
|||||||
_logger.LogDebug("Added static weapon with ID {WeaponId} to Map {MapId}.", copiedLoot.Id, mapId);
|
_logger.LogDebug("Added static weapon with ID {WeaponId} to Map {MapId}.", copiedLoot.Id, mapId);
|
||||||
}
|
}
|
||||||
|
|
||||||
var forcedStaticItems = LootDumpProcessorContext.GetForcedItems().TryGetValue(mapId, out var forcedItems)
|
var forcedStaticItems = LootDumpProcessorContext.GetForcedItems()
|
||||||
|
.TryGetValue(mapId, out List<StaticForced>? forcedItems)
|
||||||
? forcedItems
|
? forcedItems
|
||||||
: new List<StaticForced>();
|
: new List<StaticForced>();
|
||||||
|
|
||||||
@ -61,13 +62,13 @@ public class StaticContainersProcessor : IStaticContainersProcessor
|
|||||||
public IReadOnlyList<Template> CreateDynamicStaticContainers(RootData rawMapDump)
|
public IReadOnlyList<Template> CreateDynamicStaticContainers(RootData rawMapDump)
|
||||||
{
|
{
|
||||||
var dynamicContainers = rawMapDump.Data.LocationLoot.Loot
|
var dynamicContainers = rawMapDump.Data.LocationLoot.Loot
|
||||||
.Where(loot => loot.IsContainer.GetValueOrDefault() &&
|
.Where(loot => loot.IsContainer &&
|
||||||
!LootDumpProcessorContext.GetStaticWeaponIds().Contains(loot.Items.FirstOrDefault()?.Tpl))
|
!LootDumpProcessorContext.GetStaticWeaponIds().Contains(loot.Items.FirstOrDefault()?.Tpl))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
foreach (var container in dynamicContainers)
|
foreach (var container in dynamicContainers)
|
||||||
{
|
{
|
||||||
if (container.Items == null || !container.Items.Any())
|
if (container.Items == null || container.Items.Count == 0)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Dynamic container with ID {ContainerId} has no items.", container.Id);
|
_logger.LogWarning("Dynamic container with ID {ContainerId} has no items.", container.Id);
|
||||||
continue;
|
continue;
|
||||||
|
@ -38,6 +38,7 @@ public static class Program
|
|||||||
|
|
||||||
services.AddSingleton<ITarkovItemsProvider, TarkovItemsProvider>();
|
services.AddSingleton<ITarkovItemsProvider, TarkovItemsProvider>();
|
||||||
services.AddSingleton<IDataStorage>(_ => DataStorageFactory.GetInstance());
|
services.AddSingleton<IDataStorage>(_ => DataStorageFactory.GetInstance());
|
||||||
|
services.AddSingleton<IKeyGenerator, NumericKeyGenerator>();
|
||||||
services.AddTransient<IComposedKeyGenerator, ComposedKeyGenerator>();
|
services.AddTransient<IComposedKeyGenerator, ComposedKeyGenerator>();
|
||||||
|
|
||||||
services.AddTransient<IIntakeReader, JsonFileIntakeReader>();
|
services.AddTransient<IIntakeReader, JsonFileIntakeReader>();
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using LootDumpProcessor.Utils;
|
|
||||||
|
|
||||||
namespace LootDumpProcessor.Storage.Collections;
|
namespace LootDumpProcessor.Storage.Collections;
|
||||||
|
|
||||||
public class FlatKeyableDictionary<K, V> : Dictionary<K, V>, IKeyable
|
public class FlatKeyableDictionary<K, V> : Dictionary<K, V>, IKeyable
|
||||||
{
|
{
|
||||||
[JsonPropertyName("__id__")] public string __ID { get; set; } = KeyGenerator.GetNextKey();
|
[JsonPropertyName("__id__")] private string Id { get; set; }
|
||||||
|
|
||||||
public IKey GetKey() => new FlatUniqueKey([__ID]);
|
public FlatKeyableDictionary(string id)
|
||||||
|
{
|
||||||
|
ArgumentException.ThrowIfNullOrWhiteSpace(id);
|
||||||
|
Id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IKey GetKey() => new FlatUniqueKey([Id]);
|
||||||
}
|
}
|
@ -1,10 +1,14 @@
|
|||||||
using LootDumpProcessor.Utils;
|
|
||||||
|
|
||||||
namespace LootDumpProcessor.Storage.Collections;
|
namespace LootDumpProcessor.Storage.Collections;
|
||||||
|
|
||||||
public class FlatKeyableList<T> : List<T>, IKeyable
|
public class FlatKeyableList<T> : List<T>, IKeyable
|
||||||
{
|
{
|
||||||
public string __ID { get; } = KeyGenerator.GetNextKey();
|
public string Id { get; }
|
||||||
|
|
||||||
public IKey GetKey() => new FlatUniqueKey([__ID]);
|
public FlatKeyableList(string id)
|
||||||
|
{
|
||||||
|
ArgumentException.ThrowIfNullOrWhiteSpace(id);
|
||||||
|
Id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IKey GetKey() => new FlatUniqueKey([Id]);
|
||||||
}
|
}
|
@ -1,11 +1,16 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using LootDumpProcessor.Utils;
|
|
||||||
|
|
||||||
namespace LootDumpProcessor.Storage.Collections;
|
namespace LootDumpProcessor.Storage.Collections;
|
||||||
|
|
||||||
public class SubdivisionedKeyableDictionary<K, V> : Dictionary<K, V>, IKeyable
|
public class SubdivisionedKeyableDictionary<K, V> : Dictionary<K, V>, IKeyable
|
||||||
{
|
{
|
||||||
[JsonPropertyName("__id__")] public string __ID { get; set; } = KeyGenerator.GetNextKey();
|
public SubdivisionedKeyableDictionary(string id)
|
||||||
|
{
|
||||||
|
ArgumentException.ThrowIfNullOrWhiteSpace(id);
|
||||||
|
Id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonPropertyName("__id__")] private string Id { get; set; }
|
||||||
|
|
||||||
public string? Extras
|
public string? Extras
|
||||||
{
|
{
|
||||||
@ -24,10 +29,10 @@ public class SubdivisionedKeyableDictionary<K, V> : Dictionary<K, V>, IKeyable
|
|||||||
"dictionaries"
|
"dictionaries"
|
||||||
};
|
};
|
||||||
subdivisions.AddRange(ExtraSubdivisions);
|
subdivisions.AddRange(ExtraSubdivisions);
|
||||||
subdivisions.Add(__ID);
|
subdivisions.Add(Id);
|
||||||
return new SubdivisionedUniqueKey(subdivisions.ToArray());
|
return new SubdivisionedUniqueKey(subdivisions.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SubdivisionedUniqueKey(["dictionaries", __ID]);
|
return new SubdivisionedUniqueKey(["dictionaries", Id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,7 +9,8 @@ public class FileDataStorage : IDataStorage
|
|||||||
|
|
||||||
public bool Exists(IKey key) => StoreHandlerFactory.GetInstance(key.GetKeyType()).Exists(key);
|
public bool Exists(IKey key) => StoreHandlerFactory.GetInstance(key.GetKeyType()).Exists(key);
|
||||||
|
|
||||||
public T GetItem<T>(IKey key) where T : IKeyable => StoreHandlerFactory.GetInstance(key.GetKeyType()).Retrieve<T>(key);
|
public T GetItem<T>(IKey key) where T : IKeyable =>
|
||||||
|
StoreHandlerFactory.GetInstance(key.GetKeyType()).Retrieve<T>(key);
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
|
@ -2,31 +2,33 @@ using System.Text.RegularExpressions;
|
|||||||
|
|
||||||
namespace LootDumpProcessor.Utils;
|
namespace LootDumpProcessor.Utils;
|
||||||
|
|
||||||
public static class FileDateParser
|
public static partial class FileDateParser
|
||||||
{
|
{
|
||||||
private static readonly Regex _fileDateRegex =
|
private static readonly Regex FileDateRegex = GetRegex();
|
||||||
new(".*([0-9]{4})[-]([0-9]{2})[-]([0-9]{2})[_]([0-9]{2})[-]([0-9]{2})[-]([0-9]{2}).*");
|
|
||||||
|
|
||||||
public static bool TryParseFileDate(string fileName, out DateTime? date)
|
public static bool TryParseFileDate(string fileName, out DateTime? date)
|
||||||
{
|
{
|
||||||
date = null;
|
date = null;
|
||||||
if (!_fileDateRegex.IsMatch(fileName))
|
if (!FileDateRegex.IsMatch(fileName)) return false;
|
||||||
return false;
|
|
||||||
var match = _fileDateRegex.Match(fileName);
|
var match = FileDateRegex.Match(fileName);
|
||||||
var year = match.Groups[1].Value;
|
var year = match.Groups[1].Value;
|
||||||
var month = match.Groups[2].Value;
|
var month = match.Groups[2].Value;
|
||||||
var day = match.Groups[3].Value;
|
var day = match.Groups[3].Value;
|
||||||
var hour = match.Groups[4].Value;
|
var hour = match.Groups[4].Value;
|
||||||
var mins = match.Groups[5].Value;
|
var minutes = match.Groups[5].Value;
|
||||||
var secs = match.Groups[6].Value;
|
var seconds = match.Groups[6].Value;
|
||||||
date = new DateTime(
|
date = new DateTime(
|
||||||
int.Parse(year),
|
int.Parse(year),
|
||||||
int.Parse(month),
|
int.Parse(month),
|
||||||
int.Parse(day),
|
int.Parse(day),
|
||||||
int.Parse(hour),
|
int.Parse(hour),
|
||||||
int.Parse(mins),
|
int.Parse(minutes),
|
||||||
int.Parse(secs)
|
int.Parse(seconds)
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex(".*([0-9]{4})[-]([0-9]{2})[-]([0-9]{2})[_]([0-9]{2})[-]([0-9]{2})[-]([0-9]{2}).*")]
|
||||||
|
private static partial Regex GetRegex();
|
||||||
}
|
}
|
@ -1,15 +0,0 @@
|
|||||||
namespace LootDumpProcessor.Utils;
|
|
||||||
|
|
||||||
public class KeyGenerator
|
|
||||||
{
|
|
||||||
private static long currentKey = 0L;
|
|
||||||
private static object lockObject = new();
|
|
||||||
|
|
||||||
public static string GetNextKey()
|
|
||||||
{
|
|
||||||
lock (lockObject)
|
|
||||||
{
|
|
||||||
return $"{++currentKey}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user