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:
commit
5d2c0d04b1
3
.gitignore
vendored
3
.gitignore
vendored
@ -398,3 +398,6 @@ FodyWeavers.xsd
|
||||
|
||||
# JetBrains Rider
|
||||
*.sln.iml
|
||||
|
||||
# Qodo
|
||||
.qodo
|
@ -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
|
@ -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)
|
@ -1,9 +0,0 @@
|
||||
namespace LootDumpProcessor.Logger;
|
||||
|
||||
public interface ILogger
|
||||
{
|
||||
void Setup();
|
||||
void Log(string message, LogLevel level);
|
||||
bool CanBeLogged(LogLevel level);
|
||||
void Stop();
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
namespace LootDumpProcessor.Logger;
|
||||
|
||||
public enum LogLevel
|
||||
{
|
||||
Error,
|
||||
Warning,
|
||||
Info,
|
||||
Debug
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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>
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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();
|
||||
}
|
@ -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;
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
@ -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 });
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
36
Model/Upd.cs
36
Model/Upd.cs
@ -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)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace LootDumpProcessor.Process;
|
||||
|
||||
public static class PipelineFactory
|
||||
{
|
||||
public static IPipeline GetInstance()
|
||||
{
|
||||
// implement actual factory at some point
|
||||
return new QueuePipeline();
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
namespace LootDumpProcessor.Process.Processor.DumpProcessor;
|
||||
|
||||
public static class DumpProcessorFactory
|
||||
{
|
||||
|
||||
public static IDumpProcessor GetInstance()
|
||||
{
|
||||
// Implement real factory
|
||||
return new MultithreadSteppedDumpProcessor();
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
namespace LootDumpProcessor.Process.Reader.Filters;
|
||||
|
||||
public enum FileFilterTypes
|
||||
{
|
||||
JsonDump
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
namespace LootDumpProcessor.Process.Reader.Intake;
|
||||
|
||||
public enum IntakeReaderTypes
|
||||
{
|
||||
Json
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
namespace LootDumpProcessor.Process.Reader.PreProcess;
|
||||
|
||||
public enum PreProcessReaderTypes
|
||||
{
|
||||
SevenZip
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
23
Program.cs
23
Program.cs
@ -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);
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
namespace LootDumpProcessor.Serializers;
|
||||
|
||||
public interface ISerializer
|
||||
{
|
||||
string Serialize<T>(T obj);
|
||||
T? Deserialize<T>(string obj);
|
||||
}
|
@ -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
Loading…
x
Reference in New Issue
Block a user