0
0
mirror of https://github.com/sp-tarkov/loot-dump-processor.git synced 2025-02-13 02:30:45 -05:00

Merge pull request #2 from BlueXTX/pr/bluextx/nextgen-processor

Major performance boost
This commit is contained in:
Chomp 2025-01-11 10:58:32 +00:00 committed by GitHub
commit 5d2c0d04b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
271 changed files with 3026 additions and 5500 deletions

3
.gitignore vendored
View File

@ -398,3 +398,6 @@ FodyWeavers.xsd
# JetBrains Rider
*.sln.iml
# Qodo
.qodo

View File

@ -1,171 +0,0 @@
---
bigmap:
- 5938188786f77474f723e87f # Case 0031
- 5c12301c86f77419522ba7e4 # Flash drive with fake info
- 593965cf86f774087a77e1b6 # Case 0048
- 591092ef86f7747bb8703422 # Secure folder 0022 in big red offices
- 590c62a386f77412b0130255 # Sliderkey Secure Flash drive in Dorms 2-way room 220
- 5939e9b286f77462a709572c # Sealed letter (Terragroup)
- 5ac620eb86f7743a8e6e0da0 # Package of graphics cards in big red offices
- 590dde5786f77405e71908b2 # Bank case
- 5910922b86f7747d96753483 # Carbon case
- 5937fd0086f7742bf33fc198 # Bronze pocket watch on a chain
- 5939a00786f7742fe8132936 # Golden Zibbo lighter
- 5939e5a786f77461f11c0098 # Secure Folder 0013
- 64e74a3d4d49d23b2c39d319 # item_quest_clock_07 (Out of Time)
- 6614230055afee107f05e998 # The Unheard's phone
- 664fce7a90294949fe2d81cb # Item_barter_info_host_quest
- 66b22630a6b4e5ec7c02cdb7 # item_quest_instruments
#- 64bd1abff3a668f08805ce4f # Secure Flash drive V4 REMOVED BY BSG
- 675f7acc4076a741a3061566 # TerraGroup shipment report
- 675f80d4fe1b59cf490d3527 # Box with upgraded tools
- 675f7f224076a741a3061568 # Skier's wallet
- 675f7b168d28a25ec7007dbb # Delivery crew report
- 67499d0eeca8acb2d2061639 # Incriminating letter
woods:
- 5938878586f7741b797c562f # Case 0052
- 5d3ec50586f774183a607442 # Jaeger's message Underneath the wooden lookout post.
- 5af04e0a86f7743a532b79e2 # Single-axis Fiber Optic Gyroscope: item_barter_electr_gyroscope
- 5a687e7886f7740c4a5133fb # Blood sample
- 5af04c0b86f774138708f78e # Motor Controller: item_barter_electr_controller
- 664a5775f3d3570fba06be64 # quest_flyers
- 664b69c5a082271bc46c4e11 # quest_flyers2
- 664b69e8e1238e506d3630af # quest_flyers3
#- 64bde2248f3a947a990aa4a5 # Sliderkey Secure Flash drive #1 REMOVED BY BSG
#- 64bde265807321a9b905f076 # Sliderkey Secure Flash drive #2 REMOVED BY BSG
shoreline:
- 5a294d7c86f7740651337cf9 # Drone 1 SAS disk
- 5a294d8486f774068638cd93 # Drone 2 SAS disk: ambiguous with itemTpl 5a294f1686f774340c7b7e4a
- 5efdafc1e70b5e33f86de058 # Sanitar's Surgery kit marked with a blue symbol
- 5939e5a786f77461f11c0098 # Secure folder 0013
- 5a6860d886f77411cd3a9e47 # Secure folder 0060
- 5a29357286f77409c705e025 # Sliderkey Flash drive
- 5efdaf6de6a30218ed211a48 # Sanitar's Ophthalmoscope In potted plant on dining room table.
- 5d357d6b86f7745b606e3508 # Photo album in west wing room 303
- 5b4c72b386f7745b453af9c0 # Motor Controller: item_barter_electr_controller2
- 5a0448bc86f774736f14efa8 # Key to the closed premises of the Health Resort
- 5a29276886f77435ed1b117c # Working hard drive
- 5b4c72fb86f7745cef1cffc5 # Single-axis Fiber Optic Gyroscope: item_barter_electr_gyroscope2
- 5b4c72c686f77462ac37e907 # Motor Controller: item_barter_electr_controller3
- 5b43237186f7742f3a4ab252 # Chemical container: item_quest_chem_container
- 5a29284f86f77463ef3db363 # Toughbook reinforced laptop
- 64e74a534d49d23b2c39d31b # item_quest_clock_10 (Out of Time)
- 6614238e0d240a5f5d0f679d # Skier and Peacekeeper correspondence
- 661421c7c1f2f548c50ee649 # The Unheard's laptop
- 6614217b6d9d5abcad0ff098 # The Unheard's phone
- 661423200d240a5f5d0f679b # The Unheard's laptop
- 666073159916667083033cb9 # Item_quest_tattered_diary
- 66760b3deb51b08bd40c2b08 # item_barter_electr_hdd_NosQuests_quest
- 6707d1f9571b50abc703b651 # True vaccine recipe (Halloween 2024)
- 67499adbeca8acb2d2061634 # Cargo for Prapor
- 67586bee39b1b82b0d0f9d06 # Special 40-degree fuel
interchange:
- 5ae9a18586f7746e381e16a3 # OLI cargo manifests
- 5ae9a0dd86f7742e5f454a05 # Goshan cargo manifests
- 5ae9a1b886f77404c8537c62 # Idea cargo manifests
- 5ae9a25386f7746dd946e6d9 # OLI cargo route documents (locked)
- 5ae9a3f586f7740aab00e4e6 # Clothes design handbook - Part 1
- 5ae9a4fc86f7746e381e1753 # Clothes design handbook - Part 2
- 5b4c81a086f77417d26be63f # Chemical container item_quest_chem_container2
- 5b4c81bd86f77418a75ae159 # Chemical container item_quest_chem_container3
- 64e74a5ac2b4f829615ec336 # item_quest_clock_11 (Out of Time)
- 667a8ef464eea5fdef0db135 # item_quest_gamemagazine
- 671a406a6d315b526708f103 # Stolen weapon case
- 67586bee39b1b82b0d0f9d06 # Special 40-degree fuel
factory4_day:
- 591093bb86f7747caa7bb2ee # On the neck of the dead scav in the bunker (Postman Pat Part 2)
- 593a87af86f774122f54a951 # Syringe with a chemical
- 66a0e523e749756c920d02d0 # item_quest_chem_container_nf2024
- 669fac549b0ce3feae01a137 # item_quest_chimicalsample
- 66c0b90c8398582e4b0c2e27 # item_quest_factoryflight_journal
- 66c0b39ca1f68fcc1d0c0cc3 # item_quest_factorylab_journal
- 66a0f0926fee20fa70036da6 # Blood sample (Halloween2024)
factory4_night:
- 591093bb86f7747caa7bb2ee # On the neck of the dead scav in the bunker (Postman Pat Part 2)
- 593a87af86f774122f54a951 # Syringe with a chemical
- 66a0f0926fee20fa70036da6 # Blood sample (Halloween2024)
- 66a0e523e749756c920d02d0 # item_quest_chem_container_nf2024
- 669fac549b0ce3feae01a137 # item_quest_chimicalsample
- 66c0b90c8398582e4b0c2e27 # item_quest_factoryflight_journal
- 66c0b39ca1f68fcc1d0c0cc3 # item_quest_factorylab_journal
lighthouse:
- 61904c9df62c89219a56e034 # The message is tucked under the bottom of the door to the cabin.
- 619268ad78f4fa33f173dbe5 # Water pump operation data On the desk between other documents in the upper office.
- 619268de2be33f2604340159 # Pumping Station Operation Data In the upper floor office on the shelf.
- 61a00bcb177fb945751bbe6a # Stolen military documents On the back corner of the dining room table on the third floor at Chalet.
- 619252352be33f26043400a7 # Laptop with information
- 628393620d8524273e7eb028 # Working hard drive
- 6331bb0d1aa9f42b804997a6 # V3 Flash Drive
- 6398a0861c712b1e1d4dadf1 # Forged Lightkeeper intelligence (Snatch)
- 6399f54b0a36db13c823ad21 # Radio transmitter body (Key to the Tower)
- 64e74a64aac4cd0a7264ecdf # item_quest_clock_12 (Out of Time)
- 661666458c2aa9cb1602503b # Hard drive
# - 64b91627dd13d43b9d01d6d1 # Toughbook reinforced laptop (Event quest) REMOVED BY BSG
- 67586bee39b1b82b0d0f9d06 # Special 40-degree fuel
rezervbase:
- 60915994c49cf53e4772cc38 # Military documents 1 on the table inside bunker control room (Documents)
- 60a3b6359c427533db36cf84 # Military documents 2 On the bottom shelf of the cupboard near the corner.
- 60a3b65c27adf161da7b6e14 # Military documents 3 Inside the cupboard next to the 4x4 Weapon Box.
- 608c22a003292f4ba43f8a1a # Medical record 1 (locked by RB-KSM key) (Disease history)
- 60a3b5b05f84d429b732e934 # Medical record 2 (locked by RB-SMP key) Disease history)
- 609267a2bb3f46069c3e6c7d # T-90M Commander Control Panel
- 60c080eb991ac167ad1c3ad4 # MBT Integrated Navigation System
- 6398a072e301557ae24cec92 # Original Lightkeeper Intelligence (Snatch)
- 64e74a4baac4cd0a7264ecdd # item_quest_clock_09 (Out of Time)
- 67499b3eeca8acb2d2061636 # Lightkeeper's case
- 67586bee39b1b82b0d0f9d06 # Special 40-degree fuel
- 67499b9b909d2013670a5029 # KOSA UAV electronic jamming device
laboratory:
- 5eff135be0d3331e9d282b7b # Flash drive marked with blue tape (TerraGroup employee)
- 6398a4cfb5992f573c6562b3 # Secured tape
- 64e74a44c2b4f829615ec334 # Picture 8
- 666879d498b97e3a8f09f1ae # Item_barter_medical_transilluminator_quest
- 6707cef3571b50abc703b64f # Infected blood sample (Halloween 2024)
- 6707cf827d279daad80fa95f # Vaccine sample IV (Halloween 2024)
- 6707cd70aab679420007e018 # TG-Vi-24 sample (Halloween 2024)
- 6707cc67cc1667e49e0f7232 # Infected blood sample (Halloween 2024)
#- 64e74a44c2b4f829615ec334 # item_quest_clock_08 (Out of Time) #1 REMOVED BY BSG
#- 64bdcfed8f3a947a990aa49a # Hermetic container for storing various chemicals #1 REMOVED BY BSG
#- 64bdd008b0bf3baa6702f35f # Hermetic container for storing various chemicals #2 REMOVED BY BSG
#- 64bdd014f3a668f08805ce64 # Hermetic container for storing various chemicals #3 REMOVED BY BSG
tarkovstreets:
- 63a943cead5cc12f22161ff7 # Accountant's notes (Audit)
- 638cbc68a63f1b49be6a3010 # Registered letter (Youve Got Mail)
- 638df4cc7b560b03794a18d2 # AG guitar pick (Audiophile)
- 638e0057ab150a5f56238960 # Housing office journal (Population Census)
- 63927b29c115f907b14700b9 # Chemical container with samples (Urban Medicine)
- 638dfc803083a019d447768e # Working hard drive (Surveillance)
- 638e9d5536b3b72c944e2fc7 # Flash drive with recordings (Watching You)
- 6393262086e646067c176aa2 # Medical observation record (?)
- 63989ced706b793c7d60cfef # Informant's journal (Missing Informant)
- 638cbb3ba63f1b49be6a300e # Secure Flash drive (Your Car Needs a Service)
- 63a39e1d234195315d4020bd # Primorsky 46-48 skybridge key
- 64e73909cd54ef0580746af3 # item_quest_clock_01 (Out of Time)
- 64e74a186393886f74114a96 # item_quest_clock_02 (Out of Time)
- 64e74a1faac4cd0a7264ecd9 # item_quest_clock_03 (Out of Time)
- 64e74a274d49d23b2c39d317 # item_quest_clock_04 (Out of Time)
- 64e74a2fc2b4f829615ec332 # item_quest_clock_05 (Out of Time)
- 64e74a35aac4cd0a7264ecdb # item_quest_clock_06 (Out of Time)
- 64f09c02b63b74469b6c149f # Paramedic's GPhone X (Ambulances Again)
- 64f07f7726cfa02c506f8ac0 # Journal item_quest_kpss2 (Glory To CPSU P2)
- 64f69b4267e11a7c6206e010 # Chef's diary (Beyond the Red Meat - Part 1)
- 64f5b4f71a5f313cb144c06c # Secret component (Beyond the Red Meat - Part 2)
- 657acb2ac900be5902191ac9 # Cadastral registry records
- 66687bc89111279d600b5062 # keyFromCity_quest
sandbox:
- 6582bd252b50c61c565828e2 # Bottle of Le Jean wine
- 6575a6ca8778e96ded05a802 # TerraGroup scientist's hard drive
sandbox_high:
- 6582bd252b50c61c565828e2 # Bottle of Le Jean wine
- 6575a6ca8778e96ded05a802 # TerraGroup scientist's hard drive

View File

@ -1,26 +0,0 @@
---
static_weapon_ids:
# ids for static weapons
- 5d52cc5ba4b9367408500062
- 5cdeb229d7f00c000e7ce174
forced_items:
bigmap:
- containerId: container_custom_DesignStuff_00060 # unknown key
itemTpl: 593962ca86f774068014d9af
tarkovstreets:
- containerId: container_City_SE_02_DesignStuff_00091 # Backup hideout key
itemTpl: 6398fd8ad3de3849057f5128
sandbox:
- containerId: container_Test_for_export_00002 # Lab technician body
itemTpl: 658199aa38c79576a2569e13 # TerraGroup science office key
- containerId: container_Sandbox_Design_Stuff_00008 # dead body of scav near exit
itemTpl: 6217726288ed9f0845317459 # RSP-30 reactive signal cartridge (Green)
sandbox_high:
- containerId: container_Test_for_export_00002 # Lab technician body
itemTpl: 658199aa38c79576a2569e13 # TerraGroup science office key
- containerId: container_Sandbox_Design_Stuff_00008 # dead body of scav near exit
itemTpl: 6217726288ed9f0845317459 # RSP-30 reactive signal cartridge (Green)

View File

@ -1,9 +0,0 @@
namespace LootDumpProcessor.Logger;
public interface ILogger
{
void Setup();
void Log(string message, LogLevel level);
bool CanBeLogged(LogLevel level);
void Stop();
}

View File

@ -1,9 +0,0 @@
namespace LootDumpProcessor.Logger;
public enum LogLevel
{
Error,
Warning,
Info,
Debug
}

View File

@ -1,14 +0,0 @@
namespace LootDumpProcessor.Logger;
public static class LoggerFactory
{
private static ILogger? _logger;
public static ILogger GetInstance()
{
if (_logger == null)
_logger = new QueueLogger();
// TODO: implement factory
return _logger;
}
}

View File

@ -1,109 +0,0 @@
using System.Collections.Concurrent;
namespace LootDumpProcessor.Logger;
public class QueueLogger : ILogger
{
private readonly BlockingCollection<LoggedMessage> queuedMessages = new();
private Task? loggerThread;
private bool isRunning;
private int logLevel;
private const int LogTerminationTimeoutMs = 1000;
private const int LogTerminationRetryCount = 3;
public void Setup()
{
SetLogLevel();
isRunning = true;
loggerThread = Task.Factory.StartNew(() =>
{
while (isRunning)
{
while (queuedMessages.TryTake(out var value))
{
Console.ResetColor();
switch (value.LogLevel)
{
case LogLevel.Error:
Console.BackgroundColor = ConsoleColor.Red;
Console.ForegroundColor = ConsoleColor.Black;
break;
case LogLevel.Warning:
Console.BackgroundColor = ConsoleColor.Yellow;
Console.ForegroundColor = ConsoleColor.Black;
break;
case LogLevel.Debug:
Console.ForegroundColor = ConsoleColor.DarkCyan;
break;
case LogLevel.Info:
default:
break;
}
Console.WriteLine(value.Message);
}
Thread.Sleep(
TimeSpan.FromMilliseconds(LootDumpProcessorContext.GetConfig().LoggerConfig.QueueLoggerPoolingTimeoutMs));
}
}, TaskCreationOptions.LongRunning);
}
private void SetLogLevel()
{
logLevel = GetLogLevel(LootDumpProcessorContext.GetConfig().LoggerConfig.LogLevel);
}
private int GetLogLevel(LogLevel level)
{
return level switch
{
LogLevel.Error => 1,
LogLevel.Warning => 2,
LogLevel.Info => 3,
LogLevel.Debug => 4,
_ => throw new ArgumentOutOfRangeException()
};
}
public void Log(string message, LogLevel level)
{
if (GetLogLevel(level) <= logLevel)
queuedMessages.Add(new LoggedMessage { Message = message, LogLevel = level });
}
public bool CanBeLogged(LogLevel level)
{
return GetLogLevel(level) <= logLevel;
}
// Wait for graceful termination of the logging thread
public void Stop()
{
isRunning = false;
if (loggerThread != null)
{
Console.ResetColor();
var retryCount = 0;
while (!loggerThread.IsCompleted)
{
if (retryCount == LogTerminationRetryCount)
{
Console.WriteLine(
$"Logger thread did not terminate by itself after {retryCount} retries. Some log messages may be lost.");
break;
}
Console.WriteLine($"Waiting {LogTerminationTimeoutMs}ms for logger termination");
Thread.Sleep(LogTerminationTimeoutMs);
retryCount++;
}
}
}
private class LoggedMessage
{
public string Message { get; init; }
public LogLevel LogLevel { get; init; }
}
}

View File

@ -1,34 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<ServerGarbageCollection>true</ServerGarbageCollection>
<GarbageCollectionAdaptationMode>1</GarbageCollectionAdaptationMode>
<ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="7z.Libs" Version="21.7.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="NumSharp" Version="0.30.0" />
<PackageReference Include="SevenZipSharp.Interop" Version="19.1.0" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0" />
<PackageReference Include="YamlDotNet" Version="13.0.0" />
</ItemGroup>
<ItemGroup>
<None Update="Config\forced_loose.yaml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Config\forced_static.yaml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Config\config.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.4.33213.308
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LootDumpProcessor", "LootDumpProcessor.csproj", "{887819E1-72BF-4F10-9246-77D8088AC7D2}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LootDumpProcessor", "source/LootDumpProcessor/LootDumpProcessor.csproj", "{887819E1-72BF-4F10-9246-77D8088AC7D2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "source", "source", "{2B18E894-D839-4002-8B9A-6CF8A331596F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -22,4 +24,7 @@ Global
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {39C0A9FF-B0F5-4C3F-AAA7-F9E9225AE70F}
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{887819E1-72BF-4F10-9246-77D8088AC7D2} = {2B18E894-D839-4002-8B9A-6CF8A331596F}
EndGlobalSection
EndGlobal

View File

@ -1,42 +0,0 @@
using System.Text.Json.Serialization;
using LootDumpProcessor.Model.Processing;
using LootDumpProcessor.Utils;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model;
public class ComposedKey
{
[JsonProperty("key")]
[JsonPropertyName("key")]
public string Key { get; init; }
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
public Item? FirstItem { get; }
public ComposedKey(Template template) : this(template.Items)
{
}
public ComposedKey(List<Item>? items)
{
Key = items?.Select(i => i.Tpl)
.Where(i => !string.IsNullOrEmpty(i) &&
!LootDumpProcessorContext.GetTarkovItems().IsBaseClass(i, BaseClasses.Ammo))
.Cast<string>()
.Select(i => (double)i.GetHashCode())
.Sum()
.ToString() ?? KeyGenerator.GetNextKey();
FirstItem = items?[0];
}
public override bool Equals(object? obj)
{
if (obj is not ComposedKey key)
return false;
return Key == key.Key;
}
public override int GetHashCode() => Key.GetHashCode();
}

View File

@ -1,20 +0,0 @@
using System.Text.Json.Serialization;
using LootDumpProcessor.Process.Collector;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Config;
public class CollectorConfig
{
[JsonProperty("collectorType")]
[JsonPropertyName("collectorType")]
public CollectorType CollectorType { get; set; }
[JsonProperty("maxEntitiesBeforeDumping")]
[JsonPropertyName("maxEntitiesBeforeDumping")]
public int MaxEntitiesBeforeDumping { get; set; }
[JsonProperty("dumpLocation")]
[JsonPropertyName("dumpLocation")]
public string DumpLocation { get; set; }
}

View File

@ -1,64 +0,0 @@
using System.Text.Json.Serialization;
using LootDumpProcessor.Serializers.Json;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Config;
public class Config
{
[JsonProperty("serverLocation")]
[JsonPropertyName("serverLocation")]
public string? ServerLocation { get; set; }
[JsonProperty("threads")]
[JsonPropertyName("threads")]
public int Threads { get; set; } = 6;
[JsonProperty("threadPoolingTimeoutMs")]
[JsonPropertyName("threadPoolingTimeoutMs")]
public int ThreadPoolingTimeoutMs { get; set; } = 1000;
[JsonProperty("jsonSerializer")]
[JsonPropertyName("jsonSerializer")]
public JsonSerializerTypes JsonSerializer { get; set; } = JsonSerializerTypes.DotNet;
[JsonProperty("manualGarbageCollectionCalls")]
[JsonPropertyName("manualGarbageCollectionCalls")]
public bool ManualGarbageCollectionCalls { get; set; }
[JsonProperty("dataStorageConfig")]
[JsonPropertyName("dataStorageConfig")]
public DataStorageConfig DataStorageConfig { get; set; }
[JsonProperty("loggerConfig")]
[JsonPropertyName("loggerConfig")]
public LoggerConfig LoggerConfig { get; set; }
[JsonProperty("readerConfig")]
[JsonPropertyName("readerConfig")]
public ReaderConfig ReaderConfig { get; set; }
[JsonProperty("processorConfig")]
[JsonPropertyName("processorConfig")]
public ProcessorConfig ProcessorConfig { get; set; }
[JsonProperty("dumpProcessorConfig")]
[JsonPropertyName("dumpProcessorConfig")]
public DumpProcessorConfig DumpProcessorConfig { get; set; }
[JsonProperty("writerConfig")]
[JsonPropertyName("writerConfig")]
public WriterConfig WriterConfig { get; set; }
[JsonProperty("collectorConfig")]
[JsonPropertyName("collectorConfig")]
public CollectorConfig CollectorConfig { get; set; }
[JsonProperty("containerIgnoreList")]
[JsonPropertyName("containerIgnoreList")]
public Dictionary<string, string[]> ContainerIgnoreList { get; set; }
[JsonProperty("mapsToProcess")]
[JsonPropertyName("mapsToProcess")]
public List<string> MapsToProcess { get; set; }
}

View File

@ -1,14 +0,0 @@
using System.Text.Json.Serialization;
using LootDumpProcessor.Serializers.Json.Converters;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Config;
public class DumpProcessorConfig
{
[JsonProperty("spawnContainerChanceIncludeAfterDate")]
[JsonPropertyName("spawnContainerChanceIncludeAfterDate")]
[Newtonsoft.Json.JsonConverter(typeof(NewtonsoftDateTimeConverter))]
[System.Text.Json.Serialization.JsonConverter(typeof(NetDateTimeConverter))]
public DateTime SpawnContainerChanceIncludeAfterDate { get; set; }
}

View File

@ -1,22 +0,0 @@
using System.Text.Json.Serialization;
using LootDumpProcessor.Process.Reader;
using LootDumpProcessor.Process.Reader.Intake;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Config;
public class IntakeReaderConfig
{
[JsonProperty("readerType")]
[JsonPropertyName("readerType")]
public IntakeReaderTypes IntakeReaderType { get; set; } = IntakeReaderTypes.Json;
[JsonProperty("maxDumpsPerMap")]
[JsonPropertyName("maxDumpsPerMap")]
public int MaxDumpsPerMap { get; set; } = 1500;
[JsonProperty("ignoredDumpLocations")]
[JsonPropertyName("ignoredDumpLocations")]
public List<string> IgnoredDumpLocations { get; set; } = new();
}

View File

@ -1,16 +0,0 @@
using System.Text.Json.Serialization;
using LootDumpProcessor.Logger;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Config;
public class LoggerConfig
{
[JsonProperty("logLevel")]
[JsonPropertyName("logLevel")]
public LogLevel LogLevel { get; set; } = LogLevel.Info;
[JsonProperty("queueLoggerPoolingTimeoutMs")]
[JsonPropertyName("queueLoggerPoolingTimeoutMs")]
public int QueueLoggerPoolingTimeoutMs { get; set; } = 1000;
}

View File

@ -1,11 +0,0 @@
using YamlDotNet.Serialization;
namespace LootDumpProcessor.Model.Config;
public class MapDirectoryMapping
{
[YamlMember(Alias = "name")]
public List<string> Name { get; set; }
[YamlMember(Alias = "threshold_date")]
public string ThresholdDate { get; set; }
}

View File

@ -1,20 +0,0 @@
using System.Text.Json.Serialization;
using LootDumpProcessor.Process.Reader.PreProcess;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Config;
public class PreProcessorConfig
{
[JsonProperty("preProcessors")]
[JsonPropertyName("preProcessors")]
public List<PreProcessReaderTypes>? PreProcessors { get; set; }
[JsonProperty("preProcessorTempFolder")]
[JsonPropertyName("preProcessorTempFolder")]
public string? PreProcessorTempFolder { get; set; }
[JsonProperty("cleanupTempFolderAfterProcess")]
[JsonPropertyName("cleanupTempFolderAfterProcess")]
public bool CleanupTempFolderAfterProcess { get; set; } = true;
}

View File

@ -1,15 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Config;
public class ProcessorConfig
{
[JsonProperty("spawnPointToleranceForForced")]
[JsonPropertyName("spawnPointToleranceForForced")]
public double SpawnPointToleranceForForced { get; set; } = 99D;
[JsonProperty("looseLootCountTolerancePercentage")]
[JsonPropertyName("looseLootCountTolerancePercentage")]
public double LooseLootCountTolerancePercentage { get; set; } = 75D;
}

View File

@ -1,36 +0,0 @@
using System.Text.Json.Serialization;
using LootDumpProcessor.Process.Reader.Filters;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Config;
public class ReaderConfig
{
[JsonProperty("intakeReaderConfig")]
[JsonPropertyName("intakeReaderConfig")]
public IntakeReaderConfig? IntakeReaderConfig { get; set; }
[JsonProperty("preProcessorConfig")]
[JsonPropertyName("preProcessorConfig")]
public PreProcessorConfig? PreProcessorConfig { get; set; }
[JsonProperty("dumpFilesLocation")]
[JsonPropertyName("dumpFilesLocation")]
public List<string>? DumpFilesLocation { get; set; }
[JsonProperty("thresholdDate")]
[JsonPropertyName("thresholdDate")]
public string? ThresholdDate { get; set; }
[JsonProperty("acceptedFileExtensions")]
[JsonPropertyName("acceptedFileExtensions")]
public List<string> AcceptedFileExtensions { get; set; } = new();
[JsonProperty("processSubFolders")]
[JsonPropertyName("processSubFolders")]
public bool ProcessSubFolders { get; set; }
[JsonProperty("fileFilters")]
[JsonPropertyName("fileFilters")]
public List<FileFilterTypes>? FileFilters { get; set; }
}

View File

@ -1,11 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Config;
public class WriterConfig
{
[JsonProperty("outputLocation")]
[JsonPropertyName("outputLocation")]
public string? OutputLocation { get; set; }
}

View File

@ -1,20 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model
{
public class FireMode : ICloneable
{
[JsonProperty("FireMode", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("FireMode")]
public string? FireModeType { get; set; }
public object Clone()
{
return new FireMode
{
FireModeType = FireModeType
};
}
}
}

View File

@ -1,20 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model
{
public class Foldable : ICloneable
{
[JsonProperty("Folded", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Folded")]
public bool? Folded { get; set; }
public object Clone()
{
return new Foldable
{
Folded = Folded
};
}
}
}

View File

@ -1,36 +0,0 @@
using System.Text.Json.Serialization;
using LootDumpProcessor.Utils;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model
{
public class GroupPosition : ICloneable
{
[JsonProperty("Name", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Name")]
public string? Name { get; set; }
[JsonProperty("Weight", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Weight")]
public int? Weight { get; set; }
[JsonProperty("Position", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Position")]
public Vector3? Position { get; set; }
[JsonProperty("Rotation", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Rotation")]
public Vector3? Rotation { get; set; }
public object Clone()
{
return new GroupPosition
{
Name = Name,
Weight = Weight,
Position = ProcessorUtil.Copy(Position),
Rotation = ProcessorUtil.Copy(Rotation)
};
}
}
}

View File

@ -1,52 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class AdditionalHostilitySetting
{
[JsonProperty("BotRole", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotRole")]
public string? BotRole { get; set; }
[JsonProperty("AlwaysEnemies", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("AlwaysEnemies")]
public List<string>? AlwaysEnemies { get; set; }
[JsonProperty("ChancedEnemies", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("ChancedEnemies")]
public List<ChancedEnemy>? ChancedEnemies { get; set; }
[JsonProperty("Warn", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Warn")]
public List<string>? Warn { get; set; }
[JsonProperty("Neutral", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Neutral")]
public List<string>? Neutral { get; set; }
[JsonProperty("AlwaysFriends", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("AlwaysFriends")]
public List<string>? AlwaysFriends { get; set; }
[JsonProperty("SavagePlayerBehaviour", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("SavagePlayerBehaviour")]
public string? SavagePlayerBehaviour { get; set; }
[JsonProperty("BearPlayerBehaviour", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BearPlayerBehaviour")]
public string? BearPlayerBehaviour { get; set; }
[JsonProperty("BearEnemyChance", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BearEnemyChance")]
public int? BearEnemyChance { get; set; }
[JsonProperty("UsecPlayerBehaviour", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("UsecPlayerBehaviour")]
public string? UsecPlayerBehaviour { get; set; }
[JsonProperty("UsecEnemyChance", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("UsecEnemyChance")]
public int? UsecEnemyChance { get; set; }
}
}

View File

@ -1,48 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class AirdropParameter
{
[JsonProperty("PlaneAirdropStartMin", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("PlaneAirdropStartMin")]
public int? PlaneAirdropStartMin { get; set; }
[JsonProperty("PlaneAirdropStartMax", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("PlaneAirdropStartMax")]
public int? PlaneAirdropStartMax { get; set; }
[JsonProperty("PlaneAirdropEnd", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("PlaneAirdropEnd")]
public int? PlaneAirdropEnd { get; set; }
[JsonProperty("PlaneAirdropChance", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("PlaneAirdropChance")]
public float? PlaneAirdropChance { get; set; }
[JsonProperty("PlaneAirdropMax", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("PlaneAirdropMax")]
public int? PlaneAirdropMax { get; set; }
[JsonProperty("PlaneAirdropCooldownMin", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("PlaneAirdropCooldownMin")]
public int? PlaneAirdropCooldownMin { get; set; }
[JsonProperty("PlaneAirdropCooldownMax", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("PlaneAirdropCooldownMax")]
public int? PlaneAirdropCooldownMax { get; set; }
[JsonProperty("AirdropPointDeactivateDistance", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("AirdropPointDeactivateDistance")]
public int? AirdropPointDeactivateDistance { get; set; }
[JsonProperty("MinPlayersCountToSpawnAirdrop", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MinPlayersCountToSpawnAirdrop")]
public int? MinPlayersCountToSpawnAirdrop { get; set; }
[JsonProperty("UnsuccessfulTryPenalty", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("UnsuccessfulTryPenalty")]
public int? UnsuccessfulTryPenalty { get; set; }
}
}

View File

@ -1,68 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class BTRServerSettings
{
[JsonProperty("ChanceSpawn", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("ChanceSpawn")]
public float? ChanceSpawn { get; set; }
[JsonProperty("SpawnPeriod", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("SpawnPeriod")]
public Vector3? SpawnPeriod { get; set; }
[JsonProperty("MoveSpeed", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MoveSpeed")]
public float? MoveSpeed { get; set; }
[JsonProperty("ReadyToDepartureTime", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("ReadyToDepartureTime")]
public float? ReadyToDepartureTime { get; set; }
[JsonProperty("CheckTurnDistanceTime", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("CheckTurnDistanceTime")]
public float? CheckTurnDistanceTime { get; set; }
[JsonProperty("TurnCheckSensitivity", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("TurnCheckSensitivity")]
public float? TurnCheckSensitivity { get; set; }
[JsonProperty("DecreaseSpeedOnTurnLimit", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("DecreaseSpeedOnTurnLimit")]
public float? DecreaseSpeedOnTurnLimit { get; set; }
[JsonProperty("EndSplineDecelerationDistance", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("EndSplineDecelerationDistance")]
public float? EndSplineDecelerationDistance { get; set; }
[JsonProperty("AccelerationSpeed", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("AccelerationSpeed")]
public float? AccelerationSpeed { get; set; }
[JsonProperty("DecelerationSpeed", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("DecelerationSpeed")]
public float? DecelerationSpeed { get; set; }
[JsonProperty("PauseDurationRange", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("PauseDurationRange")]
public Vector3? PauseDurationRange { get; set; }
[JsonProperty("BodySwingReturnSpeed", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BodySwingReturnSpeed")]
public float? BodySwingReturnSpeed { get; set; }
[JsonProperty("BodySwingDamping", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BodySwingDamping")]
public float? BodySwingDamping { get; set; }
[JsonProperty("BodySwingIntensity", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BodySwingIntensity")]
public float? BodySwingIntensity { get; set; }
[JsonProperty("ServerMapBTRSettings", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("ServerMapBTRSettings")]
public ServerMapBTRSettings? ServerMapBTRSettings { get; set; }
}
}

View File

@ -1,16 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class Banner
{
[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonProperty("pic", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("pic")]
public Pic? Pic { get; set; }
}
}

View File

@ -1,64 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class BotLocationModifier
{
[JsonProperty("AccuracySpeed", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("AccuracySpeed")]
public float? AccuracySpeed { get; set; }
[JsonProperty("Scattering", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Scattering")]
public float? Scattering { get; set; }
[JsonProperty("GainSight", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("GainSight")]
public float? GainSight { get; set; }
[JsonProperty("MarksmanAccuratyCoef", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MarksmanAccuratyCoef")]
public float? MarksmanAccuratyCoef { get; set; }
[JsonProperty("VisibleDistance", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("VisibleDistance")]
public float? VisibleDistance { get; set; }
[JsonProperty("DistToPersueAxemanCoef", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("DistToPersueAxemanCoef")]
public float? DistToPersueAxemanCoef { get; set; }
[JsonProperty("KhorovodChance", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("KhorovodChance")]
public int? KhorovodChance { get; set; }
[JsonProperty("MinExfiltrationTime", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MinExfiltrationTime")]
public float? MinExfiltrationTime { get; set; }
[JsonProperty("MaxExfiltrationTime", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MaxExfiltrationTime")]
public float? MaxExfiltrationTime { get; set; }
[JsonProperty("DistToActivatePvE", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("DistToActivatePvE")]
public float? DistToActivatePvE { get; set; }
[JsonProperty("DistToSleepPvE", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("DistToSleepPvE")]
public float? DistToSleepPvE { get; set; }
[JsonProperty("DistToActivate", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("DistToActivate")]
public float? DistToActivate { get; set; }
[JsonProperty("DistToSleep", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("DistToSleep")]
public float? DistToSleep { get; set; }
[JsonProperty("AdditionalHostilitySettings", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("AdditionalHostilitySettings")]
public List<AdditionalHostilitySetting>? AdditionalHostilitySettings { get; set; }
}
}

View File

@ -1,16 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class ChancedEnemy
{
[JsonProperty("EnemyChance", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("EnemyChance")]
public int? EnemyChance { get; set; }
[JsonProperty("Role", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Role")]
public string? Role { get; set; }
}
}

View File

@ -1,17 +0,0 @@
using System.Text.Json.Serialization;
using LootDumpProcessor.Model.Tarkov;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class ColliderParams
{
[JsonProperty("Parent", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Parent")]
public string? Parent { get; set; }
[JsonProperty("_props", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("_props")]
public Props? Props { get; set; }
}
}

View File

@ -1,12 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class CompletedQuest
{
[JsonProperty("QuestId", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("QuestId")]
public string? QuestID { get; set; }
}
}

View File

@ -1,24 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class Data
{
[JsonProperty("serverId", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("serverId")]
public string? ServerID { get; set; }
[JsonProperty("serverSettings", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("serverSettings")]
public ServerSettings? ServerSettings { get; set; }
[JsonProperty("profile", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("profile")]
public object? Profile { get; set; }
[JsonProperty("locationLoot", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("locationLoot")]
public required LocationLoot LocationLoot { get; set; }
}
}

View File

@ -1,88 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class Exit
{
[JsonProperty("Name", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Name")]
public string? Name { get; set; }
[JsonProperty("EntryPoints", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("EntryPoints")]
public string? EntryPoints { get; set; }
[JsonProperty("Chance", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Chance")]
public float? Chance { get; set; }
[JsonProperty("MinTime", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MinTime")]
public int? MinTime { get; set; }
[JsonProperty("MaxTime", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MaxTime")]
public int? MaxTime { get; set; }
[JsonProperty("PlayersCount", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("PlayersCount")]
public int? PlayersCount { get; set; }
[JsonProperty("ExfiltrationTime", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("ExfiltrationTime")]
public float? ExfiltrationTime { get; set; }
[JsonProperty("PassageRequirement", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("PassageRequirement")]
public string? PassageRequirement { get; set; }
[JsonProperty("ExfiltrationType", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("ExfiltrationType")]
public string? ExfiltrationType { get; set; }
[JsonProperty("RequiredSlot", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("RequiredSlot")]
public string? RequiredSlot { get; set; }
[JsonProperty("Id", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Id")]
public string? Id { get; set; }
[JsonProperty("RequirementTip", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("RequirementTip")]
public string? RequirementTip { get; set; }
[JsonProperty("Count", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Count")]
public int? Count { get; set; }
[JsonProperty("EventAvailable", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("EventAvailable")]
public bool? EventAvailable { get; set; }
[JsonProperty("MinTimePVE", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MinTimePVE")]
public int? MinTimePVE { get; set; }
[JsonProperty("MaxTimePVE", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MaxTimePVE")]
public int? MaxTimePVE { get; set; }
[JsonProperty("ChancePVE", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("ChancePVE")]
public float? ChancePVE { get; set; }
[JsonProperty("CountPVE", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("CountPVE")]
public int? CountPVE { get; set; }
[JsonProperty("ExfiltrationTimePVE", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("ExfiltrationTimePVE")]
public float? ExfiltrationTimePVE { get; set; }
[JsonProperty("PlayersCountPVE", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("PlayersCountPVE")]
public int? PlayersCountPVE { get; set; }
}
}

View File

@ -1,12 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class ItemCost
{
[JsonProperty("Count", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Count")]
public int? Count { get; set; }
}
}

View File

@ -1,384 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class LocationLoot
{
[JsonProperty("Enabled", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Enabled")]
public bool? Enabled { get; set; }
[JsonProperty("EnableCoop", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("EnableCoop")]
public bool? EnableCoop { get; set; }
[JsonProperty("ForceOnlineRaidInPVE", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("ForceOnlineRaidInPVE")]
public bool? ForceOnlineRaidInPVE { get; set; }
[JsonProperty("Locked", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Locked")]
public bool? Locked { get; set; }
[JsonProperty("Insurance", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Insurance")]
public bool? Insurance { get; set; }
[JsonProperty("SafeLocation", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("SafeLocation")]
public bool? SafeLocation { get; set; }
[JsonProperty("Name", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Name")]
public string? Name { get; set; }
[JsonProperty("Description", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Description")]
public string? Description { get; set; }
[JsonProperty("Scene", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Scene")]
public Scene? Scene { get; set; }
[JsonProperty("Area", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Area")]
public float? Area { get; set; }
[JsonProperty("RequiredPlayerLevelMin", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("RequiredPlayerLevelMin")]
public int? RequiredPlayerLevelMin { get; set; }
[JsonProperty("RequiredPlayerLevelMax", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("RequiredPlayerLevelMax")]
public int? RequiredPlayerLevelMax { get; set; }
[JsonProperty("PmcMaxPlayersInGroup", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("PmcMaxPlayersInGroup")]
public int? PmcMaxPlayersInGroup { get; set; }
[JsonProperty("ScavMaxPlayersInGroup", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("ScavMaxPlayersInGroup")]
public int? ScavMaxPlayersInGroup { get; set; }
[JsonProperty("MinPlayers", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MinPlayers")]
public int? MinPlayers { get; set; }
[JsonProperty("MaxPlayers", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MaxPlayers")]
public int? MaxPlayers { get; set; }
[JsonProperty("MaxCoopGroup", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MaxCoopGroup")]
public int? MaxCoopGroup { get; set; }
[JsonProperty("exit_count", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("exit_count")]
public int? ExitCount { get; set; }
[JsonProperty("exit_access_time", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("exit_access_time")]
public int? ExitAccessTime { get; set; }
[JsonProperty("exit_time", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("exit_time")]
public int? ExitTime { get; set; }
[JsonProperty("Preview", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Preview")]
public Preview? Preview { get; set; }
[JsonProperty("IconX", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("IconX")]
public int? IconX { get; set; }
[JsonProperty("IconY", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("IconY")]
public int? IconY { get; set; }
[JsonProperty("filter_ex", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("filter_ex")]
public List<object>? FilterEx { get; set; }
[JsonProperty("waves", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("waves")]
public List<object>? Waves { get; set; }
[JsonProperty("limits", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("limits")]
public List<object>? Limits { get; set; }
[JsonProperty("AveragePlayTime", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("AveragePlayTime")]
public int? AveragePlayTime { get; set; }
[JsonProperty("AveragePlayerLevel", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("AveragePlayerLevel")]
public int? AveragePlayerLevel { get; set; }
[JsonProperty("EscapeTimeLimit", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("EscapeTimeLimit")]
public int? EscapeTimeLimit { get; set; }
[JsonProperty("EscapeTimeLimitPVE", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("EscapeTimeLimitPVE")]
public int? EscapeTimeLimitPVE { get; set; }
[JsonProperty("EscapeTimeLimitCoop", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("EscapeTimeLimitCoop")]
public int? EscapeTimeLimitCoop { get; set; }
[JsonProperty("Rules", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Rules")]
public string? Rules { get; set; }
[JsonProperty("IsSecret", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("IsSecret")]
public bool? IsSecret { get; set; }
[JsonProperty("doors", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("doors")]
public List<object>? Doors { get; set; }
[JsonProperty("tmp_location_field_remove_me", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("tmp_location_field_remove_me")]
public int? TmpLocationFieldRemoveMe { get; set; }
[JsonProperty("MinDistToExitPoint", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MinDistToExitPoint")]
public int? MinDistToExitPoint { get; set; }
[JsonProperty("MaxDistToFreePoint", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MaxDistToFreePoint")]
public int? MaxDistToFreePoint { get; set; }
[JsonProperty("MinDistToFreePoint", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MinDistToFreePoint")]
public int? MinDistToFreePoint { get; set; }
[JsonProperty("MaxBotPerZone", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MaxBotPerZone")]
public int? MaxBotPerZone { get; set; }
[JsonProperty("OpenZones", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("OpenZones")]
public string? OpenZones { get; set; }
[JsonProperty("OcculsionCullingEnabled", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("OcculsionCullingEnabled")]
public bool? OcculsionCullingEnabled { get; set; }
[JsonProperty("GlobalLootChanceModifier", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("GlobalLootChanceModifier")]
public float? GlobalLootChanceModifier { get; set; }
[JsonProperty("GlobalLootChanceModifierPvE", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("GlobalLootChanceModifierPvE")]
public float? GlobalLootChanceModifierPvE { get; set; }
[JsonProperty("OldSpawn", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("OldSpawn")]
public bool? OldSpawn { get; set; }
[JsonProperty("OfflineOldSpawn", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("OfflineOldSpawn")]
public bool? OfflineOldSpawn { get; set; }
[JsonProperty("NewSpawn", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("NewSpawn")]
public bool? NewSpawn { get; set; }
[JsonProperty("OfflineNewSpawn", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("OfflineNewSpawn")]
public bool? OfflineNewSpawn { get; set; }
[JsonProperty("BotMax", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotMax")]
public int? BotMax { get; set; }
[JsonProperty("BotMaxPvE", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotMaxPvE")]
public int? BotMaxPvE { get; set; }
[JsonProperty("BotStart", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotStart")]
public int? BotStart { get; set; }
[JsonProperty("BotStartPlayer", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotStartPlayer")]
public int? BotStartPlayer { get; set; }
[JsonProperty("BotStop", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotStop")]
public int? BotStop { get; set; }
[JsonProperty("BotMaxTimePlayer", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotMaxTimePlayer")]
public int? BotMaxTimePlayer { get; set; }
[JsonProperty("BotSpawnTimeOnMin", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotSpawnTimeOnMin")]
public int? BotSpawnTimeOnMin { get; set; }
[JsonProperty("BotSpawnTimeOnMax", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotSpawnTimeOnMax")]
public int? BotSpawnTimeOnMax { get; set; }
[JsonProperty("BotSpawnTimeOffMin", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotSpawnTimeOffMin")]
public int? BotSpawnTimeOffMin { get; set; }
[JsonProperty("BotSpawnTimeOffMax", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotSpawnTimeOffMax")]
public int? BotSpawnTimeOffMax { get; set; }
[JsonProperty("BotMaxPlayer", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotMaxPlayer")]
public int? BotMaxPlayer { get; set; }
[JsonProperty("BotEasy", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotEasy")]
public int? BotEasy { get; set; }
[JsonProperty("BotNormal", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotNormal")]
public int? BotNormal { get; set; }
[JsonProperty("BotHard", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotHard")]
public int? BotHard { get; set; }
[JsonProperty("BotImpossible", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotImpossible")]
public int? BotImpossible { get; set; }
[JsonProperty("BotAssault", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotAssault")]
public int? BotAssault { get; set; }
[JsonProperty("BotMarksman", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotMarksman")]
public int? BotMarksman { get; set; }
[JsonProperty("DisabledScavExits", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("DisabledScavExits")]
public string? DisabledScavExits { get; set; }
[JsonProperty("MinPlayerLvlAccessKeys", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MinPlayerLvlAccessKeys")]
public int? MinPlayerLvlAccessKeys { get; set; }
[JsonProperty("AccessKeys", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("AccessKeys")]
public List<object>? AccessKeys { get; set; }
[JsonProperty("UnixDateTime", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("UnixDateTime")]
public int? UnixDateTime { get; set; }
[JsonProperty("users_gather_seconds", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("users_gather_seconds")]
public int? UsersGatherSeconds { get; set; }
[JsonProperty("users_spawn_seconds_n", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("users_spawn_seconds_n")]
public int? UsersSpawnSecondsN { get; set; }
[JsonProperty("users_spawn_seconds_n2", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("users_spawn_seconds_n2")]
public int? UsersSpawnSecondsN2 { get; set; }
[JsonProperty("users_summon_seconds", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("users_summon_seconds")]
public int? UsersSummonSeconds { get; set; }
[JsonProperty("sav_summon_seconds", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("sav_summon_seconds")]
public int? SavSummonSeconds { get; set; }
[JsonProperty("matching_min_seconds", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("matching_min_seconds")]
public int? MatchingMinSeconds { get; set; }
[JsonProperty("GenerateLocalLootCache", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("GenerateLocalLootCache")]
public bool? GenerateLocalLootCache { get; set; }
[JsonProperty("PlayersRequestCount", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("PlayersRequestCount")]
public int? PlayersRequestCount { get; set; }
[JsonProperty("NonWaveGroupScenario", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("NonWaveGroupScenario")]
public NonWaveGroupScenario? NonWaveGroupScenario { get; set; }
[JsonProperty("BotSpawnCountStep", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotSpawnCountStep")]
public int? BotSpawnCountStep { get; set; }
[JsonProperty("BotSpawnPeriodCheck", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotSpawnPeriodCheck")]
public int? BotSpawnPeriodCheck { get; set; }
[JsonProperty("GlobalContainerChanceModifier", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("GlobalContainerChanceModifier")]
public float? GlobalContainerChanceModifier { get; set; }
[JsonProperty("MinMaxBots", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MinMaxBots")]
public List<object>? MinMaxBots { get; set; }
[JsonProperty("BotLocationModifier", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotLocationModifier")]
public BotLocationModifier? BotLocationModifier { get; set; }
[JsonProperty("Exits", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Exits")]
public List<Exit>? Exits { get; set; }
[JsonProperty("DisabledForScav", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("DisabledForScav")]
public bool? DisabledForScav { get; set; }
[JsonProperty("BossLocationSpawn", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BossLocationSpawn")]
public List<object>? BossLocationSpawn { get; set; }
[JsonProperty("SpawnPointParams", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("SpawnPointParams")]
public List<SpawnPointParam>? SpawnPointParams { get; set; }
[JsonProperty("MaxItemCountInLocation", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MaxItemCountInLocation")]
public List<object>? MaxItemCountInLocation { get; set; }
[JsonProperty("AirdropParameters", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("AirdropParameters")]
public List<AirdropParameter>? AirdropParameters { get; set; }
[JsonProperty("MatchMakerMinPlayersByWaitTime", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MatchMakerMinPlayersByWaitTime")]
public List<MatchMakerMinPlayersByWaitTime>? MatchMakerMinPlayersByWaitTime { get; set; }
[JsonProperty("Transits", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Transits")]
public List<Transit>? Transits { get; set; }
[JsonProperty("Id", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Id")]
public required string Id { get; set; }
[JsonProperty("_Id", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("_Id")]
public string? Id0 { get; set; }
[JsonProperty("Loot")]
[JsonPropertyName("Loot")]
public required List<Template> Loot { get; set; }
[JsonProperty("Banners", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Banners")]
public List<Banner>? Banners { get; set; }
}
}

View File

@ -1,68 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class MapSettings
{
[JsonProperty("MapID", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MapID")]
public string? MapID { get; set; }
[JsonProperty("ChanceSpawn", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("ChanceSpawn")]
public float? ChanceSpawn { get; set; }
[JsonProperty("SpawnPeriod", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("SpawnPeriod")]
public Vector3? SpawnPeriod { get; set; }
[JsonProperty("MoveSpeed", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MoveSpeed")]
public float? MoveSpeed { get; set; }
[JsonProperty("ReadyToDepartureTime", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("ReadyToDepartureTime")]
public float? ReadyToDepartureTime { get; set; }
[JsonProperty("CheckTurnDistanceTime", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("CheckTurnDistanceTime")]
public float? CheckTurnDistanceTime { get; set; }
[JsonProperty("TurnCheckSensitivity", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("TurnCheckSensitivity")]
public float? TurnCheckSensitivity { get; set; }
[JsonProperty("DecreaseSpeedOnTurnLimit", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("DecreaseSpeedOnTurnLimit")]
public float? DecreaseSpeedOnTurnLimit { get; set; }
[JsonProperty("EndSplineDecelerationDistance", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("EndSplineDecelerationDistance")]
public float? EndSplineDecelerationDistance { get; set; }
[JsonProperty("AccelerationSpeed", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("AccelerationSpeed")]
public float? AccelerationSpeed { get; set; }
[JsonProperty("DecelerationSpeed", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("DecelerationSpeed")]
public float? DecelerationSpeed { get; set; }
[JsonProperty("PauseDurationRange", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("PauseDurationRange")]
public Vector3? PauseDurationRange { get; set; }
[JsonProperty("BodySwingReturnSpeed", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BodySwingReturnSpeed")]
public float? BodySwingReturnSpeed { get; set; }
[JsonProperty("BodySwingDamping", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BodySwingDamping")]
public float? BodySwingDamping { get; set; }
[JsonProperty("BodySwingIntensity", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BodySwingIntensity")]
public float? BodySwingIntensity { get; set; }
}
}

View File

@ -1,16 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class MatchMakerMinPlayersByWaitTime
{
[JsonProperty("time", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("time")]
public int? Time { get; set; }
[JsonProperty("minPlayers", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("minPlayers")]
public int? MinPlayers { get; set; }
}
}

View File

@ -1,24 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class NonWaveGroupScenario
{
[JsonProperty("MinToBeGroup", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MinToBeGroup")]
public int? MinToBeGroup { get; set; }
[JsonProperty("MaxToBeGroup", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MaxToBeGroup")]
public int? MaxToBeGroup { get; set; }
[JsonProperty("Chance", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Chance")]
public float? Chance { get; set; }
[JsonProperty("Enabled", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Enabled")]
public bool? Enabled { get; set; }
}
}

View File

@ -1,16 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class Pic
{
[JsonProperty("path", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("path")]
public string? Path { get; set; }
[JsonProperty("rcid", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("rcid")]
public string? Rcid { get; set; }
}
}

View File

@ -1,16 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class Preview
{
[JsonProperty("path", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("path")]
public string? Path { get; set; }
[JsonProperty("rcid", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("rcid")]
public string? Rcid { get; set; }
}
}

View File

@ -1,17 +0,0 @@
using System.Text.Json.Serialization;
using LootDumpProcessor.Model.Tarkov;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class Props
{
[JsonProperty("Center", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Center")]
public Vector3? Center { get; set; }
[JsonProperty("Radius", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Radius")]
public float? Radius { get; set; }
}
}

View File

@ -1,16 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class Requirements
{
[JsonProperty("CompletedQuests", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("CompletedQuests")]
public List<CompletedQuest>? CompletedQuests { get; set; }
[JsonProperty("Standings", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Standings")]
public object? Standings { get; set; }
}
}

View File

@ -1,20 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class RootData
{
[JsonProperty("err", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("err")]
public int? Err { get; set; }
[JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("data")]
public required Data Data { get; set; }
[JsonProperty("errmsg", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("errmsg")]
public object? Errmsg { get; set; }
}
}

View File

@ -1,16 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class Scene
{
[JsonProperty("path", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("path")]
public string? Path { get; set; }
[JsonProperty("rcid", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("rcid")]
public string? Rcid { get; set; }
}
}

View File

@ -1,20 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class ServerMapBTRSettings
{
[JsonProperty("Develop", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Develop")]
public MapSettings? Develop { get; set; }
[JsonProperty("TarkovStreets", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("TarkovStreets")]
public MapSettings? TarkovStreets { get; set; }
[JsonProperty("Woods", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Woods")]
public MapSettings? Woods { get; set; }
}
}

View File

@ -1,16 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class ServerSettings
{
[JsonProperty("TraderServerSettings", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("TraderServerSettings")]
public TraderServerSettings? TraderServerSettings { get; set; }
[JsonProperty("BTRServerSettings", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BTRServerSettings")]
public BTRServerSettings? BTRServerSettings { get; set; }
}
}

View File

@ -1,11 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class ServiceItemCost
{
[JsonProperty]
public Dictionary<string, ItemCost>? Costs { get; set; }
}
}

View File

@ -1,48 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class SpawnPointParam
{
[JsonProperty("Id", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Id")]
public string? Id { get; set; }
[JsonProperty("Position", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Position")]
public Vector3? Position { get; set; }
[JsonProperty("Rotation", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Rotation")]
public float? Rotation { get; set; }
[JsonProperty("Sides", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Sides")]
public List<string>? Sides { get; set; }
[JsonProperty("Categories", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Categories")]
public List<string>? Categories { get; set; }
[JsonProperty("Infiltration", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Infiltration")]
public string? Infiltration { get; set; }
[JsonProperty("DelayToCanSpawnSec", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("DelayToCanSpawnSec")]
public float? DelayToCanSpawnSec { get; set; }
[JsonProperty("ColliderParams", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("ColliderParams")]
public ColliderParams? ColliderParams { get; set; }
[JsonProperty("BotZoneName", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BotZoneName")]
public string? BotZoneName { get; set; }
[JsonProperty("CorePointId", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("CorePointId")]
public int? CorePointId { get; set; }
}
}

View File

@ -1,12 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class Standing
{
[JsonProperty("Value", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Value")]
public float? Value { get; set; }
}
}

View File

@ -1,12 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class TraderServerSettings
{
[JsonProperty("TraderServices", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("TraderServices")]
public TraderServices? TraderServices { get; set; }
}
}

View File

@ -1,28 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class TraderService
{
[JsonProperty("TraderId", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("TraderId")]
public string? TraderID { get; set; }
[JsonProperty("TraderServiceType", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("TraderServiceType")]
public string? TraderServiceType { get; set; }
[JsonProperty("Requirements", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Requirements")]
public Requirements? Requirements { get; set; }
[JsonProperty("ServiceItemCost", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("ServiceItemCost")]
public object? ServiceItemCost { get; set; }
[JsonProperty("UniqueItems", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("UniqueItems")]
public List<object>? UniqueItems { get; set; }
}
}

View File

@ -1,36 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class TraderServices
{
[JsonProperty("ExUsecLoyalty", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("ExUsecLoyalty")]
public TraderService? ExUsecLoyalty { get; set; }
[JsonProperty("ZryachiyAid", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("ZryachiyAid")]
public TraderService? ZryachiyAid { get; set; }
[JsonProperty("CultistsAid", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("CultistsAid")]
public TraderService? CultistsAid { get; set; }
[JsonProperty("PlayerTaxi", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("PlayerTaxi")]
public TraderService? PlayerTaxi { get; set; }
[JsonProperty("BtrItemsDelivery", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BtrItemsDelivery")]
public TraderService? BtrItemsDelivery { get; set; }
[JsonProperty("BtrBotCover", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("BtrBotCover")]
public TraderService? BtrBotCover { get; set; }
[JsonProperty("TransitItemsDelivery", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("TransitItemsDelivery")]
public TraderService? TransitItemsDelivery { get; set; }
}
}

View File

@ -1,44 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class Transit
{
[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("id")]
public int? Id { get; set; }
[JsonProperty("active", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("active")]
public bool? Active { get; set; }
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("name")]
public string? Name { get; set; }
[JsonProperty("location", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("location")]
public string? Location { get; set; }
[JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("description")]
public string? Description { get; set; }
[JsonProperty("activateAfterSec", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("activateAfterSec")]
public int? ActivateAfterSec { get; set; }
[JsonProperty("target", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("target")]
public string? Target { get; set; }
[JsonProperty("time", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("time")]
public int? Time { get; set; }
[JsonProperty("conditions", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("conditions")]
public string? Conditions { get; set; }
}
}

View File

@ -1,12 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Input
{
public class Update
{
[JsonProperty("StackObjectsCount", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("StackObjectsCount")]
public int? StackObjectsCount { get; set; }
}
}

View File

@ -1,58 +0,0 @@
using System.Text.Json.Serialization;
using LootDumpProcessor.Utils;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model
{
public class Item : ICloneable
{
[JsonProperty("_id", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("_id")]
public string? Id { get; set; }
[JsonProperty("_tpl", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("_tpl")]
public string? Tpl { get; set; }
[JsonProperty("upd", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("upd")]
public Upd? Upd { get; set; }
[JsonProperty("parentId", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("parentId")]
public string? ParentId { get; set; }
[JsonProperty("slotId", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("slotId")]
public string? SlotId { get; set; }
[JsonProperty("location", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("location")]
public object? Location { get; set; }
public override bool Equals(object? obj)
{
if (obj is not Item parsed)
return false;
return parsed.Tpl == Tpl && parsed.ParentId == ParentId;
}
public override int GetHashCode()
{
return (Tpl?.GetHashCode() + ParentId?.GetHashCode()) ?? base.GetHashCode();
}
public object Clone()
{
return new Item
{
Id = Id,
Tpl = Tpl,
ParentId = ParentId,
SlotId = SlotId,
Location = Location,
Upd = ProcessorUtil.Copy(Upd)
};
}
}
}

View File

@ -1,11 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Output;
public abstract class AbstractDistribution
{
[JsonProperty("relativeProbability", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("relativeProbability")]
public int? RelativeProbability { get; set; }
}

View File

@ -1,11 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Output;
public class AmmoDistribution : AbstractDistribution
{
[JsonProperty("tpl", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("tpl")]
public string? Tpl { get; set; }
}

View File

@ -1,16 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Output
{
public class ItemCountDistribution
{
[JsonProperty("count", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("count")]
public int? Count { get; set; }
[JsonProperty("relativeProbability", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("relativeProbability")]
public int? RelativeProbability { get; set; }
}
}

View File

@ -1,12 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Output
{
public class ItemDistribution : AbstractDistribution
{
[JsonProperty("composedKey", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("composedKey")]
public ComposedKey? ComposedKey { get; set; }
}
}

View File

@ -1,20 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Output.LooseLoot
{
public class LooseLootRoot
{
[JsonProperty("spawnpointCount", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("spawnpointCount")]
public SpawnPointCount? SpawnPointCount { get; set; }
[JsonProperty("spawnpointsForced", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("spawnpointsForced")]
public List<SpawnPointsForced>? SpawnPointsForced { get; set; }
[JsonProperty("spawnpoints", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("spawnpoints")]
public List<SpawnPoint>? SpawnPoints { get; set; }
}
}

View File

@ -1,24 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Output.LooseLoot
{
public class SpawnPoint
{
[JsonProperty("locationId", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("locationId")]
public string? LocationId { get; set; }
[JsonProperty("probability", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("probability")]
public double? Probability { get; set; }
[JsonProperty("template", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("template")]
public Template? Template { get; set; }
[JsonProperty("itemDistribution", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("itemDistribution")]
public List<ItemDistribution>? ItemDistribution { get; set; }
}
}

View File

@ -1,16 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Output.LooseLoot
{
public class SpawnPointCount
{
[JsonProperty("mean", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("mean")]
public double? Mean { get; set; }
[JsonProperty("std", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("std")]
public double? Std { get; set; }
}
}

View File

@ -1,20 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Output.LooseLoot
{
public class SpawnPointsForced
{
[JsonProperty("locationId", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("locationId")]
public string? LocationId { get; set; }
[JsonProperty("probability", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("probability")]
public double? Probability { get; set; }
[JsonProperty("template", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("template")]
public Template? Template { get; set; }
}
}

View File

@ -1,20 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Output.StaticContainer
{
public class MapStaticLoot
{
[JsonProperty("staticWeapons", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("staticWeapons")]
public List<Template>? StaticWeapons { get; set; }
[JsonProperty("staticContainers", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("staticContainers")]
public List<StaticDataPoint>? StaticContainers { get; set; }
[JsonProperty("staticForced", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("staticForced")]
public List<StaticForced>? StaticForced { get; set; }
}
}

View File

@ -1,48 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Output.StaticContainer
{
public class StaticContainerRoot
{
[JsonProperty("Laboratory", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Laboratory")]
public MapStaticLoot? Laboratory { get; set; }
[JsonProperty("Shoreline", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Shoreline")]
public MapStaticLoot? Shoreline { get; set; }
[JsonProperty("Streets of Tarkov", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Streets of Tarkov")]
public MapStaticLoot? StreetsofTarkov { get; set; }
[JsonProperty("Interchange", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Interchange")]
public MapStaticLoot? Interchange { get; set; }
[JsonProperty("Customs", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Customs")]
public MapStaticLoot? Customs { get; set; }
[JsonProperty("Woods", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Woods")]
public MapStaticLoot? Woods { get; set; }
[JsonProperty("Factory", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Factory")]
public MapStaticLoot? Factory { get; set; }
[JsonProperty("ReserveBase", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("ReserveBase")]
public MapStaticLoot? ReserveBase { get; set; }
[JsonProperty("Lighthouse", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Lighthouse")]
public MapStaticLoot? Lighthouse { get; set; }
[JsonProperty("Sandbox", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Sandbox")]
public MapStaticLoot? GroundZero { get; set; }
}
}

View File

@ -1,15 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Output.StaticContainer;
public class StaticDataPoint
{
[JsonProperty("probability", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("probability")]
public double? Probability { get; set; }
[JsonProperty("template", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("template")]
public Template? Template { get; set; }
}

View File

@ -1,19 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
using YamlDotNet.Serialization;
namespace LootDumpProcessor.Model.Output.StaticContainer
{
public class StaticForced
{
[JsonProperty("containerId", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("containerId")]
[YamlMember(Alias = "containerId")]
public string? ContainerId { get; set; }
[JsonProperty("itemTpl", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("itemTpl")]
[YamlMember(Alias = "itemTpl")]
public string? ItemTpl { get; set; }
}
}

View File

@ -1,11 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Output;
public class StaticDistribution : AbstractDistribution
{
[JsonProperty("tpl", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("tpl")]
public string? Tpl { get; set; }
}

View File

@ -1,16 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Output
{
public class StaticItemDistribution
{
[JsonProperty("itemcountDistribution", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("itemcountDistribution")]
public List<ItemCountDistribution>? ItemCountDistribution { get; set; }
[JsonProperty("itemDistribution", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("itemDistribution")]
public List<StaticDistribution>? ItemDistribution { get; set; }
}
}

View File

@ -1,81 +0,0 @@
namespace LootDumpProcessor.Model.Processing;
public static class BaseClasses
{
public static string DefaultInventory = "55d7217a4bdc2d86028b456d";
public static string Inventory = "55d720f24bdc2d88028b456d";
public static string Pockets = "557596e64bdc2dc2118b4571";
public static string Weapon = "5422acb9af1c889c16000029";
public static string Headwear = "5a341c4086f77401f2541505";
public static string Armor = "5448e54d4bdc2dcc718b4568";
public static string Vest = "5448e5284bdc2dcb718b4567";
public static string Backpack = "5448e53e4bdc2d60728b4567";
public static string Visors = "5448e5724bdc2ddf718b4568";
public static string Food = "5448e8d04bdc2ddf718b4569";
public static string Drink = "5448e8d64bdc2dce718b4568";
public static string BarterItem = "5448eb774bdc2d0a728b4567";
public static string Info = "5448ecbe4bdc2d60728b4568";
public static string MedKit = "5448f39d4bdc2d0a728b4568";
public static string Drugs = "5448f3a14bdc2d27728b4569";
public static string Stimulator = "5448f3a64bdc2d60728b456a";
public static string Medical = "5448f3ac4bdc2dce718b4569";
public static string MedicalSupplies = "57864c8c245977548867e7f1";
public static string Mod = "5448fe124bdc2da5018b4567";
public static string Stock = "55818a594bdc2db9688b456a";
public static string Foregrip = "55818af64bdc2d5b648b4570";
public static string Mount = "55818b224bdc2dde698b456f";
public static string Muzzle = "5448fe394bdc2d0d028b456c";
public static string Sights = "5448fe7a4bdc2d6f028b456b";
public static string Meds = "543be5664bdc2dd4348b4569";
public static string Money = "543be5dd4bdc2deb348b4569";
public static string Key = "543be5e94bdc2df1348b4568";
public static string KeyMechanical = "5c99f98d86f7745c314214b3";
public static string Keycard = "5c164d2286f774194c5e69fa";
public static string Equipment = "543be5f84bdc2dd4348b456a";
public static string ThrowWeap = "543be6564bdc2df4348b4568";
public static string FoodDrink = "543be6674bdc2df1348b4569";
public static string Pistol = "5447b5cf4bdc2d65278b4567";
public static string Smg = "5447b5e04bdc2d62278b4567";
public static string AssaultRifle = "5447b5f14bdc2d61278b4567";
public static string AssaultCarbine = "5447b5fc4bdc2d87278b4567";
public static string Shotgun = "5447b6094bdc2dc3278b4567";
public static string MarksmanRifle = "5447b6194bdc2d67278b4567";
public static string SniperRifle = "5447b6254bdc2dc3278b4568";
public static string MachineGun = "5447bed64bdc2d97278b4568";
public static string GrenadeLauncher = "5447bedf4bdc2d87278b4568";
public static string SpecialWeapon = "5447bee84bdc2dc3278b4569";
public static string SpecItem = "5447e0e74bdc2d3c308b4567";
public static string Knife = "5447e1d04bdc2dff2f8b4567";
public static string Ammo = "5485a8684bdc2da71d8b4567";
public static string AmmoBox = "543be5cb4bdc2deb348b4568";
public static string LootContainer = "566965d44bdc2d814c8b4571";
public static string MobContainer = "5448bf274bdc2dfc2f8b456a";
public static string SearchableItem = "566168634bdc2d144c8b456c";
public static string Stash = "566abbb64bdc2d144c8b457d";
public static string SortingTable = "6050cac987d3f925bf016837";
public static string LockableContainer = "5671435f4bdc2d96058b4569";
public static string SimpleContainer = "5795f317245977243854e041";
public static string StationaryContainer = "567583764bdc2d98058b456e";
public static string Armband = "5b3f15d486f77432d0509248";
public static string DogTagUsec = "59f32c3b86f77472a31742f0";
public static string DogTagBear = "59f32bb586f774757e1e8442";
public static string Jewelry = "57864a3d24597754843f8721";
public static string Electronics = "57864a66245977548f04a81f";
public static string BuildingMaterial = "57864ada245977548638de91";
public static string Tool = "57864bb7245977548b3b66c2";
public static string HouseholdGoods = "57864c322459775490116fbf";
public static string Lubricant = "57864e4c24597754843f8723";
public static string Battery = "57864ee62459775490116fc1";
public static string FunctionalMod = "550aa4154bdc2dd8348b456b";
public static string GearMod = "55802f3e4bdc2de7118b4584";
public static string MasterMod = "55802f4a4bdc2ddb688b4569";
public static string Other = "590c745b86f7743cc433c5f2";
public static string AssaultScope = "55818add4bdc2d5b648b456f";
public static string ReflexSight = "55818ad54bdc2ddc698b4569";
public static string TacticalCombo = "55818b164bdc2ddc698b456c";
public static string Magazine = "5448bc234bdc2d3c308b4569";
public static string LightLaser = "55818b0e4bdc2dde698b456e";
public static string Silencer = "550aa4cd4bdc2dd8348b456c";
public static string PortableRangeFinder = "61605ddea09d851a0a0c1bbc";
public static string Item = "54009119af1c881c07000029";
}

View File

@ -1,24 +0,0 @@
using System.Text.Json.Serialization;
using LootDumpProcessor.Storage;
using LootDumpProcessor.Utils;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Processing;
public class LooseLootCounts : IKeyable
{
[JsonProperty("__id__")]
[JsonPropertyName("__id__")]
public string __ID { get; set; } = KeyGenerator.GetNextKey();
public IKey Counts { get; set; }
// public IKey Items { get; set; }
public IKey ItemProperties { get; set; }
public List<int> MapSpawnpointCount { get; set; } = new();
public IKey GetKey()
{
return new FlatUniqueKey(new[] { __ID });
}
}

View File

@ -1,20 +0,0 @@
using LootDumpProcessor.Serializers.Json.Converters;
using LootDumpProcessor.Storage;
namespace LootDumpProcessor.Model.Processing;
public class PreProcessedLooseLoot : IKeyable
{
public Dictionary<string, int> Counts { get; set; }
[Newtonsoft.Json.JsonConverter(typeof(NewtonsoftJsonKeyConverter))]
[System.Text.Json.Serialization.JsonConverter(typeof(NetJsonKeyConverter))]
public IKey ItemProperties { get; set; }
public int MapSpawnpointCount { get; set; }
public IKey GetKey()
{
throw new NotImplementedException();
}
}

View File

@ -1,25 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model
{
public class Repairable : ICloneable
{
[JsonProperty("Durability", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Durability")]
public int? Durability { get; set; }
[JsonProperty("MaxDurability", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("MaxDurability")]
public int? MaxDurability { get; set; }
public object Clone()
{
return new Repairable
{
Durability = Durability,
MaxDurability = MaxDurability
};
}
}
}

View File

@ -1,36 +0,0 @@
namespace LootDumpProcessor.Model.Tarkov;
public class Category
{
public string Id { get; set; }
public string ParentId { get; set; }
public string Icon { get; set; }
public string Color { get; set; }
public string Order { get; set; }
}
public class HandbookItem
{
public string Id { get; set; }
public string ParentId { get; set; }
public int Price { get; set; }
}
public class HandbookRoot
{
public List<Category> Categories { get; set; }
public List<HandbookItem> Items { get; set; }
}
public class StaticContainerRoot
{
public decimal probability { get; set; }
public StaticContainerTemplate template { get; set; }
}
public class StaticContainerTemplate
{
public string Id { get; set; }
public decimal SpawnChance { get; set; }
public bool IsAlwaysSpawn { get; set; }
}

View File

@ -1,152 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Tarkov;
public class TemplateFileItem
{
[JsonProperty("_id")]
[JsonPropertyName("_id")]
public string Id { get; set; }
[JsonProperty("_name")]
[JsonPropertyName("_name")]
public string Name { get; set; }
[JsonProperty("_parent")]
[JsonPropertyName("_parent")]
public string? Parent { get; set; }
[JsonProperty("_type")]
[JsonPropertyName("_type")]
public string Type { get; set; }
[JsonProperty("_props")]
[JsonPropertyName("_props")]
public Props Props { get; set; }
}
public class Props
{
public string Name { get; set; }
public string ShortName { get; set; }
public string Description { get; set; }
public double? MaxDurability { get; set; }
public string? Caliber { get; set; }
[JsonProperty("ammoCaliber")]
[JsonPropertyName("ammoCaliber")]
public string? AmmoCaliber { get; set; }
public bool QuestItem { get; set; }
public int SpawnChance { get; set; }
public List<string> SpawnFilter { get; set; }
public List<Grid> Grids { get; set; }
public string Rarity { get; set; }
public int ExtraSizeLeft { get; set; }
public int ExtraSizeRight { get; set; }
public int ExtraSizeUp { get; set; }
public int ExtraSizeDown { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public int? StackMinRandom { get; set; }
public int? StackMaxRandom { get; set; }
public List<Chamber> Chambers { get; set; }
public List<Slot> Slots { get; set; }
[JsonProperty("defAmmo")]
[JsonPropertyName("defAmmo")]
public string DefaultAmmo { get; set; }
}
public class Grid
{
[JsonProperty("_props")]
[JsonPropertyName("_props")]
public GridProps Props { get; set; }
}
public class GridProps
{
[JsonProperty("cellsH")]
[JsonPropertyName("cellsH")]
public int CellsHorizontal { get; set; }
[JsonProperty("cellsV")]
[JsonPropertyName("cellsV")]
public int CellsVertical { get; set; }
[JsonProperty("minCount")]
[JsonPropertyName("minCount")]
public int MinCount { get; set; }
[JsonProperty("maxCount")]
[JsonPropertyName("maxCount")]
public int MaxCount { get; set; }
[JsonProperty("filters")]
[JsonPropertyName("filters")]
public List<GridFilter> Filters { get; set; }
}
public class GridFilter
{
}
public class Chamber
{
[JsonProperty("_name")]
[JsonPropertyName("_name")]
public string Name { get; set; }
[JsonProperty("_id")]
[JsonPropertyName("_id")]
public string Id { get; set; }
[JsonProperty("_parent")]
[JsonPropertyName("_parent")]
public string Parent { get; set; }
[JsonProperty("_props")]
[JsonPropertyName("_props")]
public ChamberProps Props { get; set; }
[JsonProperty("_required")]
[JsonPropertyName("_required")]
public bool Required { get; set; }
[JsonProperty("_mergeSlotWithChildren")]
[JsonPropertyName("_mergeSlotWithChildren")]
public bool MergeSlotWithChildren { get; set; }
[JsonProperty("_proto")]
[JsonPropertyName("_proto")]
public string Proto { get; set; }
}
public class Slot
{
[JsonProperty("_name")]
[JsonPropertyName("_name")]
public string Name { get; set; }
[JsonProperty("_required")]
[JsonPropertyName("_required")]
public bool Required { get; set; }
}
public class ChamberProps
{
[JsonProperty("filters")]
[JsonPropertyName("filters")]
public List<FilterClass> Filters { get; set; }
}
public class FilterClass
{
[JsonProperty("filter")]
[JsonPropertyName("filter")]
public List<string> Filter { get; set; }
}

View File

@ -1,99 +0,0 @@
using System.Text.Json.Serialization;
using LootDumpProcessor.Storage;
using LootDumpProcessor.Utils;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model
{
public class Template : IKeyable, ICloneable
{
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
public string __ID { get; } = KeyGenerator.GetNextKey();
[JsonProperty("Id", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Id")]
public string? Id { get; set; }
[JsonProperty("IsContainer", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("IsContainer")]
public bool? IsContainer { get; set; }
[JsonProperty("useGravity", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("useGravity")]
public bool? UseGravity { get; set; }
[JsonProperty("randomRotation", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("randomRotation")]
public bool? RandomRotation { get; set; }
[JsonProperty("Position", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Position")]
public Vector3? Position { get; set; }
[JsonProperty("Rotation", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Rotation")]
public Vector3? Rotation { get; set; }
[JsonProperty("IsGroupPosition", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("IsGroupPosition")]
public bool? IsGroupPosition { get; set; }
[JsonProperty("GroupPositions", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("GroupPositions")]
public List<GroupPosition>? GroupPositions { get; set; }
[JsonProperty("IsAlwaysSpawn", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("IsAlwaysSpawn")]
public bool? IsAlwaysSpawn { get; set; }
[JsonProperty("Root")]
[JsonPropertyName("Root")]
public string? Root { get; set; }
[JsonProperty("Items")]
[JsonPropertyName("Items")]
public required List<Item> Items { get; set; }
protected bool Equals(Template other)
{
return Id == other.Id;
}
public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((Template)obj);
}
public override int GetHashCode()
{
return (Id != null ? Id.GetHashCode() : 0);
}
public IKey GetKey()
{
return new FlatUniqueKey(new[] { __ID });
}
public object Clone()
{
return new Template
{
Id = Id,
IsContainer = IsContainer,
UseGravity = UseGravity,
RandomRotation = RandomRotation,
Position = ProcessorUtil.Copy(Position),
Rotation = ProcessorUtil.Copy(Rotation),
IsGroupPosition = IsGroupPosition,
GroupPositions = ProcessorUtil.Copy(GroupPositions),
IsAlwaysSpawn = IsAlwaysSpawn,
Root = Root,
Items = ProcessorUtil.Copy(Items)
};
}
}
}

View File

@ -1,36 +0,0 @@
using System.Text.Json.Serialization;
using LootDumpProcessor.Utils;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model
{
public class Upd : ICloneable
{
[JsonProperty("StackObjectsCount", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("StackObjectsCount")]
public object? StackObjectsCount { get; set; }
[JsonProperty("FireMode", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("FireMode")]
public FireMode? FireMode { get; set; }
[JsonProperty("Foldable", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Foldable")]
public Foldable? Foldable { get; set; }
[JsonProperty("Repairable", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Repairable")]
public Repairable? Repairable { get;set; }
public object Clone()
{
return new Upd
{
StackObjectsCount = StackObjectsCount,
FireMode = ProcessorUtil.Copy(FireMode),
Foldable = ProcessorUtil.Copy(Foldable),
Repairable = ProcessorUtil.Copy(Repairable)
};
}
}
}

View File

@ -1,30 +0,0 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model
{
public class Vector3 : ICloneable
{
[JsonProperty("x", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("x")]
public float? X { get; set; }
[JsonProperty("y", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("y")]
public float? Y { get; set; }
[JsonProperty("z", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("z")]
public float? Z { get; set; }
public object Clone()
{
return new Vector3
{
X = X,
Y = Y,
Z = Z
};
}
}
}

View File

@ -1,10 +0,0 @@
namespace LootDumpProcessor.Process;
public static class PipelineFactory
{
public static IPipeline GetInstance()
{
// implement actual factory at some point
return new QueuePipeline();
}
}

View File

@ -1,12 +0,0 @@
namespace LootDumpProcessor.Process.Processor.DumpProcessor;
public static class DumpProcessorFactory
{
public static IDumpProcessor GetInstance()
{
// Implement real factory
return new MultithreadSteppedDumpProcessor();
}
}

View File

@ -1,390 +0,0 @@
using System.Collections.Concurrent;
using LootDumpProcessor.Logger;
using LootDumpProcessor.Model;
using LootDumpProcessor.Model.Input;
using LootDumpProcessor.Model.Output.StaticContainer;
using LootDumpProcessor.Model.Processing;
using LootDumpProcessor.Serializers.Json;
using LootDumpProcessor.Storage;
using LootDumpProcessor.Storage.Collections;
using LootDumpProcessor.Utils;
namespace LootDumpProcessor.Process.Processor.DumpProcessor;
public class MultithreadSteppedDumpProcessor : IDumpProcessor
{
private static IJsonSerializer _jsonSerializer = JsonSerializerFactory.GetInstance();
private static readonly List<Task> Runners = new();
// if we need to, this variable can be moved to use the factory, but since the factory
// needs a locking mechanism to prevent dictionary access exceptions, its better to keep
// a reference to use here
private static readonly IDataStorage _dataStorage = DataStorageFactory.GetInstance();
public Dictionary<OutputFileType, object> ProcessDumps(List<PartialData> dumps)
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
LoggerFactory.GetInstance().Log("Starting final dump processing", LogLevel.Info);
var output = new Dictionary<OutputFileType, object>();
var dumpProcessData = GetDumpProcessData(dumps);
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
LoggerFactory.GetInstance().Log("Heavy processing done!", LogLevel.Info);
var staticContainers = new Dictionary<string, MapStaticLoot>();
var staticContainersLock = new object();
// We need to count how many dumps we have for each map
var mapDumpCounter = new Dictionary<string, int>();
var mapDumpCounterLock = new object();
// dictionary of maps, that has a dictionary of template and hit count
var mapStaticContainersAggregated = new Dictionary<string, Dictionary<Template, int>>();
var mapStaticContainersAggregatedLock = new object();
Runners.Clear();
// BSG changed the map data so static containers are now dynamic, so we need to scan all dumps for the static containers.
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
LoggerFactory.GetInstance().Log("Queuing dumps for static data processing", LogLevel.Info);
foreach (var dumped in dumps)
{
Runners.Add(
Task.Factory.StartNew(() =>
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Debug))
LoggerFactory.GetInstance().Log($"Processing static data for file {dumped.BasicInfo.FileName}", LogLevel.Debug);
var dataDump = _jsonSerializer.Deserialize<RootData>(File.ReadAllText(dumped.BasicInfo.FileName));
if (dataDump == null)
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Error))
LoggerFactory.GetInstance().Log($"Failed to deserialize data from file {dumped.BasicInfo.FileName}", LogLevel.Error);
return; // Skip processing this dump
}
var mapId = dataDump.Data.LocationLoot.Id.ToLower();
// Because we may use multiple version dumps for map data, merge the static loot between dumps
lock (staticContainersLock)
{
if (!staticContainers.TryGetValue(mapId, out var mapStaticLoot))
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
LoggerFactory.GetInstance().Log($"Doing first time process for map {mapId} of real static data", LogLevel.Info);
staticContainers[mapId] = new MapStaticLoot
{
StaticWeapons = new List<Template>(),
StaticForced = new List<StaticForced>()
};
}
else
{
// .Item1 = map name
// .Item2 = force/weapon static arrays
var mapStaticContainers = StaticLootProcessor.CreateStaticWeaponsAndStaticForcedContainers(dataDump);
var newStaticWeapons = mapStaticContainers.Item2.StaticWeapons.Where(x => !mapStaticLoot.StaticWeapons.Exists(y => y.Id == x.Id));
var newStaticForced = mapStaticContainers.Item2.StaticForced.Where(x => !mapStaticLoot.StaticForced.Exists(y => y.ContainerId == x.ContainerId));
mapStaticLoot.StaticWeapons.AddRange(newStaticWeapons);
mapStaticLoot.StaticForced.AddRange(newStaticForced);
}
}
// Takes care of finding how many "dynamic static containers" we have on the map
Dictionary<Template, int> mapAggregatedDataDict;
lock (mapStaticContainersAggregatedLock)
{
// Init dict if map key doesnt exist
if (!mapStaticContainersAggregated.TryGetValue(mapId, out mapAggregatedDataDict))
{
mapAggregatedDataDict = new Dictionary<Template, int>();
mapStaticContainersAggregated.Add(mapId, mapAggregatedDataDict);
}
}
// Only process the dump file if the date is higher (after) the configuration date
if (!DumpWasMadeAfterConfigThresholdDate(dumped))
{
return;
}
// Keep track of how many dumps we have for each map
lock (mapDumpCounterLock)
{
IncrementMapCounterDictionaryValue(mapDumpCounter, mapId);
}
var containerIgnoreListExists = LootDumpProcessorContext.GetConfig().ContainerIgnoreList.TryGetValue(mapId, out string[]? ignoreListForMap);
foreach (var dynamicStaticContainer in StaticLootProcessor.CreateDynamicStaticContainers(dataDump))
{
lock (mapStaticContainersAggregatedLock)
{
if (containerIgnoreListExists && ignoreListForMap.Contains(dynamicStaticContainer.Id))
{
// Skip adding containers to aggregated data if container id is in ignore list
continue;
}
// Increment times container seen in dump by 1
if (!mapAggregatedDataDict.TryAdd(dynamicStaticContainer, 1))
{
mapAggregatedDataDict[dynamicStaticContainer] += 1;
}
}
}
GCHandler.Collect();
})
);
}
Task.WaitAll(Runners.ToArray());
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
LoggerFactory.GetInstance().Log("All static data processing threads finished", LogLevel.Info);
// Aggregate and calculate the probability of a static container
mapStaticContainersAggregated.ToDictionary(
kv => kv.Key,
kv => kv.Value.Select(
td => new StaticDataPoint
{
Template = td.Key,
Probability = GetStaticContainerProbability(kv.Key, td, mapDumpCounter) // kv.Key = map name
}
).ToList()
).ToList().ForEach(kv => staticContainers[kv.Key].StaticContainers = kv.Value); // Hydrate staticContainers.StaticContainers
// Static containers
output.Add(OutputFileType.StaticContainer, staticContainers);
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
LoggerFactory.GetInstance().Log("Processing ammo distribution", LogLevel.Info);
// Ammo distribution
output.Add(
OutputFileType.StaticAmmo,
StaticLootProcessor.CreateAmmoDistribution(dumpProcessData.ContainerCounts)
);
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
LoggerFactory.GetInstance().Log("Processing static loot distribution", LogLevel.Info);
// Static loot distribution
output.Add(
OutputFileType.StaticLoot,
StaticLootProcessor.CreateStaticLootDistribution(dumpProcessData.ContainerCounts, staticContainers)
);
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
LoggerFactory.GetInstance().Log("Processing loose loot distribution", LogLevel.Info);
// Loose loot distribution
var looseLootDistribution = LooseLootProcessor.CreateLooseLootDistribution(
dumpProcessData.MapCounts,
dumpProcessData.LooseLootCounts
);
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
LoggerFactory.GetInstance().Log("Collecting loose loot distribution information", LogLevel.Info);
var loot = dumpProcessData.MapCounts
.Select(mapCount => mapCount.Key)
.ToDictionary(mi => mi, mi => looseLootDistribution[mi]);
output.Add(OutputFileType.LooseLoot, loot);
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
LoggerFactory.GetInstance().Log("Dump processing fully completed!", LogLevel.Info);
return output;
}
private static bool DumpWasMadeAfterConfigThresholdDate(PartialData dataDump)
{
return FileDateParser.TryParseFileDate(dataDump.BasicInfo.FileName, out var fileDate) &&
fileDate.HasValue &&
fileDate.Value > LootDumpProcessorContext.GetConfig().DumpProcessorConfig
.SpawnContainerChanceIncludeAfterDate;
}
private static void IncrementMapCounterDictionaryValue(Dictionary<string, int> mapDumpCounter, string mapName)
{
if (!mapDumpCounter.TryAdd(mapName, 1))
{
// Dict has map, increment count by 1
mapDumpCounter[mapName] += 1;
}
}
private static double GetStaticContainerProbability(string mapName, KeyValuePair<Template, int> td, Dictionary<string, int> mapDumpCounter)
{
return Math.Round((double)((decimal)td.Value / (decimal)mapDumpCounter[mapName]), 2);
}
private static DumpProcessData GetDumpProcessData(List<PartialData> dumps)
{
var dumpProcessData = new DumpProcessData();
dumps.GroupBy(dump => dump.BasicInfo.Map)
.ToList()
.ForEach(tuple =>
{
var mapName = tuple.Key;
var partialFileMetaData = tuple.ToList();
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
LoggerFactory.GetInstance().Log(
$"Processing map {mapName}, total dump data to process: {partialFileMetaData.Count}",
LogLevel.Info
);
dumpProcessData.MapCounts[mapName] = partialFileMetaData.Count;
var lockObjectContainerCounts = new object();
var lockObjectCounts = new object();
var looseLootCounts = new LooseLootCounts();
var lockObjectDictionaryCounts = new object();
var dictionaryCounts = new FlatKeyableDictionary<string, int>();
looseLootCounts.Counts = dictionaryCounts.GetKey();
/*
var dictionaryItemCounts = new FlatKeyableDictionary<string, List<string>>();
counts.Items = dictionaryItemCounts.GetKey();
*/
var lockObjectDictionaryItemProperties = new object();
var dictionaryItemProperties = new FlatKeyableDictionary<string, FlatKeyableList<Template>>();
var actualDictionaryItemProperties = new FlatKeyableDictionary<string, IKey>();
looseLootCounts.ItemProperties = actualDictionaryItemProperties.GetKey();
dumpProcessData.LooseLootCounts.Add(mapName, looseLootCounts.GetKey());
BlockingCollection<PartialData> _partialDataToProcess = new();
// add the items to the queue
foreach (var partialData in partialFileMetaData)
{
_partialDataToProcess.Add(partialData);
}
// Call GC before running threads
partialFileMetaData = null;
tuple = null;
GCHandler.Collect();
// The data storage factory has a lock, we dont want the locks to occur when multithreading
for (int i = 0; i < LootDumpProcessorContext.GetConfig().Threads; i++)
{
Runners.Add(
Task.Factory.StartNew(
() =>
{
while (_partialDataToProcess.TryTake(out var partialData,
TimeSpan.FromMilliseconds(5000)))
{
try
{
var dumpData = _dataStorage.GetItem<ParsedDump>(partialData.ParsedDumpKey);
// Static containers
lock (lockObjectContainerCounts)
{
if (!dumpProcessData.ContainerCounts.ContainsKey(mapName))
{
dumpProcessData.ContainerCounts.Add(mapName, dumpData.Containers);
}
else
{
dumpProcessData.ContainerCounts[mapName].AddRange(dumpData.Containers);
}
}
// Loose loot into ids on files
var loadedDictionary =
_dataStorage
.GetItem<SubdivisionedKeyableDictionary<string, List<Template>>>(
dumpData.LooseLoot.ItemProperties
);
foreach (var (uniqueKey, containerTemplate) in loadedDictionary)
{
var count = dumpData.LooseLoot.Counts[uniqueKey];
lock (lockObjectDictionaryCounts)
{
if (dictionaryCounts.ContainsKey(uniqueKey))
dictionaryCounts[uniqueKey] += count;
else
dictionaryCounts[uniqueKey] = count;
}
/*
var itemList = dumpData.LooseLoot.Items[k];
if (!dictionaryItemCounts.TryGetValue(k, out var itemCounts))
{
itemCounts = new List<string>();
dictionaryItemCounts.Add(k, itemCounts);
}
itemCounts.AddRange(itemList);
*/
lock (lockObjectDictionaryItemProperties)
{
if (!dictionaryItemProperties.TryGetValue(uniqueKey, out var values))
{
values = new FlatKeyableList<Template>();
dictionaryItemProperties.Add(uniqueKey, values);
actualDictionaryItemProperties.Add(uniqueKey, values.GetKey());
}
values.AddRange(containerTemplate);
}
}
lock (lockObjectCounts)
{
looseLootCounts.MapSpawnpointCount.Add(dumpData.LooseLoot.MapSpawnpointCount);
}
}
catch (Exception e)
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Error))
LoggerFactory.GetInstance().Log(
$"ERROR OCCURRED:{e.Message}\n{e.StackTrace}",
LogLevel.Error
);
}
}
},
TaskCreationOptions.LongRunning)
);
}
// Wait until all runners are done processing
while (!Runners.All(r => r.IsCompleted))
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
LoggerFactory.GetInstance().Log(
$"One or more file processors are still processing files. Waiting {LootDumpProcessorContext.GetConfig().ThreadPoolingTimeoutMs}ms before checking again",
LogLevel.Info
);
Thread.Sleep(
TimeSpan.FromMilliseconds(LootDumpProcessorContext.GetConfig().ThreadPoolingTimeoutMs));
}
foreach (var (_, value) in dictionaryItemProperties)
{
_dataStorage.Store(value);
}
_dataStorage.Store(dictionaryCounts);
dictionaryCounts = null;
GCHandler.Collect();
/*
DataStorageFactory.GetInstance().Store(dictionaryItemCounts);
dictionaryItemCounts = null;
GC.Collect();
*/
_dataStorage.Store(actualDictionaryItemProperties);
actualDictionaryItemProperties = null;
GCHandler.Collect();
_dataStorage.Store(looseLootCounts);
looseLootCounts = null;
GCHandler.Collect();
});
return dumpProcessData;
}
}

View File

@ -1,54 +0,0 @@
using LootDumpProcessor.Logger;
using LootDumpProcessor.Model;
using LootDumpProcessor.Model.Processing;
using LootDumpProcessor.Storage;
namespace LootDumpProcessor.Process.Processor.FileProcessor;
public class FileProcessor : IFileProcessor
{
public PartialData Process(BasicInfo parsedData)
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Debug))
LoggerFactory.GetInstance().Log($"Processing file {parsedData.FileName}...", LogLevel.Debug);
List<Template> looseLoot = new List<Template>();
List<Template> staticLoot = new List<Template>();
foreach (var item in parsedData.Data.Data.LocationLoot.Loot)
{
if (item.IsContainer ?? false)
staticLoot.Add(item);
else
looseLoot.Add(item);
}
parsedData.Data = null;
var dumpData = new ParsedDump
{
BasicInfo = parsedData
};
var data = new PartialData
{
BasicInfo = parsedData,
ParsedDumpKey = (AbstractKey)dumpData.GetKey()
};
if (!DataStorageFactory.GetInstance().Exists(dumpData.GetKey()))
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Debug))
LoggerFactory.GetInstance().Log(
$"Cached not found for {string.Join("/", dumpData.GetKey().GetLookupIndex())} processing.",
LogLevel.Debug
);
dumpData.Containers = StaticLootProcessor.PreProcessStaticLoot(staticLoot);
dumpData.LooseLoot = LooseLootProcessor.PreProcessLooseLoot(looseLoot);
DataStorageFactory.GetInstance().Store(dumpData);
}
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Debug))
LoggerFactory.GetInstance().Log($"File {parsedData.FileName} finished processing!", LogLevel.Debug);
return data;
}
}

View File

@ -1,13 +0,0 @@
namespace LootDumpProcessor.Process.Processor.FileProcessor;
public static class FileProcessorFactory
{
private static IFileProcessor? _fileProcessor;
public static IFileProcessor GetInstance()
{
// TODO: implement actual factory someday
if (_fileProcessor == null)
_fileProcessor = new FileProcessor();
return _fileProcessor;
}
}

View File

@ -1,279 +0,0 @@
using LootDumpProcessor.Logger;
using LootDumpProcessor.Model;
using LootDumpProcessor.Model.Output;
using LootDumpProcessor.Model.Output.LooseLoot;
using LootDumpProcessor.Model.Processing;
using LootDumpProcessor.Storage;
using LootDumpProcessor.Storage.Collections;
using LootDumpProcessor.Utils;
using NumSharp;
namespace LootDumpProcessor.Process.Processor;
public static class LooseLootProcessor
{
public static PreProcessedLooseLoot PreProcessLooseLoot(List<Template> looseloot)
{
var looseloot_ci = new PreProcessedLooseLoot
{
Counts = new Dictionary<string, int>()
};
var temporalItemProperties = new SubdivisionedKeyableDictionary<string, List<Template>>();
looseloot_ci.ItemProperties = (AbstractKey)temporalItemProperties.GetKey();
looseloot_ci.MapSpawnpointCount = looseloot.Count;
var uniqueIds = new Dictionary<string, object>();
// sometimes the rotation changes very slightly in the dumps for the same location / rotation spawnpoint
// use rounding to make sure it is not generated to two spawnpoint
foreach (var looseLootTemplate in looseloot)
{
// the bsg ids are insane.
// Sometimes the last 7 digits vary but they spawn the same item at the same position
// e.g. for the quest item "60a3b65c27adf161da7b6e14" at "loot_bunker_quest (3)555192"
// so the first approach was to remove the last digits.
// We then saw, that sometimes when the last digits differ for the same string, also the position
// differs.
// We decided to group over the position/rotation/useGravity since they make out a distinct spot
var saneId = looseLootTemplate.GetSaneId();
if (!uniqueIds.ContainsKey(saneId))
{
uniqueIds[saneId] = looseLootTemplate.Id;
if (looseloot_ci.Counts.ContainsKey(saneId))
looseloot_ci.Counts[saneId]++;
else
looseloot_ci.Counts[saneId] = 1;
}
if (!temporalItemProperties.TryGetValue(saneId, out var templates))
{
templates = new FlatKeyableList<Template>();
temporalItemProperties.Add(saneId, templates);
}
templates.Add(looseLootTemplate);
}
DataStorageFactory.GetInstance().Store(temporalItemProperties);
return looseloot_ci;
}
public static Dictionary<string, LooseLootRoot> CreateLooseLootDistribution(
Dictionary<string, int> map_counts,
Dictionary<string, IKey> looseloot_counts
)
{
var forcedConfidence = LootDumpProcessorContext.GetConfig().ProcessorConfig.SpawnPointToleranceForForced / 100;
var probabilities = new Dictionary<string, Dictionary<string, double>>();
var looseLootDistribution = new Dictionary<string, LooseLootRoot>();
foreach (var _tup_1 in map_counts)
{
var mapName = _tup_1.Key;
var mapCount = _tup_1.Value;
probabilities[mapName] = new Dictionary<string, double>();
var looseLootCounts = DataStorageFactory.GetInstance().GetItem<LooseLootCounts>(looseloot_counts[mapName]);
var counts = DataStorageFactory.GetInstance()
.GetItem<FlatKeyableDictionary<string, int>>(looseLootCounts.Counts);
foreach (var (idi, cnt) in counts)
{
probabilities[mapName][idi] = (double)((decimal)cnt / mapCount);
}
// No longer used, dispose
counts = null;
// we want to cleanup the data, so we calculate the mean for the values we get raw
// For whatever reason, we sometimes get dumps that have A LOT more loose loot point than
// the average
var values = looseLootCounts.MapSpawnpointCount.Select(Convert.ToDouble);
var initialMean = np.mean(np.array(values)).ToArray<double>().First();
var looseLootCountTolerancePercentage = LootDumpProcessorContext.GetConfig().ProcessorConfig.LooseLootCountTolerancePercentage / 100;
// We calculate here a high point to check, anything above this value will be ignored
// The data that was inside those loose loot points still counts for them though!
var high = initialMean * (1 + looseLootCountTolerancePercentage);
looseLootCounts.MapSpawnpointCount = looseLootCounts.MapSpawnpointCount.Where(v => v <= high).ToList();
looseLootDistribution[mapName] = new LooseLootRoot
{
SpawnPointCount = new SpawnPointCount
{
Mean = np.mean(np.array(looseLootCounts.MapSpawnpointCount)),
Std = np.std(np.array(looseLootCounts.MapSpawnpointCount))
},
SpawnPointsForced = new List<SpawnPointsForced>(),
SpawnPoints = new List<SpawnPoint>()
};
var itemProperties = DataStorageFactory.GetInstance()
.GetItem<FlatKeyableDictionary<string, IKey>>(looseLootCounts.ItemProperties);
foreach (var (spawnPoint, itemList) in itemProperties)
{
var itemsCounts = new Dictionary<ComposedKey, int>();
var savedItemProperties = DataStorageFactory.GetInstance().GetItem<FlatKeyableList<Template>>(itemList);
foreach (var savedTemplateProperties in savedItemProperties)
{
var key = new ComposedKey(savedTemplateProperties);
if (itemsCounts.ContainsKey(key))
itemsCounts[key] += 1;
else
itemsCounts[key] = 1;
}
// Group by arguments to create possible positions / rotations per spawnpoint
// check if grouping is unique
var itemListSorted = savedItemProperties.Select(template => (template.GetSaneId(), template))
.GroupBy(g => g.Item1).ToList();
if (itemListSorted.Count > 1)
{
throw new Exception("More than one saneKey found");
}
var spawnPoints = itemListSorted.First().Select(v => v.template).ToList();
var locationId = spawnPoints[0].GetLocationId();
var template = ProcessorUtil.Copy(spawnPoints[0]);
//template.Root = null; // Why do we do this, not null in bsg data
var itemDistribution = itemsCounts.Select(kv => new ItemDistribution
{
ComposedKey = kv.Key,
RelativeProbability = kv.Value
}).ToList();
// If any of the items is a quest item or forced loose loot items, or the item normally appreas 99.5%
// Only add position to forced loot if it has only 1 item in the array.
if (itemDistribution.Count == 1 && itemDistribution.Any(item =>
LootDumpProcessorContext.GetTarkovItems().IsQuestItem(item.ComposedKey?.FirstItem?.Tpl) ||
LootDumpProcessorContext.GetForcedLooseItems()[mapName].Contains(item.ComposedKey?.FirstItem?.Tpl))
)
{
var spawnPointToAdd = new SpawnPointsForced
{
LocationId = locationId,
Probability = probabilities[mapName][spawnPoint],
Template = template
};
looseLootDistribution[mapName].SpawnPointsForced.Add(spawnPointToAdd);
}
else if (probabilities[mapName][spawnPoint] > forcedConfidence)
{
var spawnPointToAdd = new SpawnPointsForced
{
LocationId = locationId,
Probability = probabilities[mapName][spawnPoint],
Template = template
};
looseLootDistribution[mapName].SpawnPointsForced.Add(spawnPointToAdd);
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Warning))
LoggerFactory.GetInstance().Log(
$"Item: {template.Id} has > {LootDumpProcessorContext.GetConfig().ProcessorConfig.SpawnPointToleranceForForced}% spawn chance in spawn point: {spawnPointToAdd.LocationId} but isn't in forced loot, adding to forced",
LogLevel.Warning
);
}
else // Normal spawn point, add to non-forced spawnpoint array
{
var spawnPointToAdd = new SpawnPoint
{
LocationId = locationId,
Probability = probabilities[mapName][spawnPoint],
Template = template,
ItemDistribution = itemDistribution
};
template.Items = new List<Item>();
var group = spawnPoints.GroupBy(template => new ComposedKey(template))
.ToDictionary(g => g.Key, g => g.ToList());
foreach (var distribution in itemDistribution)
{
if (group.TryGetValue(distribution.ComposedKey, out var items))
{
// We need to reparent the IDs to match the composed key ID
var itemDistributionItemList = items.First().Items;
// Find the item with no parent id, this is essentially the "Root" of the actual item
var firstItemInTemplate =
itemDistributionItemList.Find(i => string.IsNullOrEmpty(i.ParentId));
// Save the original ID reference, we need to replace it on child items
var originalId = firstItemInTemplate.Id;
// Put the composed key instead
firstItemInTemplate.Id = distribution.ComposedKey.Key;
// Reparent any items with the original id on it
itemDistributionItemList.Where(i => i.ParentId == originalId)
.ToList()
.ForEach(i => i.ParentId = firstItemInTemplate.Id);
template.Items.AddRange(itemDistributionItemList);
}
else
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Error))
LoggerFactory.GetInstance().Log(
$"Item template {distribution.ComposedKey?.FirstItem?.Tpl} was on loose loot distribution for spawn point {template.Id} but the spawn points didnt contain a template matching it.",
LogLevel.Error
);
}
}
looseLootDistribution[mapName].SpawnPoints.Add(spawnPointToAdd);
}
}
// # Test for duplicate position
// # we removed most of them by "rounding away" the jitter in rotation,
// # there are still a few duplicate locations with distinct difference in rotation left though
// group_fun = lambda x: (
// x["template"]["Position"]["x"],
// x["template"]["Position"]["y"],
// x["template"]["Position"]["z"],
// )
// test = sorted(loose_loot_distribution[mi]["spawnpoints"], key=group_fun)
// test_grouped = groupby(test, group_fun)
// test_len = []
// for k, g in test_grouped:
// gl = list(g)
// test_len.append(len(gl))
// if len(gl) > 1:
// print(gl)
//
// print(mi, np.unique(test_len, return_counts=True))
looseLootDistribution[mapName].SpawnPoints =
looseLootDistribution[mapName].SpawnPoints.OrderBy(x => x.Template.Id).ToList();
// Cross check with forced loot in dumps vs items defined in forced_loose.yaml
var forcedTplsInConfig = new HashSet<string>(
(from forceditem in LootDumpProcessorContext.GetForcedLooseItems()[mapName]
select forceditem).ToList());
var forcedTplsFound = new HashSet<string>(
(from forceditem in looseLootDistribution[mapName].SpawnPointsForced
select forceditem.Template.Items[0].Tpl).ToList());
// All the tpls that are defined in the forced_loose.yaml for this map that are not found as forced
foreach (var itemTpl in forcedTplsInConfig)
{
if (!forcedTplsFound.Contains(itemTpl))
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Error))
LoggerFactory.GetInstance().Log(
$"Expected item: {itemTpl} defined in forced_loose.yaml config not found in forced loot",
LogLevel.Error
);
}
}
// All the tpls that are found as forced in output file but not in the forced_loose.yaml config
foreach (var itemTpl in forcedTplsFound)
{
if (!forcedTplsInConfig.Contains(itemTpl))
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Warning))
LoggerFactory.GetInstance().Log(
$"Map: {mapName} Item: {itemTpl} not defined in forced_loose.yaml config but was flagged as forced by code",
LogLevel.Warning
);
}
}
}
return looseLootDistribution;
}
}

View File

@ -1,281 +0,0 @@
using LootDumpProcessor.Model;
using LootDumpProcessor.Model.Input;
using LootDumpProcessor.Model.Output;
using LootDumpProcessor.Model.Output.StaticContainer;
using LootDumpProcessor.Model.Processing;
using LootDumpProcessor.Utils;
using System.Collections.Generic;
namespace LootDumpProcessor.Process.Processor;
public static class StaticLootProcessor
{
public static List<PreProcessedStaticLoot> PreProcessStaticLoot(List<Template> staticloot)
{
var containers = new List<PreProcessedStaticLoot>();
foreach (var lootSpawnPosition in staticloot)
{
var tpl = lootSpawnPosition.Items[0].Tpl;
if (!LootDumpProcessorContext.GetStaticWeaponIds().Contains(tpl))
{
// Only add non-weapon static containers
containers.Add(new PreProcessedStaticLoot
{
Type = tpl,
ContainerId = lootSpawnPosition.Items[0].Id,
Items = lootSpawnPosition.Items.Skip(1).ToList()
});
}
}
return containers;
}
public static Tuple<string, MapStaticLoot> CreateStaticWeaponsAndStaticForcedContainers(RootData rawMapDump)
{
var mapName = rawMapDump.Data.LocationLoot.Name;
var mapId = rawMapDump.Data.LocationLoot.Id.ToLower();
var staticLootPositions = (from li in rawMapDump.Data.LocationLoot.Loot
where li.IsContainer ?? false
select li).ToList();
var staticWeapons = new List<Template>();
staticLootPositions = staticLootPositions.OrderBy(x => x.Id).ToList();
foreach (var staticLootPosition in staticLootPositions)
{
if (LootDumpProcessorContext.GetStaticWeaponIds().Contains(staticLootPosition.Items[0].Tpl))
{
staticWeapons.Add(ProcessorUtil.Copy(staticLootPosition));
}
}
var forcedStaticItems = LootDumpProcessorContext.GetForcedItems().ContainsKey(mapId)
? LootDumpProcessorContext.GetForcedItems()[mapId]
: new List<StaticForced>();
var mapStaticData = new MapStaticLoot
{
StaticWeapons = staticWeapons,
StaticForced = forcedStaticItems
};
return Tuple.Create(mapId, mapStaticData);
}
public static List<Template> CreateDynamicStaticContainers(RootData rawMapDump)
{
var data = (from li in rawMapDump.Data.LocationLoot.Loot
where (li.IsContainer ?? false) && (!LootDumpProcessorContext.GetStaticWeaponIds().Contains(li.Items[0].Tpl))
select li).ToList();
foreach (var item in data)
{
// remove all but first item from containers items
item.Items = new List<Item> { item.Items[0] };
}
return data;
}
/// <summary>
///
/// </summary>
/// <param name="container_counts"></param>
/// <returns>key = mapid / </returns>
public static Dictionary<string, Dictionary<string, List<AmmoDistribution>>> CreateAmmoDistribution(
Dictionary<string, List<PreProcessedStaticLoot>> container_counts
)
{
var allMapsAmmoDistro = new Dictionary<string, Dictionary<string, List<AmmoDistribution>>>();
foreach (var mapAndContainers in container_counts)
{
var mapid = mapAndContainers.Key;
var containers = mapAndContainers.Value;
var ammo = new List<string>();
foreach (var ci in containers)
{
ammo.AddRange(from item in ci.Items
where LootDumpProcessorContext.GetTarkovItems().IsBaseClass(item.Tpl, BaseClasses.Ammo)
select item.Tpl);
}
var ammo_counts = new List<CaliberTemplateCount>();
ammo_counts.AddRange(
ammo.GroupBy(a => a)
.Select(g => new CaliberTemplateCount
{
Caliber = LootDumpProcessorContext.GetTarkovItems().AmmoCaliber(g.Key),
Template = g.Key,
Count = g.Count()
})
);
ammo_counts = ammo_counts.OrderBy(x => x.Caliber).ToList();
var ammo_distribution = new Dictionary<string, List<AmmoDistribution>>();
foreach (var _tup_3 in ammo_counts.GroupBy(x => x.Caliber))
{
var k = _tup_3.Key;
var g = _tup_3.ToList();
ammo_distribution[k] = (from gi in g
select new AmmoDistribution
{
Tpl = gi.Template,
RelativeProbability = gi.Count
}).ToList();
}
allMapsAmmoDistro.TryAdd(mapid, ammo_distribution);
}
return allMapsAmmoDistro;
//var ammo = new List<string>();
//foreach (var ci in container_counts)
//{
// ammo.AddRange(from item in ci.Items
// where LootDumpProcessorContext.GetTarkovItems().IsBaseClass(item.Tpl, BaseClasses.Ammo)
// select item.Tpl);
//}
//var ammo_counts = new List<CaliberTemplateCount>();
//ammo_counts.AddRange(
// ammo.GroupBy(a => a)
// .Select(g => new CaliberTemplateCount
// {
// Caliber = LootDumpProcessorContext.GetTarkovItems().AmmoCaliber(g.Key),
// Template = g.Key,
// Count = g.Count()
// })
//);
//ammo_counts = ammo_counts.OrderBy(x => x.Caliber).ToList();
//var ammo_distribution = new Dictionary<string, List<AmmoDistribution>>();
//foreach (var _tup_3 in ammo_counts.GroupBy(x => x.Caliber))
//{
// var k = _tup_3.Key;
// var g = _tup_3.ToList();
// ammo_distribution[k] = (from gi in g
// select new AmmoDistribution
// {
// Tpl = gi.Template,
// RelativeProbability = gi.Count
// }).ToList();
//}
//return ammo_distribution;
}
/// <summary>
/// Dict key = map,
/// value = sub dit:
/// key = container Ids
/// value = items + counts
/// </summary>
public static Dictionary<string, Dictionary<string, StaticItemDistribution>> CreateStaticLootDistribution(
Dictionary<string, List<PreProcessedStaticLoot>> container_counts,
Dictionary<string, MapStaticLoot> staticContainers)
{
var allMapsStaticLootDisto = new Dictionary< string, Dictionary<string, StaticItemDistribution>>();
// Iterate over each map we have containers for
foreach (var mapContainersKvp in container_counts)
{
var mapName = mapContainersKvp.Key;
var containers = mapContainersKvp.Value;
var static_loot_distribution = new Dictionary<string, StaticItemDistribution>();
var uniqueContainerTypeIds = Enumerable.Distinct((from ci in containers
select ci.Type).ToList());
foreach (var typeId in uniqueContainerTypeIds)
{
var container_counts_selected = (from ci in containers
where ci.Type == typeId
select ci).ToList();
// Get array of all times a count of items was found in container
List<int> itemCountsInContainer = GetCountOfItemsInContainer(container_counts_selected);
// Create structure to hold item count + weight that it will be picked
// Group same counts together
static_loot_distribution[typeId] = new StaticItemDistribution();
static_loot_distribution[typeId].ItemCountDistribution = itemCountsInContainer.GroupBy(i => i)
.Select(g => new ItemCountDistribution
{
Count = g.Key,
RelativeProbability = g.Count()
}).ToList();
static_loot_distribution[typeId].ItemDistribution = CreateItemDistribution(container_counts_selected);
}
// Key = containers tpl, value = items + count weights
allMapsStaticLootDisto.TryAdd(mapName, static_loot_distribution);
}
return allMapsStaticLootDisto;
//var static_loot_distribution = new Dictionary<string, StaticItemDistribution>();
//var uniqueContainerTypeIds = Enumerable.Distinct((from ci in container_counts
// select ci.Type).ToList());
//foreach (var typeId in uniqueContainerTypeIds)
//{
// var container_counts_selected = (from ci in container_counts
// where ci.Type == typeId
// select ci).ToList();
// // Get array of all times a count of items was found in container
// List<int> itemCountsInContainer = GetCountOfItemsInContainer(container_counts_selected);
// // Create structure to hold item count + weight that it will be picked
// // Group same counts together
// static_loot_distribution[typeId] = new StaticItemDistribution();
// static_loot_distribution[typeId].ItemCountDistribution = itemCountsInContainer.GroupBy(i => i)
// .Select(g => new ItemCountDistribution
// {
// Count = g.Key,
// RelativeProbability = g.Count()
// }).ToList();
// static_loot_distribution[typeId].ItemDistribution = CreateItemDistribution(container_counts_selected);
//}
//// Key = containers tpl, value = items + count weights
//return static_loot_distribution;
}
private static List<StaticDistribution> CreateItemDistribution(List<PreProcessedStaticLoot> container_counts_selected)
{
// TODO: Change for different algo that splits items per parent once parentid = containerid, then compose
// TODO: key and finally create distribution based on composed Id instead
var itemsHitCounts = new Dictionary<string, int>();
foreach (var ci in container_counts_selected)
{
foreach (var cii in ci.Items.Where(cii => cii.ParentId == ci.ContainerId))
{
if (itemsHitCounts.ContainsKey(cii.Tpl))
itemsHitCounts[cii.Tpl] += 1;
else
itemsHitCounts[cii.Tpl] = 1;
}
}
// WIll create array of objects that have a tpl + relative probability weight value
return itemsHitCounts.Select(v => new StaticDistribution
{
Tpl = v.Key,
RelativeProbability = v.Value
}).ToList();
}
private static List<int> GetCountOfItemsInContainer(List<PreProcessedStaticLoot> container_counts_selected)
{
var itemCountsInContainer = new List<int>();
foreach (var containerWithItems in container_counts_selected)
{
// Only count item if its parent is the container, only root items are counted (not mod/attachment items)
itemCountsInContainer.Add((from cii in containerWithItems.Items
where cii.ParentId == containerWithItems.ContainerId
select cii).ToList().Count);
}
return itemCountsInContainer;
}
}

View File

@ -1,427 +0,0 @@
using System.Collections.Concurrent;
using LootDumpProcessor.Logger;
using LootDumpProcessor.Model.Input;
using LootDumpProcessor.Process.Collector;
using LootDumpProcessor.Process.Processor;
using LootDumpProcessor.Process.Processor.DumpProcessor;
using LootDumpProcessor.Process.Processor.FileProcessor;
using LootDumpProcessor.Process.Reader;
using LootDumpProcessor.Process.Reader.Filters;
using LootDumpProcessor.Process.Reader.Intake;
using LootDumpProcessor.Process.Reader.PreProcess;
using LootDumpProcessor.Process.Writer;
using LootDumpProcessor.Serializers.Json;
using LootDumpProcessor.Storage;
using LootDumpProcessor.Utils;
namespace LootDumpProcessor.Process;
public class QueuePipeline : IPipeline
{
private static readonly BlockingCollection<string> _filesToRename = new();
private static readonly BlockingCollection<string> _filesToProcess = new();
private static readonly List<Task> Runners = new();
private static readonly List<Task> Renamers = new();
private readonly List<string> _mapNames = LootDumpProcessorContext.GetConfig().MapsToProcess;
private static readonly Dictionary<string, IPreProcessReader> _preProcessReaders;
static QueuePipeline()
{
_preProcessReaders = LootDumpProcessorContext.GetConfig()
.ReaderConfig
.PreProcessorConfig
?.PreProcessors
?.ToDictionary(
t => PreProcessReaderFactory.GetInstance(t).GetHandleExtension().ToLower(),
PreProcessReaderFactory.GetInstance
) ?? new Dictionary<string, IPreProcessReader>();
}
public void DoProcess()
{
// Single collector instance to collect results
var collector = CollectorFactory.GetInstance();
collector.Setup();
// We add 2 more threads to the total count to account for subprocesses and others
int threads = LootDumpProcessorContext.GetConfig().Threads;
ThreadPool.SetMaxThreads(threads + 2, threads + 2);
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
{
LoggerFactory.GetInstance().Log("Gathering files to begin processing", LogLevel.Info);
}
try
{
FixFilesFromDumps(threads);
foreach (var mapName in _mapNames)
{
ProcessFilesFromDumpsPerMap(threads, collector, mapName);
}
}
finally
{
// use dispose on the preprocessreaders to eliminate any temporary files generated
foreach (var (_, value) in _preProcessReaders)
{
value.Dispose();
}
}
}
private List<string> GatherFiles()
{
// Read locations
var inputPath = LootDumpProcessorContext.GetConfig().ReaderConfig.DumpFilesLocation;
if (inputPath == null || inputPath.Count == 0)
{
throw new Exception("Reader dumpFilesLocations must be set to a valid value");
}
// We gather up all files into a queue
var queuedFilesToProcess = GetFileQueue(inputPath);
// Then we preprocess the files in the queue and get them ready for processing
return PreProcessQueuedFiles(queuedFilesToProcess);
}
private List<string> PreProcessQueuedFiles(Queue<string> queuedFilesToProcess)
{
var gatheredFiles = new List<string>();
if (queuedFilesToProcess.Count == 0)
{
throw new Exception("No files matched accepted extension types in configs");
}
var fileFilters = GetFileFilters() ?? new Dictionary<string, IFileFilter>();
while (queuedFilesToProcess.TryDequeue(out var file))
{
var extension = Path.GetExtension(file)[1..].ToLower();
// if there is a preprocessor, call it and preprocess the file, then add them to the queue
if (_preProcessReaders.TryGetValue(extension, out var preProcessor))
{
// if the preprocessor found something new to process or generated new files, add them to the queue
if (preProcessor.TryPreProcess(file, out var outputFiles, out var outputDirectories))
{
// all new directories need to be processed as well
GetFileQueue(outputDirectories).ToList().ForEach(queuedFilesToProcess.Enqueue);
// all output files need to be queued as well
outputFiles.ForEach(queuedFilesToProcess.Enqueue);
}
}
else
{
// if there is no preprocessor for the file, means its ready to filter or accept
if (fileFilters.TryGetValue(extension, out var filter))
{
if (filter.Accept(file))
{
gatheredFiles.Add(file);
}
}
else
{
gatheredFiles.Add(file);
}
}
}
return gatheredFiles;
}
private Queue<string> GetFileQueue(List<string> inputPath)
{
var queuedPathsToProcess = new Queue<string>();
var queuedFilesToProcess = new Queue<string>();
// Accepted file extensions on raw files
var acceptedFileExtension = LootDumpProcessorContext.GetConfig()
.ReaderConfig
.AcceptedFileExtensions
.Select(ex => ex.ToLower())
.ToHashSet();
inputPath.ForEach(p => queuedPathsToProcess.Enqueue(p));
while (queuedPathsToProcess.TryDequeue(out var path))
{
// Check the input file to be sure its going to have data on it.
if (!Directory.Exists(path))
{
throw new Exception($"Input directory \"{inputPath}\" could not be found");
}
// If we should process subfolder, queue them up as well
if (LootDumpProcessorContext.GetConfig().ReaderConfig.ProcessSubFolders)
{
foreach (var directory in Directory.GetDirectories(path))
{
queuedPathsToProcess.Enqueue(directory);
}
}
var files = Directory.GetFiles(path);
foreach (var file in files)
{
if (acceptedFileExtension.Contains(Path.GetExtension(file)[1..].ToLower()))
{
queuedFilesToProcess.Enqueue(file);
}
}
}
return queuedFilesToProcess;
}
private Dictionary<string, IFileFilter>? GetFileFilters()
{
return LootDumpProcessorContext.GetConfig()
.ReaderConfig
.FileFilters
?.ToDictionary(
t => FileFilterFactory.GetInstance(t).GetExtension(),
FileFilterFactory.GetInstance
);
}
/// <summary>
/// Gets all files and adds them to the processor.
/// use per map version now
/// </summary>
/// <param name="threads"></param>
/// <param name="collector"></param>
private void ProcessFilesFromDumps(int threads, ICollector collector)
{
// Gather all files, sort them by date descending and then add them into the processing queue
GatherFiles().OrderByDescending(f =>
{
FileDateParser.TryParseFileDate(f, out var date);
return date;
}
).ToList().ForEach(f => _filesToProcess.Add(f));
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
{
LoggerFactory.GetInstance().Log("Files sorted and ready to begin pre-processing", LogLevel.Info);
}
// We startup all the threads and collect them into a runners list
for (int i = 0; i < threads; i++)
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
{
LoggerFactory.GetInstance().Log("Creating pre-processing threads", LogLevel.Info);
}
Runners.Add(
Task.Factory.StartNew(
() =>
{
while (_filesToProcess.TryTake(out var file, TimeSpan.FromMilliseconds(5000)))
{
try
{
var reader = IntakeReaderFactory.GetInstance();
var processor = FileProcessorFactory.GetInstance();
if (reader.Read(file, out var basicInfo))
{
collector.Hold(processor.Process(basicInfo));
}
}
catch (Exception e)
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Error))
{
LoggerFactory.GetInstance().Log(
$"Error occurred while processing file {file}\n{e.Message}\n{e.StackTrace}",
LogLevel.Error);
}
}
}
},
TaskCreationOptions.LongRunning)
);
}
// Wait until all runners are done processing
while (!Runners.All(r => r.IsCompleted))
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
{
LoggerFactory.GetInstance().Log(
$"One or more file processors are still processing files. Waiting {LootDumpProcessorContext.GetConfig().ThreadPoolingTimeoutMs}ms before checking again",
LogLevel.Info);
}
Thread.Sleep(TimeSpan.FromMilliseconds(LootDumpProcessorContext.GetConfig().ThreadPoolingTimeoutMs));
}
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
{
LoggerFactory.GetInstance().Log("Pre-processing finished", LogLevel.Info);
}
// Single writer instance to collect results
var writer = WriterFactory.GetInstance();
// Single collector instance to collect results
var dumpProcessor = DumpProcessorFactory.GetInstance();
writer.WriteAll(dumpProcessor.ProcessDumps(collector.Retrieve()));
}
private void ProcessFilesFromDumpsPerMap(int threads, ICollector collector, string mapName)
{
// Gather all files, sort them by date descending and then add them into the processing queue
GatherFiles().FindAll(f => f.ToLower().Contains($"{mapName}--")).OrderByDescending(f =>
{
FileDateParser.TryParseFileDate(f, out var date);
return date;
}
).ToList().ForEach(f => _filesToProcess.Add(f));
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
{
LoggerFactory.GetInstance().Log("Files sorted and ready to begin pre-processing", LogLevel.Info);
}
// We startup all the threads and collect them into a runners list
for (int i = 0; i < threads; i++)
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
{
LoggerFactory.GetInstance().Log("Creating pre-processing threads", LogLevel.Info);
}
Runners.Add(
Task.Factory.StartNew(
() =>
{
while (_filesToProcess.TryTake(out var file, TimeSpan.FromMilliseconds(5000)))
{
try
{
var reader = IntakeReaderFactory.GetInstance();
var processor = FileProcessorFactory.GetInstance();
if (reader.Read(file, out var basicInfo))
{
collector.Hold(processor.Process(basicInfo));
}
}
catch (Exception e)
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Error))
{
LoggerFactory.GetInstance().Log(
$"Error occurred while processing file {file}\n{e.Message}\n{e.StackTrace}",
LogLevel.Error);
}
}
}
},
TaskCreationOptions.LongRunning)
);
}
// Wait until all runners are done processing
while (!Runners.All(r => r.IsCompleted))
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
{
LoggerFactory.GetInstance().Log(
$"One or more file processors are still processing files. Waiting {LootDumpProcessorContext.GetConfig().ThreadPoolingTimeoutMs}ms before checking again",
LogLevel.Info);
}
Thread.Sleep(TimeSpan.FromMilliseconds(LootDumpProcessorContext.GetConfig().ThreadPoolingTimeoutMs));
}
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
{
LoggerFactory.GetInstance().Log("Pre-processing finished", LogLevel.Info);
}
// Single writer instance to collect results
var writer = WriterFactory.GetInstance();
// Single collector instance to collect results
var dumpProcessor = DumpProcessorFactory.GetInstance();
writer.WriteAll(dumpProcessor.ProcessDumps(collector.Retrieve()));
// clear collector and datastorage as we process per map now
collector.Clear();
DataStorageFactory.GetInstance().Clear();
}
/// <summary>
/// Adds map name to file if they dont have it already.
/// </summary>
/// <param name="threads">Number of threads to use</param>
private void FixFilesFromDumps(int threads)
{
var inputPath = LootDumpProcessorContext.GetConfig().ReaderConfig.DumpFilesLocation;
if (inputPath == null || inputPath.Count == 0)
{
throw new Exception("Reader dumpFilesLocations must be set to a valid value");
}
GetFileQueue(inputPath).ToList().ForEach(f => _filesToRename.Add(f));
var jsonUtil = JsonSerializerFactory.GetInstance(JsonSerializerTypes.DotNet);
for (var i = 0; i < threads; i++)
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
{
LoggerFactory.GetInstance().Log("Creating file-processing threads", LogLevel.Info);
}
Renamers.Add(Task.Factory.StartNew(() =>
{
while (_filesToRename.TryTake(out var file, TimeSpan.FromMilliseconds(5000)))
{
if (_mapNames.Any(x => file.Contains(x)))
{
continue;
}
try
{
var data = File.ReadAllText(file);
var fileData = jsonUtil.Deserialize<RootData>(data);
var newpath = file.Replace("resp", $"{fileData.Data.LocationLoot.Id.ToLower()}--resp");
File.Move(file, newpath);
}
catch (Exception e)
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Error))
{
LoggerFactory.GetInstance().Log(
$"Error occurred while processing file {file}\n{e.Message}\n{e.StackTrace}",
LogLevel.Error);
}
}
}
}, TaskCreationOptions.LongRunning));
}
while (!Renamers.All(r => r.IsCompleted))
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
{
LoggerFactory.GetInstance()
.Log($"one or more files are being processed. Waiting {LootDumpProcessorContext.GetConfig().ThreadPoolingTimeoutMs} ms", LogLevel.Info);
}
Thread.Sleep(TimeSpan.FromMilliseconds(LootDumpProcessorContext.GetConfig().ThreadPoolingTimeoutMs));
}
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
{
LoggerFactory.GetInstance().Log("File-processing finished", LogLevel.Info);
}
}
}

View File

@ -1,25 +0,0 @@
namespace LootDumpProcessor.Process.Reader.Filters;
public static class FileFilterFactory
{
private static readonly Dictionary<FileFilterTypes, IFileFilter> _fileFilters = new();
private static object lockObject = new();
public static IFileFilter GetInstance(FileFilterTypes type)
{
lock (lockObject)
{
if (!_fileFilters.TryGetValue(type, out var filter))
{
filter = type switch
{
FileFilterTypes.JsonDump => new JsonDumpFileFilter(),
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
};
_fileFilters.Add(type, filter);
}
return filter;
}
}
}

View File

@ -1,6 +0,0 @@
namespace LootDumpProcessor.Process.Reader.Filters;
public enum FileFilterTypes
{
JsonDump
}

View File

@ -1,28 +0,0 @@
namespace LootDumpProcessor.Process.Reader.Intake;
public static class IntakeReaderFactory
{
private static readonly Dictionary<IntakeReaderTypes, IIntakeReader> Instances = new();
private static readonly object DictionaryLock = new();
public static IIntakeReader GetInstance()
{
var type = LootDumpProcessorContext.GetConfig().ReaderConfig.IntakeReaderConfig?.IntakeReaderType ??
IntakeReaderTypes.Json;
lock (DictionaryLock)
{
if (!Instances.TryGetValue(type, out var intakeReader))
{
intakeReader = type switch
{
IntakeReaderTypes.Json => new JsonFileIntakeReader(),
_ => throw new ArgumentOutOfRangeException(
"IntakeReaderType",
"Value was not defined on IntakeReaderConfig"
)
};
Instances.Add(type, intakeReader);
}
return intakeReader;
}
}
}

View File

@ -1,6 +0,0 @@
namespace LootDumpProcessor.Process.Reader.Intake;
public enum IntakeReaderTypes
{
Json
}

View File

@ -1,81 +0,0 @@
using System.Collections.Concurrent;
using LootDumpProcessor.Logger;
using LootDumpProcessor.Model.Input;
using LootDumpProcessor.Model.Processing;
using LootDumpProcessor.Serializers.Json;
using LootDumpProcessor.Utils;
namespace LootDumpProcessor.Process.Reader.Intake;
public class JsonFileIntakeReader : IIntakeReader
{
private static readonly IJsonSerializer _jsonSerializer = JsonSerializerFactory.GetInstance();
private static readonly HashSet<string>? _ignoredLocations =
LootDumpProcessorContext.GetConfig().ReaderConfig.IntakeReaderConfig?.IgnoredDumpLocations.ToHashSet();
private static readonly ConcurrentDictionary<string, int> _totalMapDumpsCounter = new();
public bool Read(string file, out BasicInfo basicInfo)
{
var fileData = File.ReadAllText(file);
if (fileData == null)
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Error))
LoggerFactory.GetInstance().Log($"Couldnt parse date from file: {file}", LogLevel.Error);
basicInfo = null;
return false;
}
// If the file format changes it may screw up this date parser
if (!FileDateParser.TryParseFileDate(file, out var date))
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Error))
LoggerFactory.GetInstance().Log($"Couldnt parse date from file: {file}", LogLevel.Error);
}
var fi = _jsonSerializer.Deserialize<RootData>(fileData);
if (fi?.Data?.LocationLoot?.Name != null && (!_ignoredLocations?.Contains(fi.Data.LocationLoot.Name) ?? true))
{
if (!_totalMapDumpsCounter.TryGetValue(fi.Data.LocationLoot.Name, out var counter))
{
counter = 0;
_totalMapDumpsCounter[fi.Data.LocationLoot.Name] = counter;
}
if (counter < (LootDumpProcessorContext.GetConfig().ReaderConfig.IntakeReaderConfig?.MaxDumpsPerMap ?? 1500))
{
basicInfo = new BasicInfo
{
Map = fi.Data.LocationLoot.Id.ToLower(),
FileHash = ProcessorUtil.HashFile(fileData),
Data = fi,
Date = date ?? DateTime.MinValue,
FileName = file
};
_totalMapDumpsCounter[fi.Data.LocationLoot.Name] += 1;
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Debug))
LoggerFactory.GetInstance().Log($"File {file} fully read, returning data", LogLevel.Debug);
return true;
}
// Map dump limit reached, exit
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Debug))
LoggerFactory.GetInstance().Log($"Ignoring file {file} as the file cap for map {fi.Data.LocationLoot.Id} has been reached", LogLevel.Debug);
basicInfo = null;
return false;
}
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Warning))
LoggerFactory.GetInstance().Log($"File {file} was not eligible for dump data, it did not contain a location name or it was on ignored locations config", LogLevel.Warning);
basicInfo = null;
return false;
}
}

View File

@ -1,49 +0,0 @@
using LootDumpProcessor.Logger;
namespace LootDumpProcessor.Process.Reader.PreProcess;
public abstract class AbstractPreProcessReader : IPreProcessReader
{
protected readonly string _tempFolder;
public AbstractPreProcessReader()
{
var tempFolder = LootDumpProcessorContext.GetConfig().ReaderConfig.PreProcessorConfig?.PreProcessorTempFolder;
if (string.IsNullOrEmpty(tempFolder))
{
tempFolder = GetBaseDirectory();
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Warning))
LoggerFactory.GetInstance()
.Log(
$"No temp folder was assigned preProcessorTempFolder in PreProcessorConfig, defaulting to {tempFolder}",
LogLevel.Warning
);
}
// Cleanup the temp directory before starting the process
if (Directory.Exists(tempFolder))
{
Directory.Delete(tempFolder, true);
}
Directory.CreateDirectory(tempFolder);
_tempFolder = tempFolder;
}
public abstract string GetHandleExtension();
public abstract bool TryPreProcess(string file, out List<string> files, out List<string> directories);
protected string GetBaseDirectory()
{
return $@"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}\SPT\tmp\PreProcessor";
}
public void Dispose()
{
if (LootDumpProcessorContext.GetConfig().ReaderConfig.PreProcessorConfig?.CleanupTempFolderAfterProcess ?? true)
{
Directory.Delete(_tempFolder, true);
}
}
}

View File

@ -1,11 +0,0 @@
namespace LootDumpProcessor.Process.Reader.PreProcess;
public interface IPreProcessReader
{
string GetHandleExtension();
bool TryPreProcess(string file, out List<string> files, out List<string> directories);
// Custom dispose, not IDisposable
void Dispose();
}

View File

@ -1,21 +0,0 @@
namespace LootDumpProcessor.Process.Reader.PreProcess;
public static class PreProcessReaderFactory
{
private static readonly Dictionary<PreProcessReaderTypes, IPreProcessReader> _proProcessReaders = new();
public static IPreProcessReader GetInstance(PreProcessReaderTypes type)
{
if (!_proProcessReaders.TryGetValue(type, out var preProcessReader))
{
preProcessReader = type switch
{
PreProcessReaderTypes.SevenZip => new SevenZipPreProcessReader(),
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
};
_proProcessReaders.Add(type, preProcessReader);
}
return preProcessReader;
}
}

View File

@ -1,6 +0,0 @@
namespace LootDumpProcessor.Process.Reader.PreProcess;
public enum PreProcessReaderTypes
{
SevenZip
}

View File

@ -1,43 +0,0 @@
using LootDumpProcessor.Logger;
using SevenZip;
using SevenZip.Sdk.Compression.Lzma;
namespace LootDumpProcessor.Process.Reader.PreProcess;
public class SevenZipPreProcessReader : AbstractPreProcessReader
{
public override string GetHandleExtension() => "7z";
static SevenZipPreProcessReader()
{
SevenZipBase.SetLibraryPath("./x64/7z.dll");
}
public override bool TryPreProcess(string file, out List<string> files, out List<string> directories)
{
var fileRaw = Path.GetFileNameWithoutExtension(file);
// SevenZip library doesnt like forward slashes for some reason
var outPath = $"{_tempFolder}\\{fileRaw}".Replace("/", "\\");
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
LoggerFactory.GetInstance().Log(
$"Unzipping {file} into temp path {outPath}, this may take a while...",
LogLevel.Info);
var extractor = new SevenZipExtractor(file);
// Only log process on debug mode
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Debug))
{
extractor.Extracting += (_, args) =>
{
if (args.PercentDone % 10 == 0)
LoggerFactory.GetInstance().Log($"Unzip progress: {args.PercentDone}%", LogLevel.Debug);
};
}
extractor.ExtractArchive(outPath);
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Info))
LoggerFactory.GetInstance().Log($"Finished unzipping {file} into temp path {outPath}", LogLevel.Info);
files = Directory.GetFiles(outPath).ToList();
directories = Directory.GetDirectories(outPath).ToList();
return true;
}
}

View File

@ -1,68 +0,0 @@
using LootDumpProcessor.Logger;
using LootDumpProcessor.Model.Tarkov;
using LootDumpProcessor.Serializers.Json;
namespace LootDumpProcessor.Process;
public class TarkovItems(string items)
{
private static readonly IJsonSerializer _jsonSerializer = JsonSerializerFactory.GetInstance();
private readonly Dictionary<string, TemplateFileItem>? _items = _jsonSerializer.Deserialize<Dictionary<string, TemplateFileItem>>(File.ReadAllText(items));
public virtual bool IsBaseClass(string tpl, string baseclass_id)
{
if (_items == null)
throw new Exception("The server items couldnt be found or loaded. Check server config is pointing to the correct place");
if (!_items.TryGetValue(tpl, out var item_template))
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Error))
LoggerFactory.GetInstance().Log($"[IsBaseClass] Item template '{tpl}' with base class id '{baseclass_id}' was not found on the server items!", LogLevel.Error);
return false;
}
if (string.IsNullOrEmpty(item_template.Parent))
return false;
return item_template.Parent == baseclass_id || IsBaseClass(item_template.Parent, baseclass_id);
}
public virtual bool IsQuestItem(string tpl)
{
if (_items == null)
throw new Exception("The server items couldnt be found or loaded. Check server config is pointing to the correct place");
if (!_items.TryGetValue(tpl, out var item_template))
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Error))
LoggerFactory.GetInstance().Log($"[IsQuestItem] Item template '{tpl}' was not found on the server items!", LogLevel.Error);
return false;
}
return item_template.Props.QuestItem;
}
public virtual string? MaxDurability(string tpl)
{
if (_items == null)
throw new Exception("The server items couldnt be found or loaded. Check server config is pointing to the correct place");
if (!_items.TryGetValue(tpl, out var item_template))
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Error))
LoggerFactory.GetInstance().Log($"[MaxDurability] Item template '{tpl}' was not found on the server items!", LogLevel.Error);
return null;
}
return item_template.Props.MaxDurability?.ToString() ?? "";
}
public virtual string? AmmoCaliber(string tpl)
{
if (_items == null)
throw new Exception("The server items couldnt be found or loaded. Check server config is pointing to the correct place");
if (!_items.TryGetValue(tpl, out var item_template))
{
if (LoggerFactory.GetInstance().CanBeLogged(LogLevel.Error))
LoggerFactory.GetInstance().Log($"[AmmoCaliber] Item template '{tpl}' was not found on the server items!", LogLevel.Error);
return null;
}
return item_template.Props.Caliber;
}
}

View File

@ -1,23 +0,0 @@
using LootDumpProcessor.Logger;
using LootDumpProcessor.Process;
using LootDumpProcessor.Storage;
namespace LootDumpProcessor;
public static class Program
{
public static void Main()
{
// Bootstrap the config before anything else, its required by the whole application to work
LootDumpProcessorContext.GetConfig();
// Some loggers may need a startup and stop mechanism
LoggerFactory.GetInstance().Setup();
// Setup Data storage
DataStorageFactory.GetInstance().Setup();
// startup the pipeline
PipelineFactory.GetInstance().DoProcess();
// stop loggers at the end
LoggerFactory.GetInstance().Stop();
Thread.Sleep(10000);
}
}

View File

@ -1,7 +0,0 @@
namespace LootDumpProcessor.Serializers;
public interface ISerializer
{
string Serialize<T>(T obj);
T? Deserialize<T>(string obj);
}

View File

@ -1,28 +0,0 @@
using System.Globalization;
using Newtonsoft.Json;
namespace LootDumpProcessor.Serializers.Json.Converters;
public class NewtonsoftDateTimeConverter : JsonConverter<DateTime>
{
private const string DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
public override void WriteJson(JsonWriter writer, DateTime value, JsonSerializer serializer)
{
writer.WriteValue(value.ToString(DateTimeFormat));
}
public override DateTime ReadJson(
JsonReader reader,
Type objectType,
DateTime existingValue,
bool hasExistingValue,
JsonSerializer serializer
)
{
var stringDate = reader.Value?.ToString() ?? "";
if (!DateTime.TryParseExact(stringDate, DateTimeFormat, null, DateTimeStyles.None, out var parsedDate))
throw new Exception($"Invalid value for DateTime format: {DateTimeFormat}");
return parsedDate;
}
}

Some files were not shown because too many files have changed in this diff Show More