Compare commits
5 Commits
5b0bf0ad93
...
9e6a4318c8
| Author | SHA1 | Date | |
|---|---|---|---|
| 9e6a4318c8 | |||
| e8c914e58a | |||
| 9b75392553 | |||
| 4999c3edca | |||
| 23367ba6cc |
@@ -0,0 +1,70 @@
|
||||
<h1 align="center">
|
||||
<b>UnlockedByDaylight</b>
|
||||
</h1>
|
||||
|
||||
<p align="center">
|
||||
Unlocks all perks, skins, items and addons
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
###### chatgpt generated instructions below
|
||||
|
||||
## Requirements
|
||||
|
||||
Before building the project, ensure you have the following installed on your system:
|
||||
|
||||
- **Git**: To clone the repository and its vendored submodules.
|
||||
- **Visual Studio 2022**: You must install the following workloads:
|
||||
- *Desktop development with C++*
|
||||
- *.NET desktop development* (for the C# dumper project)
|
||||
- **.NET 8.0 SDK**: Required for the dumper tools. Usually included with the Visual Studio .NET desktop development workload.
|
||||
- **CMake** `4.1.0` or newer: To generate the build files for the C++ unlocker proxy.
|
||||
- **OpenSSL**: Download and install the full (non-Light) 64-bit version from [Win32 OpenSSL](https://slproweb.com/products/Win32OpenSSL.html).
|
||||
- *Important*: You must install the **full version**, not the "Light" version, as the project requires the developer headers and libraries to compile (`find_package(OpenSSL REQUIRED)`).
|
||||
|
||||
## Building Instructions
|
||||
|
||||
The project uses several Git submodules (such as `nerutils`, `simdjson`, and `CUE4Parse`), so you must clone it recursively to pull all dependencies.
|
||||
|
||||
### Step 1: Clone the repository
|
||||
|
||||
Open your terminal or command prompt (such as PowerShell or Git Bash) and run:
|
||||
|
||||
```ps1
|
||||
git clone --recursive https://git.neru.rip/neru/UnlockedByDaylight.git
|
||||
cd UnlockedByDaylight
|
||||
```
|
||||
|
||||
*(Note: If you have already cloned the repository without the `--recursive` flag, you can fetch the submodules by running `git submodule update --init --recursive` inside the project folder).*
|
||||
|
||||
### Step 2: Generate project files using CMake
|
||||
|
||||
Generate the Visual Studio solution and project files in a `build` directory:
|
||||
|
||||
```ps1
|
||||
cmake -B build
|
||||
```
|
||||
|
||||
*(Note: Depending on how OpenSSL was installed, CMake usually detects it automatically. If it doesn't, ensure your OpenSSL installation is added to your system `PATH` or manually provide the path via CMake arguments).*
|
||||
|
||||
### Step 3: Compile the project
|
||||
|
||||
You can build the project directly from the command line using CMake, or open the generated solution file in Visual Studio.
|
||||
|
||||
**Option A: Command Line (Recommended)**
|
||||
```ps1
|
||||
cmake --build build --config Release
|
||||
```
|
||||
|
||||
**Option B: Visual Studio 2022**
|
||||
1. Navigate to the `build` folder.
|
||||
2. Open the newly generated `.sln` file (e.g., `dbd-unlocker.sln`).
|
||||
3. Set your build configuration to `Release` and architecture to `x64` in the top toolbar.
|
||||
4. Right-click the `dbd-unlocker` target in the Solution Explorer and select **Set as Startup Project**.
|
||||
5. Build the entire solution (Press `Ctrl + Shift + B`).
|
||||
|
||||
### Additional Notes
|
||||
|
||||
- **Resources**: When building the unlocker (`dbd-unlocker`), the JSON files inside the `res/` directory will be automatically copied into the target output directory as configured by the CMake post-build step.
|
||||
- Ensure you run the applications from folders where they have access to their respective resources.
|
||||
@@ -1,5 +1,77 @@
|
||||
{
|
||||
"Standard": [
|
||||
"Items": [
|
||||
"Addon_Firecracker_BlackPowder",
|
||||
"Addon_Firecracker_BuckShot",
|
||||
"Addon_Firecracker_FlashPowder",
|
||||
"Addon_Firecracker_GunPowder",
|
||||
"Addon_Firecracker_LargePack",
|
||||
"Addon_Firecracker_LongFuse",
|
||||
"Addon_Firecracker_MagnesiumPowder",
|
||||
"Addon_Firecracker_MediumFuse",
|
||||
"Addon_Flashlight_001",
|
||||
"Addon_Flashlight_002",
|
||||
"Addon_Flashlight_003",
|
||||
"Addon_Flashlight_004",
|
||||
"Addon_Flashlight_005",
|
||||
"Addon_Flashlight_006",
|
||||
"Addon_Flashlight_007",
|
||||
"Addon_Flashlight_008",
|
||||
"Addon_Flashlight_BrokenBulb",
|
||||
"ADDON_flashlight_highendsapphire",
|
||||
"ADDON_flashlight_intensehalogen",
|
||||
"ADDON_flashlight_lonflifebattery",
|
||||
"ADDON_flashlight_oddbulb",
|
||||
"ADDON_flashlight_rubbergrip",
|
||||
"Addon_FogVial_Accelerant",
|
||||
"Addon_FogVial_Amplifier",
|
||||
"Addon_FogVial_DenseFogExtract",
|
||||
"Addon_FogVial_LargeVial",
|
||||
"Addon_FogVial_SlowRelease",
|
||||
"Addon_Key_001",
|
||||
"Addon_Key_002",
|
||||
"Addon_Key_003",
|
||||
"Addon_Key_004",
|
||||
"Addon_Key_005",
|
||||
"Addon_Key_006",
|
||||
"Addon_Key_007",
|
||||
"Addon_Key_008",
|
||||
"Addon_Key_WeddingRing",
|
||||
"Addon_Map_001",
|
||||
"Addon_Map_002",
|
||||
"Addon_Map_003",
|
||||
"Addon_Map_004",
|
||||
"Addon_Map_005",
|
||||
"Addon_Map_006",
|
||||
"Addon_Map_007",
|
||||
"Addon_Map_008",
|
||||
"Addon_Map_009",
|
||||
"Addon_Medkit_001",
|
||||
"Addon_Medkit_002",
|
||||
"Addon_Medkit_003",
|
||||
"Addon_Medkit_004",
|
||||
"Addon_Medkit_005",
|
||||
"Addon_Medkit_006",
|
||||
"Addon_Medkit_007",
|
||||
"Addon_Medkit_008",
|
||||
"ADDON_medkit_abdominaldressing",
|
||||
"Addon_Medkit_BlightedSyringe",
|
||||
"ADDON_medkit_gauzeroll",
|
||||
"ADDON_medkit_needleandthread",
|
||||
"ADDON_medkit_selfadherentwrap",
|
||||
"ADDON_medkit_surgicalsuture",
|
||||
"Addon_Toolbox_001",
|
||||
"Addon_Toolbox_002",
|
||||
"Addon_Toolbox_003",
|
||||
"Addon_Toolbox_004",
|
||||
"Addon_Toolbox_005",
|
||||
"Addon_Toolbox_006",
|
||||
"Addon_Toolbox_007",
|
||||
"Addon_Toolbox_008",
|
||||
"ADDON_toolbox_cuttingwire",
|
||||
"ADDON_toolbox_socketswivels",
|
||||
"ADDON_toolbox_springclamp"
|
||||
],
|
||||
"Powers": [
|
||||
"Addon_Beartrap_001",
|
||||
"Addon_Beartrap_002",
|
||||
"Addon_Beartrap_003",
|
||||
@@ -105,25 +177,6 @@
|
||||
"Addon_DreamInducer_UnicornBlock",
|
||||
"Addon_DreamInducer_WoolShirt",
|
||||
"Addon_DreamInducer_ZBlock",
|
||||
"Addon_Flashlight_001",
|
||||
"Addon_Flashlight_002",
|
||||
"Addon_Flashlight_003",
|
||||
"Addon_Flashlight_004",
|
||||
"Addon_Flashlight_005",
|
||||
"Addon_Flashlight_006",
|
||||
"Addon_Flashlight_007",
|
||||
"Addon_Flashlight_008",
|
||||
"Addon_Flashlight_BrokenBulb",
|
||||
"ADDON_flashlight_highendsapphire",
|
||||
"ADDON_flashlight_intensehalogen",
|
||||
"ADDON_flashlight_lonflifebattery",
|
||||
"ADDON_flashlight_oddbulb",
|
||||
"ADDON_flashlight_rubbergrip",
|
||||
"Addon_FogVial_Accelerant",
|
||||
"Addon_FogVial_Amplifier",
|
||||
"Addon_FogVial_DenseFogExtract",
|
||||
"Addon_FogVial_LargeVial",
|
||||
"Addon_FogVial_SlowRelease",
|
||||
"ADDON_Frenzy_ColdDirt",
|
||||
"ADDON_Frenzy_DefacedSmileyPin",
|
||||
"ADDON_Frenzy_EtchedRuler",
|
||||
@@ -163,7 +216,10 @@
|
||||
"Addon_GasBomb_17",
|
||||
"Addon_GasBomb_18",
|
||||
"Addon_GasBomb_19",
|
||||
"Addon_GasBomb_19a",
|
||||
"Addon_GasBomb_20",
|
||||
"Addon_GasBomb_20a",
|
||||
"Addon_GasBomb_20b",
|
||||
"Addon_Ghost_CheapCologne",
|
||||
"Addon_Ghost_ChewedPen",
|
||||
"Addon_Ghost_DriversLicense",
|
||||
@@ -625,15 +681,6 @@
|
||||
"Addon_Kanobo_WoodenOniMask",
|
||||
"Addon_Kanobo_YamaokaFamilyCrest",
|
||||
"Addon_Kanobo_YamaokaSashimono",
|
||||
"Addon_Key_001",
|
||||
"Addon_Key_002",
|
||||
"Addon_Key_003",
|
||||
"Addon_Key_004",
|
||||
"Addon_Key_005",
|
||||
"Addon_Key_006",
|
||||
"Addon_Key_007",
|
||||
"Addon_Key_008",
|
||||
"Addon_Key_WeddingRing",
|
||||
"Addon_Killer_Halloween2020",
|
||||
"ADDON_Lastbreath_AtaxicRespiration",
|
||||
"ADDON_Lastbreath_BadManLastBreath",
|
||||
@@ -663,29 +710,6 @@
|
||||
"ADDON_LFChainsaw_SpeedLimiter",
|
||||
"ADDON_LFChainsaw_TheGrease",
|
||||
"ADDON_LFChainsaw_VegetableOil",
|
||||
"Addon_Map_001",
|
||||
"Addon_Map_002",
|
||||
"Addon_Map_003",
|
||||
"Addon_Map_004",
|
||||
"Addon_Map_005",
|
||||
"Addon_Map_006",
|
||||
"Addon_Map_007",
|
||||
"Addon_Map_008",
|
||||
"Addon_Map_009",
|
||||
"Addon_Medkit_001",
|
||||
"Addon_Medkit_002",
|
||||
"Addon_Medkit_003",
|
||||
"Addon_Medkit_004",
|
||||
"Addon_Medkit_005",
|
||||
"Addon_Medkit_006",
|
||||
"Addon_Medkit_007",
|
||||
"Addon_Medkit_008",
|
||||
"ADDON_medkit_abdominaldressing",
|
||||
"Addon_Medkit_BlightedSyringe",
|
||||
"ADDON_medkit_gauzeroll",
|
||||
"ADDON_medkit_needleandthread",
|
||||
"ADDON_medkit_selfadherentwrap",
|
||||
"ADDON_medkit_surgicalsuture",
|
||||
"Addon_PhantomTrap_BloodiedMud",
|
||||
"Addon_PhantomTrap_BloodiedWater",
|
||||
"Addon_PhantomTrap_BogWater",
|
||||
@@ -846,17 +870,6 @@
|
||||
"Addon_TheOnryo_18",
|
||||
"Addon_TheOnryo_19",
|
||||
"Addon_TheOnryo_20",
|
||||
"Addon_Toolbox_001",
|
||||
"Addon_Toolbox_002",
|
||||
"Addon_Toolbox_003",
|
||||
"Addon_Toolbox_004",
|
||||
"Addon_Toolbox_005",
|
||||
"Addon_Toolbox_006",
|
||||
"Addon_Toolbox_007",
|
||||
"Addon_Toolbox_008",
|
||||
"ADDON_toolbox_cuttingwire",
|
||||
"ADDON_toolbox_socketswivels",
|
||||
"ADDON_toolbox_springclamp",
|
||||
"ADDON_TormentMode_BlackStrap",
|
||||
"ADDON_TormentMode_BurningManPainting",
|
||||
"ADDON_TormentMode_CinderellaMusicBox",
|
||||
@@ -903,6 +916,5 @@
|
||||
"Addon_Trickster_18",
|
||||
"Addon_Trickster_19",
|
||||
"Addon_Trickster_20"
|
||||
],
|
||||
"Special": []
|
||||
]
|
||||
}
|
||||
@@ -1,52 +1,58 @@
|
||||
{
|
||||
"Standard": [
|
||||
"Items": [
|
||||
"FireflyLantern",
|
||||
"Item_Camper_AlexsToolbox",
|
||||
"Item_Camper_AnniversaryToolbox",
|
||||
"Item_Camper_BeigeMap",
|
||||
"Item_Camper_BrokenKey",
|
||||
"Item_Camper_CommodiousToolbox",
|
||||
"Item_Camper_ContaminationSerum",
|
||||
"Item_Camper_DullKey",
|
||||
"Item_Camper_EngineerToolbox",
|
||||
"Item_Camper_FadedMap",
|
||||
"Item_Camper_Firecracker_Anniversary2019",
|
||||
"Item_Camper_Firecracker_Chinese",
|
||||
"Item_Camper_Firecracker_Flashbang",
|
||||
"Item_Camper_Firecracker_WinterEvent",
|
||||
"Item_Camper_Flashlight",
|
||||
"Item_Camper_Flashlight_Anniversary2020",
|
||||
"Item_Camper_Flashlight_Anniversary2022",
|
||||
"Item_Camper_Flashlight_Random",
|
||||
"Item_Camper_Flashlight02",
|
||||
"Item_Camper_Flashlight03",
|
||||
"Item_Camper_Flashlight04",
|
||||
"Item_Camper_JerryCan_Spring2025",
|
||||
"Item_Camper_K29InfectionRemover",
|
||||
"Item_Camper_K32Emp",
|
||||
"Item_Camper_Key",
|
||||
"Item_Camper_Key_Random",
|
||||
"Item_Camper_LunarToolbox",
|
||||
"Item_Camper_Map_Random",
|
||||
"Item_Camper_Map_Spring2024",
|
||||
"Item_Camper_MechanicsToolbox",
|
||||
"Item_Camper_MedKit",
|
||||
"Item_Camper_Medkit_Anniversary2020",
|
||||
"Item_Camper_Medkit_Anniversary2022",
|
||||
"Item_Camper_MedKit_Random",
|
||||
"Item_Camper_MedKit02",
|
||||
"Item_Camper_MedKit03",
|
||||
"Item_Camper_MedKit04",
|
||||
"Item_Camper_Medkit05",
|
||||
"Item_Camper_OnryoTape",
|
||||
"Item_Camper_RainbowMap",
|
||||
"Item_Camper_Toolbox",
|
||||
"Item_Camper_Toolbox_Anniversary2022",
|
||||
"Item_Camper_Toolbox_Random",
|
||||
"Item_Camper_VoidBomb_Halloween2024",
|
||||
"Item_Camper_WornoutToolbox",
|
||||
"Item_Slasher_K24Power",
|
||||
"Item_Slasher_K29Power",
|
||||
"Item_Slasher_ThrowingKnives",
|
||||
"Item_FragileObject",
|
||||
"Item_Survivor_CalamariContaminationAntidote",
|
||||
"Item_Survivor_K41Mushroom",
|
||||
"Item_Survivor_MakeshiftFogVial",
|
||||
"Item_Survivor_PrototypeFogVial",
|
||||
"Item_Survivor_VigosFogVial"
|
||||
],
|
||||
"Special": [
|
||||
"FireflyLantern",
|
||||
"Item_Blighted_Serum",
|
||||
"Item_Camper_Flashlight_Random",
|
||||
"Item_Camper_Key_Random",
|
||||
"Item_Camper_Map_Random",
|
||||
"Item_Camper_MedKit_Random",
|
||||
"Item_Camper_Toolbox_Random",
|
||||
"Powers": [
|
||||
"Item_Slasher_Beartrap",
|
||||
"Item_Slasher_Blinker",
|
||||
"Item_Slasher_Chainsaw",
|
||||
@@ -59,10 +65,12 @@
|
||||
"Item_Slasher_Hatchet",
|
||||
"Item_Slasher_K21Power",
|
||||
"Item_Slasher_K22Power",
|
||||
"Item_Slasher_K24Power",
|
||||
"Item_Slasher_K25Power",
|
||||
"Item_Slasher_K26Power",
|
||||
"Item_Slasher_K27Power",
|
||||
"Item_Slasher_K28Power",
|
||||
"Item_Slasher_K29Power",
|
||||
"Item_Slasher_K30Power",
|
||||
"Item_Slasher_K31Power",
|
||||
"Item_Slasher_K32Power",
|
||||
@@ -85,7 +93,7 @@
|
||||
"Item_Slasher_QatarKillerPower",
|
||||
"Item_Slasher_ReverseBearTrap",
|
||||
"Item_Slasher_Stalker",
|
||||
"Item_Slasher_TormentMode",
|
||||
"Item_Survivor_K41Mushroom"
|
||||
"Item_Slasher_ThrowingKnives",
|
||||
"Item_Slasher_TormentMode"
|
||||
]
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
{
|
||||
"Standard": [
|
||||
"Anniversary2019Offering",
|
||||
"Anniversary2020Offering",
|
||||
"Anniversary2021Offering",
|
||||
"Anniversary2022Offering",
|
||||
"Anniversary2023Offering",
|
||||
"Anniversary2024Offering",
|
||||
"Anniversary2025Offering",
|
||||
"AnnotatedBlueprint",
|
||||
"ArdentRavenWreath",
|
||||
"ArdentShrikeWreath",
|
||||
"ArdentSpottedowlWreath",
|
||||
"ArdentTanagerWreath",
|
||||
"AzarovKey",
|
||||
"BlackSaltStatuette",
|
||||
"BlackWard",
|
||||
"BloodiedBlueprint",
|
||||
"BloodyPartyStreamers",
|
||||
"BogLaurelSachet",
|
||||
"BoundEnvelope",
|
||||
"ChalkPouch",
|
||||
"CharredWeddingPhotograph",
|
||||
"ClearReagent",
|
||||
"CreamChalkPouch",
|
||||
"CrispleafAmaranthSachet",
|
||||
"CutCoin",
|
||||
"CypressMementoMori",
|
||||
"DevoutRavenWreath",
|
||||
"DevoutShrikeWreath",
|
||||
"DevoutSpottedowlWreath",
|
||||
"DevoutTanagerWreath",
|
||||
"EbonyMementoMori",
|
||||
"EclipseThemeOffering",
|
||||
"EscapeCake",
|
||||
"FaintReagent",
|
||||
"FragrantBogLaurel",
|
||||
"FragrantCrispleafAmaranth",
|
||||
"FragrantPrimroseBlossom",
|
||||
"FragrantSweetWilliam",
|
||||
"FreshBogLaurel",
|
||||
"FreshCrispleafAmaranth",
|
||||
"FreshPrimroseBlossom",
|
||||
"FreshSweetWilliam",
|
||||
"GranmasCookbook",
|
||||
"Halloween2021Offering",
|
||||
"Halloween2022Offering",
|
||||
"HalloweenOffering",
|
||||
"HazyReagent",
|
||||
"HeartLocket",
|
||||
"HollowShell",
|
||||
"IonThemeOffering",
|
||||
"IvoryChalkPouch",
|
||||
"IvoryMementoMori",
|
||||
"JapaneseCountrySide",
|
||||
"Jigsawpiece",
|
||||
"KenyaThemeOffering",
|
||||
"MacMillanPhalanxBone",
|
||||
"MeteorThemeOffering",
|
||||
"MoldyOak",
|
||||
"MurkyReagent",
|
||||
"PetrifiedOak",
|
||||
"PrimroseBlossomSachet",
|
||||
"PutridOak",
|
||||
"QatarThemeOffering",
|
||||
"QuantumThemeOffering",
|
||||
"QuicheThemeOffering",
|
||||
"RavenWreath",
|
||||
"RedMoney",
|
||||
"RottenOak",
|
||||
"SacrificalWard",
|
||||
"SaltPouch",
|
||||
"ScratchedCoin",
|
||||
"SealedEnvelope",
|
||||
"ShatteredGlasses",
|
||||
"ShinyCoin",
|
||||
"ShrikeWreath",
|
||||
"ShroudofBinding",
|
||||
"ShroudofSeparation",
|
||||
"ShroudofUnion",
|
||||
"SpottedOwlWreath",
|
||||
"Spring2024Offering",
|
||||
"SummerOffering",
|
||||
"SurvivorPudding",
|
||||
"SweetWilliamSachet",
|
||||
"TanagerWreath",
|
||||
"TarnishedCoin",
|
||||
"TheLastMask",
|
||||
"ThePiedPiper",
|
||||
"TornBlueprint",
|
||||
"UkraineThemeOffering",
|
||||
"UmbraThemeOffering",
|
||||
"VigosBlueprint",
|
||||
"VigosJarOfSaltyLips",
|
||||
"VigosShroud",
|
||||
"WalesThemeOffering",
|
||||
"WhiteWard",
|
||||
"Winter2024Offering",
|
||||
"WormholeThemeOffering"
|
||||
],
|
||||
"Special": [
|
||||
"BlackSplinter",
|
||||
"BoneSplinter",
|
||||
"CattleTag28",
|
||||
"ChildrensBook",
|
||||
"ColdwindCattleTag81",
|
||||
"CrescentMoonBouquet",
|
||||
"DecrepitClapboard",
|
||||
"EmergencyCertificate",
|
||||
"FullMoonBouquet",
|
||||
"FumingCordage",
|
||||
"FumingWelcomeSign",
|
||||
"GlassSplinter",
|
||||
"HarvestFestivalLeaflet",
|
||||
"LunacyTicket",
|
||||
"MacmillanLedgerPage",
|
||||
"MuddySplinter",
|
||||
"NewMoonBouquet",
|
||||
"PaintedRiverRock",
|
||||
"PElliotLunacyTicket",
|
||||
"PsychiatricAssessmentReport",
|
||||
"QuarterMoonBouquet",
|
||||
"ShockSplinter",
|
||||
"ShreddedPlate",
|
||||
"SignedLedgerPage",
|
||||
"SmokingSplinter",
|
||||
"StrodeRealtyKey",
|
||||
"VirginiaPlate"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
[
|
||||
"BoneSplinter",
|
||||
"ArdentRavenWreath",
|
||||
"ArdentShrikeWreath",
|
||||
"ArdentSpottedowlWreath",
|
||||
"ArdentTanagerWreath",
|
||||
"AzarovKey",
|
||||
"BlackSaltStatuette",
|
||||
"BlackWard",
|
||||
"BogLaurelSachet",
|
||||
"BoundEnvelope",
|
||||
"CattleTag28",
|
||||
"ChalkPouch",
|
||||
"CharredWeddingPhotograph",
|
||||
"ClearReagent",
|
||||
"ColdwindCattleTag81",
|
||||
"CreamChalkPouch",
|
||||
"CrescentMoonBouquet",
|
||||
"CrispleafAmaranthSachet",
|
||||
"CutCoin",
|
||||
"CypressMementoMori",
|
||||
"DevoutRavenWreath",
|
||||
"DevoutShrikeWreath",
|
||||
"DevoutSpottedowlWreath",
|
||||
"DevoutTanagerWreath",
|
||||
"EbonyMementoMori",
|
||||
"FaintReagent",
|
||||
"FragrantBogLaurel",
|
||||
"FragrantCrispleafAmaranth",
|
||||
"FragrantPrimroseBlossom",
|
||||
"FragrantSweetWilliam",
|
||||
"FreshBogLaurel",
|
||||
"FreshCrispleafAmaranth",
|
||||
"FreshPrimroseBlossom",
|
||||
"FreshSweetWilliam",
|
||||
"FullMoonBouquet",
|
||||
"HazyReagent",
|
||||
"HeartLocket",
|
||||
"HollowShell",
|
||||
"IvoryChalkPouch",
|
||||
"IvoryMementoMori",
|
||||
"LunacyTicket",
|
||||
"MacmillanLedgerPage",
|
||||
"MacMillanPhalanxBone",
|
||||
"MoldyOak",
|
||||
"MurkyReagent",
|
||||
"NewMoonBouquet",
|
||||
"PElliotLunacyTicket",
|
||||
"PetrifiedOak",
|
||||
"PrimroseBlossomSachet",
|
||||
"PutridOak",
|
||||
"QuarterMoonBouquet",
|
||||
"RavenWreath",
|
||||
"RottenOak",
|
||||
"SaltPouch",
|
||||
"ScratchedCoin",
|
||||
"SealedEnvelope",
|
||||
"ShinyCoin",
|
||||
"ShreddedPlate",
|
||||
"ShrikeWreath",
|
||||
"ShroudofBinding",
|
||||
"ShroudofSeparation",
|
||||
"ShroudofUnion",
|
||||
"SignedLedgerPage",
|
||||
"SpottedOwlWreath",
|
||||
"SweetWilliamSachet",
|
||||
"TanagerWreath",
|
||||
"TarnishedCoin",
|
||||
"VigosShroud",
|
||||
"VirginiaPlate",
|
||||
"WhiteWard",
|
||||
"VigosJarOfSaltyLips",
|
||||
"MuddySplinter",
|
||||
"FumingCordage",
|
||||
"FumingWelcomeSign",
|
||||
"GranmasCookbook",
|
||||
"EscapeCake",
|
||||
"SurvivorPudding",
|
||||
"BloodyPartyStreamers",
|
||||
"Anniversary2019Offering",
|
||||
"Anniversary2022Offering",
|
||||
"Anniversary2024Offering",
|
||||
"Winter2024Offering",
|
||||
"Spring2024Offering",
|
||||
"Anniversary2025Offering",
|
||||
"Anniversary2023Offering",
|
||||
"Halloween2022Offering",
|
||||
"Halloween2021Offering",
|
||||
"PaintedRiverRock",
|
||||
"ChildrensBook",
|
||||
"TheLastMask",
|
||||
"Anniversary2021Offering",
|
||||
"SummerOffering",
|
||||
"QatarThemeOffering",
|
||||
"RedMoney",
|
||||
"SmokingSplinter",
|
||||
"ThePiedPiper",
|
||||
"QuicheThemeOffering",
|
||||
"WormholeThemeOffering",
|
||||
"Anniversary2020Offering",
|
||||
"BlackSplinter",
|
||||
"StrodeRealtyKey",
|
||||
"DecrepitClapboard",
|
||||
"HarvestFestivalLeaflet",
|
||||
"ShockSplinter",
|
||||
"EmergencyCertificate",
|
||||
"PsychiatricAssessmentReport",
|
||||
"ShatteredGlasses",
|
||||
"HalloweenOffering",
|
||||
"UmbraThemeOffering",
|
||||
"QuantumThemeOffering",
|
||||
"KenyaThemeOffering",
|
||||
"EclipseThemeOffering",
|
||||
"IonThemeOffering",
|
||||
"GlassSplinter",
|
||||
"Jigsawpiece",
|
||||
"JapaneseCountrySide",
|
||||
"MeteorThemeOffering",
|
||||
"UkraineThemeOffering",
|
||||
"SacrificalWard",
|
||||
"TornBlueprint",
|
||||
"BloodiedBlueprint",
|
||||
"VigosBlueprint",
|
||||
"AnnotatedBlueprint",
|
||||
"WalesThemeOffering"
|
||||
]
|
||||
+313
@@ -0,0 +1,313 @@
|
||||
[
|
||||
"S45P01",
|
||||
"S45P02",
|
||||
"S45P03",
|
||||
"K38P01",
|
||||
"K38P02",
|
||||
"K38P03",
|
||||
"K37P01",
|
||||
"K37P02",
|
||||
"K37P03",
|
||||
"TacticianBlastMine_Calamari",
|
||||
"TacticianWireTap_Calamari",
|
||||
"BetterTogether",
|
||||
"Fixated",
|
||||
"InnerStrength",
|
||||
"S24P01",
|
||||
"S24P02",
|
||||
"S24P03",
|
||||
"S31P01",
|
||||
"S31P02",
|
||||
"S31P03",
|
||||
"S32P01",
|
||||
"S32P02",
|
||||
"S32P03",
|
||||
"Solidarity",
|
||||
"Poised",
|
||||
"HeadOn",
|
||||
"S29P01",
|
||||
"S29P02",
|
||||
"S29P03",
|
||||
"S27P01",
|
||||
"S27P02",
|
||||
"S27P03",
|
||||
"LuckyBreak",
|
||||
"AnyMeansNecessary",
|
||||
"Breakout",
|
||||
"DeadHard",
|
||||
"NoMither",
|
||||
"WereGonnaLiveForever",
|
||||
"S26P01",
|
||||
"S26P02",
|
||||
"S26P03",
|
||||
"S35P01",
|
||||
"S35P02",
|
||||
"S35P03",
|
||||
"S39P01",
|
||||
"S39P02",
|
||||
"S39P03",
|
||||
"FlipFlop",
|
||||
"BuckleUp",
|
||||
"TheMettleOfMan",
|
||||
"Babysitter",
|
||||
"Camaraderie",
|
||||
"SecondWind",
|
||||
"K27P01",
|
||||
"K27P02",
|
||||
"K27P03",
|
||||
"Ace_In_The_Hole",
|
||||
"Open_Handed",
|
||||
"Up_The_Ante",
|
||||
"Thanatophobia",
|
||||
"NurseCalling",
|
||||
"Stridor",
|
||||
"K33P01",
|
||||
"K33P02",
|
||||
"K33P03",
|
||||
"WindowsOfOpportunity",
|
||||
"BoilOver",
|
||||
"Dance_with_me",
|
||||
"OverwhelmingPresence",
|
||||
"MonitorAndAbuse",
|
||||
"GeneratorOvercharge",
|
||||
"K29P01",
|
||||
"K29P02",
|
||||
"K29P03",
|
||||
"Adrenaline",
|
||||
"QuickQuiet",
|
||||
"Sprint_Burst",
|
||||
"Balanced_Landing",
|
||||
"Urban_Evasion",
|
||||
"Streetwise",
|
||||
"S34P01",
|
||||
"S34P02",
|
||||
"S34P03",
|
||||
"S33P01",
|
||||
"S33P02",
|
||||
"S33P03",
|
||||
"S25P01",
|
||||
"S25P02",
|
||||
"S25P03",
|
||||
"Breakdown",
|
||||
"Aftercare",
|
||||
"Distortion",
|
||||
"BBQAndChilli",
|
||||
"InTheDark",
|
||||
"FranklinsLoss",
|
||||
"HangmansTrick",
|
||||
"Surveillance",
|
||||
"MakeYourChoice",
|
||||
"BorrowedTime",
|
||||
"SelfSufficient",
|
||||
"LeftBehind",
|
||||
"BeastOfPrey",
|
||||
"Hex_HuntressLullaby",
|
||||
"TerritorialImperative",
|
||||
"Botany_Knowledge",
|
||||
"Empathy",
|
||||
"Self_Care",
|
||||
"OffTheRecord",
|
||||
"RedHerring",
|
||||
"ForThePeople",
|
||||
"K24P01",
|
||||
"K24P02",
|
||||
"K24P03",
|
||||
"S38P01",
|
||||
"S38P02",
|
||||
"S38P03",
|
||||
"BloodHound",
|
||||
"Predator",
|
||||
"Shadowborn",
|
||||
"ImAllEars",
|
||||
"ThrillingTremors",
|
||||
"FurtiveChase",
|
||||
"S41P01",
|
||||
"S41P02",
|
||||
"S41P03",
|
||||
"SoleSurvivor",
|
||||
"DecisiveStrike",
|
||||
"ObjectOfObsession",
|
||||
"K34P01",
|
||||
"K34P02",
|
||||
"K34P03",
|
||||
"K23P01",
|
||||
"K23P02",
|
||||
"K23P03",
|
||||
"K30P01",
|
||||
"K30P02",
|
||||
"K30P03",
|
||||
"Visionary",
|
||||
"DesperateMeasures",
|
||||
"BuiltToLast",
|
||||
"Bond",
|
||||
"Leader",
|
||||
"Prove_Thyself",
|
||||
"CorruptIntervention",
|
||||
"InfectiousFright",
|
||||
"DarkDevotion",
|
||||
"S49P01",
|
||||
"S49P02",
|
||||
"S49P03",
|
||||
"K41P01",
|
||||
"K41P02",
|
||||
"K41P03",
|
||||
"SoulGuard",
|
||||
"BloodPact",
|
||||
"RepressedAlliance",
|
||||
"Discordance",
|
||||
"MadGrit",
|
||||
"Ironmaiden",
|
||||
"S30P01",
|
||||
"S30P02",
|
||||
"S30P03",
|
||||
"K42P01",
|
||||
"K42P02",
|
||||
"K42P03",
|
||||
"K35P01",
|
||||
"K35P02",
|
||||
"K35P03",
|
||||
"S46P01",
|
||||
"S46P02",
|
||||
"S46P03",
|
||||
"S28P01",
|
||||
"S28P02",
|
||||
"S28P03",
|
||||
"ZanshinTactics",
|
||||
"BloodEcho",
|
||||
"Nemesis",
|
||||
"S42P01",
|
||||
"S42P02",
|
||||
"S42P03",
|
||||
"S51P01",
|
||||
"S51P02",
|
||||
"S51P03",
|
||||
"S50P01",
|
||||
"S50P02",
|
||||
"S50P03",
|
||||
"Calm_Spirit",
|
||||
"Iron_Will",
|
||||
"Saboteur",
|
||||
"K32P01",
|
||||
"K32P02",
|
||||
"K32P03",
|
||||
"S52P01",
|
||||
"S52P02",
|
||||
"S52P03",
|
||||
"BloodWarden",
|
||||
"FireUp",
|
||||
"RememberMe",
|
||||
"ForcedPenance",
|
||||
"TrailofTorment",
|
||||
"Deathbound",
|
||||
"S37P01",
|
||||
"S37P02",
|
||||
"S37P03",
|
||||
"S47P01",
|
||||
"S47P02",
|
||||
"S47P03",
|
||||
"Save_The_Best_For_Last",
|
||||
"Dying_Light",
|
||||
"Play_With_Your_Food",
|
||||
"S48P01",
|
||||
"S48P02",
|
||||
"S48P03",
|
||||
"Technician",
|
||||
"Lithe",
|
||||
"Alert",
|
||||
"Pharmacy",
|
||||
"Vigil",
|
||||
"WakeUp",
|
||||
"Diversion",
|
||||
"Deliverance",
|
||||
"Autodidact",
|
||||
"S40P01",
|
||||
"S40P02",
|
||||
"S40P03",
|
||||
"S36P01",
|
||||
"S36P02",
|
||||
"S36P03",
|
||||
"K25P01",
|
||||
"K25P02",
|
||||
"K25P03",
|
||||
"K31P01",
|
||||
"K31P02",
|
||||
"K31P03",
|
||||
"S43P01",
|
||||
"S43P02",
|
||||
"S43P03",
|
||||
"K28P01",
|
||||
"K28P02",
|
||||
"K28P03",
|
||||
"K39P01",
|
||||
"K39P02",
|
||||
"K39P03",
|
||||
"K40P01",
|
||||
"K40P02",
|
||||
"K40P03",
|
||||
"Surge",
|
||||
"Mindbreaker",
|
||||
"CruelConfinement",
|
||||
"Tenacity",
|
||||
"DetectivesHunch",
|
||||
"StakeOut",
|
||||
"K36P01",
|
||||
"K36P02",
|
||||
"K36P03",
|
||||
"S44P01",
|
||||
"S44P02",
|
||||
"S44P03",
|
||||
"Agitation",
|
||||
"Bitter_Murmur",
|
||||
"Brutal_Strength",
|
||||
"Dark_Sense",
|
||||
"Deerstalker",
|
||||
"Deja_Vu",
|
||||
"Distressing",
|
||||
"Enduring",
|
||||
"Hex_Devour_Hope",
|
||||
"Hex_Ruin",
|
||||
"Hex_The_Third_Seal",
|
||||
"Hex_Thrill_Of_The_Hunt",
|
||||
"Hope",
|
||||
"Insidious",
|
||||
"Iron_Grasp",
|
||||
"Kindred",
|
||||
"Lightborn",
|
||||
"Lightweight",
|
||||
"Monstrous_Shrine",
|
||||
"No_One_Escapes_Death",
|
||||
"No_One_Left_Behind",
|
||||
"Plunderers_Instinct",
|
||||
"Premonition",
|
||||
"Resilience",
|
||||
"Slippery_Meat",
|
||||
"Sloppy_Butcher",
|
||||
"Small_Game",
|
||||
"Spies_From_The_Shadows",
|
||||
"Spine_Chill",
|
||||
"This_Is_Not_Happening",
|
||||
"Tinkerer",
|
||||
"Unnerving_Presence",
|
||||
"Unrelenting",
|
||||
"WellMakeIt",
|
||||
"Whispers",
|
||||
"K22P01",
|
||||
"K22P02",
|
||||
"K22P03",
|
||||
"K26P01",
|
||||
"K26P02",
|
||||
"K26P03",
|
||||
"SpiritFury",
|
||||
"Hex_HauntedGround",
|
||||
"Rancor",
|
||||
"BoonDestroyer",
|
||||
"Gearhead",
|
||||
"DeadMansSwitch",
|
||||
"HexRetribution",
|
||||
"Coulrophobia",
|
||||
"pop_goes_the_weasel",
|
||||
"Bamboozle",
|
||||
"DragonsGrip",
|
||||
"HexUndying",
|
||||
"HexBloodFavor"
|
||||
]
|
||||
+102
-41
@@ -4,15 +4,10 @@ using CUE4Parse.FileProvider;
|
||||
using CUE4Parse.MappingsProvider;
|
||||
using CUE4Parse.UE4.Assets.Exports.Engine;
|
||||
using CUE4Parse.UE4.Assets.Exports.Texture;
|
||||
using CUE4Parse.UE4.Assets.Objects.Properties;
|
||||
using CUE4Parse.UE4.Objects.Core.Misc;
|
||||
using CUE4Parse.UE4.Objects.UObject;
|
||||
using CUE4Parse.UE4.Versions;
|
||||
using CUE4Parse.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
class DumpByDaylight
|
||||
@@ -55,7 +50,7 @@ class DumpByDaylight
|
||||
}
|
||||
|
||||
ZlibHelper.Initialize();
|
||||
|
||||
|
||||
var oodlePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, OodleHelper.OodleFileName);
|
||||
OodleHelper.Initialize(oodlePath);
|
||||
|
||||
@@ -71,56 +66,122 @@ class DumpByDaylight
|
||||
|
||||
Console.WriteLine("\nProvider Initialized. Extracting Databases...");
|
||||
|
||||
string[] dbNames = { "ItemDB", "OfferingDB", "ItemAddonDB" };
|
||||
var dataPak = provider.GetArchive("pakchunk4-Windows.utoc");
|
||||
|
||||
foreach (var dbName in dbNames)
|
||||
/*
|
||||
* itemdb dump
|
||||
*/
|
||||
var searchPaths = dataPak.Files.Keys.Where(x => x.Contains($"/ItemDB.uasset", StringComparison.OrdinalIgnoreCase)).ToList();
|
||||
var items = new List<string>();
|
||||
var powers = new List<string>();
|
||||
|
||||
foreach (var path in searchPaths)
|
||||
{
|
||||
var searchPaths = dataPak.Files.Keys
|
||||
.Where(x => x.Contains($"/{dbName}.uasset", StringComparison.OrdinalIgnoreCase))
|
||||
.ToList();
|
||||
|
||||
var standard = new List<string>();
|
||||
var special = new List<string>();
|
||||
|
||||
foreach (var path in searchPaths)
|
||||
var cleanPath = path.Contains('.') ? path.Substring(0, path.LastIndexOf('.')) : path;
|
||||
if (provider.TryLoadPackageObject<UDataTable>(cleanPath, out var dataTable))
|
||||
{
|
||||
var cleanPath = path.Contains('.') ? path.Substring(0, path.LastIndexOf('.')) : path;
|
||||
Console.WriteLine($"getting items / powers from {Path.GetFileName(path)}");
|
||||
|
||||
if (provider.TryLoadPackageObject<UDataTable>(cleanPath, out var dataTable))
|
||||
foreach (var row in dataTable.RowMap)
|
||||
{
|
||||
Console.WriteLine($"- Processing {dbName} (from {Path.GetFileName(path)})...");
|
||||
foreach (var row in dataTable.RowMap)
|
||||
var typeProperty = row.Value.Properties.FirstOrDefault(p => p.Name.Text == "Type");
|
||||
if (typeProperty?.Tag is EnumProperty enumProp)
|
||||
{
|
||||
bool isInventory = row.Value.GetOrDefault<bool>("Inventory");
|
||||
bool isBloodweb = row.Value.GetOrDefault<bool>("Bloodweb");
|
||||
string typeName = enumProp.Value.ToString() ?? "null";
|
||||
|
||||
if (isBloodweb)
|
||||
{
|
||||
standard.Add(row.Key.Text);
|
||||
}
|
||||
else if (isInventory)
|
||||
{
|
||||
special.Add(row.Key.Text);
|
||||
}
|
||||
if (typeName == "EInventoryItemType::Power")
|
||||
powers.Add(row.Key.Text);
|
||||
else if (typeName == "EInventoryItemType::Item")
|
||||
items.Add(row.Key.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (standard.Count > 0 || special.Count > 0)
|
||||
var itemsSerialized = new
|
||||
{
|
||||
Items = items.OrderBy(x => x).ToList(),
|
||||
Powers = powers.OrderBy(x => x).ToList()
|
||||
};
|
||||
File.WriteAllText("items.json", JsonConvert.SerializeObject(itemsSerialized, Formatting.Indented));
|
||||
|
||||
/*
|
||||
* addon dump
|
||||
*/
|
||||
searchPaths = dataPak.Files.Keys.Where(x => x.Contains($"/ItemAddonDB.uasset", StringComparison.OrdinalIgnoreCase)).ToList();
|
||||
var itemAddons = new List<string>();
|
||||
var powerAddons = new List<string>();
|
||||
|
||||
foreach (var path in searchPaths)
|
||||
{
|
||||
var cleanPath = path.Contains('.') ? path.Substring(0, path.LastIndexOf('.')) : path;
|
||||
if (provider.TryLoadPackageObject<UDataTable>(cleanPath, out var dataTable))
|
||||
{
|
||||
var result = new
|
||||
{
|
||||
Standard = standard.OrderBy(x => x).ToList(),
|
||||
Special = special.OrderBy(x => x).ToList()
|
||||
};
|
||||
Console.WriteLine($"getting item / power addons from {Path.GetFileName(path)}");
|
||||
|
||||
string outputPath = $"{dbName}_Names.json";
|
||||
File.WriteAllText(outputPath, JsonConvert.SerializeObject(result, Formatting.Indented));
|
||||
Console.WriteLine($" -> Saved {standard.Count} standard and {special.Count} special entries to {outputPath}");
|
||||
foreach (var row in dataTable.RowMap)
|
||||
{
|
||||
var typeProperty = row.Value.Properties.FirstOrDefault(p => p.Name.Text == "Type");
|
||||
if (typeProperty?.Tag is EnumProperty enumProp)
|
||||
{
|
||||
string typeName = enumProp.Value.ToString() ?? "null";
|
||||
|
||||
if (typeName == "EInventoryItemType::ItemAddOn")
|
||||
itemAddons.Add(row.Key.Text);
|
||||
else if (typeName == "EInventoryItemType::PowerAddOn")
|
||||
powerAddons.Add(row.Key.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var addonsSerialized = new
|
||||
{
|
||||
Items = itemAddons.OrderBy(x => x).ToList(),
|
||||
Powers = powerAddons.OrderBy(x => x).ToList()
|
||||
};
|
||||
File.WriteAllText("addons.json", JsonConvert.SerializeObject(addonsSerialized, Formatting.Indented));
|
||||
|
||||
/*
|
||||
* offerings
|
||||
*/
|
||||
searchPaths = dataPak.Files.Keys.Where(x => x.Contains($"/OfferingDB.uasset", StringComparison.OrdinalIgnoreCase)).ToList();
|
||||
|
||||
var offerings = new List<string>();
|
||||
|
||||
foreach (var path in searchPaths)
|
||||
{
|
||||
var cleanPath = path.Contains('.') ? path.Substring(0, path.LastIndexOf('.')) : path;
|
||||
if (provider.TryLoadPackageObject<UDataTable>(cleanPath, out var dataTable))
|
||||
{
|
||||
Console.WriteLine($"getting offerings from {Path.GetFileName(path)}");
|
||||
|
||||
foreach (var row in dataTable.RowMap)
|
||||
offerings.Add(row.Key.Text);
|
||||
}
|
||||
}
|
||||
File.WriteAllText("offerings.json", JsonConvert.SerializeObject(offerings, Formatting.Indented));
|
||||
|
||||
/*
|
||||
* perks
|
||||
*/
|
||||
searchPaths = dataPak.Files.Keys.Where(x => x.Contains($"/PerkDB.uasset", StringComparison.OrdinalIgnoreCase)).ToList();
|
||||
|
||||
var perks = new List<string>();
|
||||
|
||||
foreach (var path in searchPaths)
|
||||
{
|
||||
var cleanPath = path.Contains('.') ? path.Substring(0, path.LastIndexOf('.')) : path;
|
||||
if (provider.TryLoadPackageObject<UDataTable>(cleanPath, out var dataTable))
|
||||
{
|
||||
Console.WriteLine($"getting perks from {Path.GetFileName(path)}");
|
||||
|
||||
foreach (var row in dataTable.RowMap)
|
||||
perks.Add(row.Key.Text);
|
||||
}
|
||||
}
|
||||
File.WriteAllText("perks.json", JsonConvert.SerializeObject(perks, Formatting.Indented));
|
||||
|
||||
Console.WriteLine("\nAll dumper operations finished. Press any key to Close.");
|
||||
Console.ReadKey();
|
||||
}
|
||||
|
||||
+171
-83
@@ -12,6 +12,8 @@
|
||||
#include <format>
|
||||
#include <mutex>
|
||||
#include <ctime>
|
||||
#include <regex>
|
||||
#include <unordered_set>
|
||||
#include <simdjson.h>
|
||||
|
||||
std::string getExeDir()
|
||||
@@ -20,8 +22,7 @@ std::string getExeDir()
|
||||
GetModuleFileNameA(NULL, buffer, MAX_PATH);
|
||||
std::string path(buffer);
|
||||
size_t pos = path.find_last_of("\\/");
|
||||
if (pos != std::string::npos)
|
||||
return path.substr(0, pos + 1);
|
||||
if (pos != std::string::npos) return path.substr(0, pos + 1);
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -75,49 +76,78 @@ BOOL WINAPI consoleHandler(DWORD dwType)
|
||||
std::mutex g_dataMutex;
|
||||
std::vector<std::string> g_allObjectIds;
|
||||
std::vector<std::string> g_allCharacterIds;
|
||||
std::vector<std::string> g_dumpedItems;
|
||||
std::vector<std::string> g_stackableItems;
|
||||
std::vector<std::string> g_uniqueItems;
|
||||
std::vector<std::string> g_perks;
|
||||
|
||||
void loadJsonDump(const std::string& path)
|
||||
void loadDictDump(const std::string& path, std::vector<std::string>& outStackable, std::vector<std::string>& outUnique)
|
||||
{
|
||||
std::ifstream file(path);
|
||||
if (!file.is_open())
|
||||
simdjson::dom::parser parser;
|
||||
simdjson::dom::element doc;
|
||||
auto error = parser.load(path).get(doc);
|
||||
if (error)
|
||||
{
|
||||
Log::warning("Failed to open dump file: {}", path);
|
||||
Log::warning("Failed to open or parse dict dump {}: {}", path, simdjson::error_message(error));
|
||||
return;
|
||||
}
|
||||
std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||
try
|
||||
{
|
||||
simdjson::ondemand::parser parser;
|
||||
simdjson::padded_string json(content);
|
||||
auto doc = parser.iterate(json);
|
||||
|
||||
for (auto field : doc.get_object())
|
||||
simdjson::dom::array itemsArr;
|
||||
if (doc.at_key("Items").get(itemsArr) == simdjson::SUCCESS)
|
||||
{
|
||||
for (auto item : itemsArr)
|
||||
{
|
||||
for (auto item : field.value().get_array())
|
||||
{
|
||||
std::string_view id;
|
||||
if (item.get_string().get(id) == simdjson::SUCCESS)
|
||||
{
|
||||
g_dumpedItems.push_back(std::string(id));
|
||||
}
|
||||
}
|
||||
std::string_view id;
|
||||
if (item.get(id) == simdjson::SUCCESS) outStackable.push_back(std::string(id));
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
|
||||
simdjson::dom::array powersArr;
|
||||
if (doc.at_key("Powers").get(powersArr) == simdjson::SUCCESS)
|
||||
{
|
||||
Log::warning("Failed to parse dump file {}: {}", path, e.what());
|
||||
for (auto item : powersArr)
|
||||
{
|
||||
std::string_view id;
|
||||
if (item.get(id) == simdjson::SUCCESS) outUnique.push_back(std::string(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void loadArrayDump(const std::string& path, std::vector<std::string>& outList)
|
||||
{
|
||||
simdjson::dom::parser parser;
|
||||
simdjson::dom::element doc;
|
||||
auto error = parser.load(path).get(doc);
|
||||
if (error)
|
||||
{
|
||||
Log::warning("Failed to open or parse array dump {}: {}", path, simdjson::error_message(error));
|
||||
return;
|
||||
}
|
||||
|
||||
simdjson::dom::array arr;
|
||||
if (doc.get(arr) == simdjson::SUCCESS)
|
||||
{
|
||||
for (auto item : arr)
|
||||
{
|
||||
std::string_view id;
|
||||
if (item.get(id) == simdjson::SUCCESS) outList.push_back(std::string(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void loadAllCustomItems()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_dataMutex);
|
||||
g_dumpedItems.clear();
|
||||
loadJsonDump(getExeDir() + "itemdb.json");
|
||||
loadJsonDump(getExeDir() + "itemaddonsdb.json");
|
||||
loadJsonDump(getExeDir() + "offeringdb.json");
|
||||
Log::info("Loaded {} custom items from dumps", g_dumpedItems.size());
|
||||
g_stackableItems.clear();
|
||||
g_uniqueItems.clear();
|
||||
g_perks.clear();
|
||||
|
||||
loadDictDump(getExeDir() + "addons.json", g_stackableItems, g_stackableItems);
|
||||
loadDictDump(getExeDir() + "items.json", g_stackableItems, g_uniqueItems);
|
||||
loadArrayDump(getExeDir() + "offerings.json", g_stackableItems);
|
||||
loadArrayDump(getExeDir() + "perks.json", g_perks);
|
||||
|
||||
Log::info("Loaded {} stackable, {} unique (powers), and {} perk items from dumps", g_stackableItems.size(),
|
||||
g_uniqueItems.size(), g_perks.size());
|
||||
}
|
||||
|
||||
void parseCatalog(const std::string& data)
|
||||
@@ -235,55 +265,77 @@ int main()
|
||||
/*
|
||||
listeners
|
||||
*/
|
||||
|
||||
|
||||
proxy->OnClientRequest.addListener([](const std::string& url, std::string& data) {
|
||||
if (url.find("/v1/party") != std::string::npos)
|
||||
{
|
||||
data;
|
||||
Log::verbose("party req");
|
||||
}
|
||||
});
|
||||
|
||||
proxy->OnServerResponse.addListener([](const std::string& url, std::string& data) {
|
||||
bool dumpOnly = true;
|
||||
if (url.find("bhvrdbd.com") != std::string::npos) Log::verbose("BHVR api res: {}", url);
|
||||
|
||||
if (url.find("/v1/party") != std::string::npos)
|
||||
{
|
||||
data;
|
||||
Log::verbose("party res");
|
||||
}
|
||||
|
||||
Log::verbose("res: {}", url);
|
||||
if (url.find("api/v1/extensions/store/getCatalogItems") != std::string::npos)
|
||||
updateCatalog(data);
|
||||
//else if (dumpOnly == true)
|
||||
// return;
|
||||
else if (url.find("api/v1/dbd-inventories/all") != std::string::npos)
|
||||
{
|
||||
std::vector<std::string> localObjectIds;
|
||||
std::lock_guard<std::mutex> lock(g_dataMutex);
|
||||
if (!g_allObjectIds.empty() || !g_stackableItems.empty() || !g_uniqueItems.empty())
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_dataMutex);
|
||||
localObjectIds = g_allObjectIds;
|
||||
}
|
||||
Log::info("Merging catalog and custom items into real inventory response");
|
||||
|
||||
if (!localObjectIds.empty())
|
||||
{
|
||||
Log::info("Merging {} catalog items into real inventory response", localObjectIds.size());
|
||||
std::regex qtyRegex(R"("quantity"\s*:\s*\d+)");
|
||||
for (const auto& id : g_stackableItems)
|
||||
{
|
||||
size_t pos = data.find("\"objectId\":\"" + id + "\"");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
size_t start = data.rfind("{", pos);
|
||||
size_t end = data.find("}", pos);
|
||||
if (start != std::string::npos && end != std::string::npos && start < end)
|
||||
{
|
||||
std::string objStr = data.substr(start, end - start + 1);
|
||||
objStr = std::regex_replace(objStr, qtyRegex, "\"quantity\":100");
|
||||
data.replace(start, end - start + 1, objStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t closePos = data.rfind("]}");
|
||||
if (closePos != std::string::npos)
|
||||
{
|
||||
uint64_t now = time(nullptr);
|
||||
std::string injected;
|
||||
injected.reserve(localObjectIds.size() * 60);
|
||||
injected.reserve((g_allObjectIds.size() + g_stackableItems.size() + g_uniqueItems.size()) * 60);
|
||||
|
||||
for (const auto& id : localObjectIds)
|
||||
std::unordered_set<std::string> dbIds;
|
||||
for (auto& id : g_stackableItems)
|
||||
dbIds.insert(id);
|
||||
for (auto& id : g_uniqueItems)
|
||||
dbIds.insert(id);
|
||||
for (auto& id : g_perks)
|
||||
dbIds.insert(id);
|
||||
|
||||
std::unordered_set<std::string> handledIds;
|
||||
auto injectItem = [&](const std::string& id, int qty) {
|
||||
if (id.empty()) return;
|
||||
if (handledIds.count(id)) return;
|
||||
|
||||
std::string searchPat = "\"objectId\":\"" + id + "\"";
|
||||
if (data.find(searchPat) != std::string::npos)
|
||||
{
|
||||
handledIds.insert(id);
|
||||
return;
|
||||
}
|
||||
|
||||
injected += ",{\"lastUpdateAt\":" + std::to_string(now) +
|
||||
",\"quantity\":" + std::to_string(qty) + ",\"objectId\":\"" + id + "\"}";
|
||||
handledIds.insert(id);
|
||||
};
|
||||
|
||||
for (const auto& id : g_stackableItems)
|
||||
injectItem(id, 100);
|
||||
for (const auto& id : g_uniqueItems)
|
||||
injectItem(id, 1);
|
||||
for (const auto& id : g_perks)
|
||||
injectItem(id, 3);
|
||||
|
||||
for (const auto& id : g_allObjectIds)
|
||||
{
|
||||
if (data.find("\"objectId\":\"" + id + "\"") != std::string::npos) continue;
|
||||
|
||||
injected += ",{\"lastUpdateAt\":" + std::to_string(now) + ",\"quantity\":1,\"objectId\":\"" +
|
||||
id + "\"}";
|
||||
if (dbIds.find(id) == dbIds.end()) injectItem(id, 1);
|
||||
}
|
||||
|
||||
if (!injected.empty()) data.insert(closePos, injected);
|
||||
@@ -293,53 +345,89 @@ int main()
|
||||
}
|
||||
}
|
||||
else
|
||||
Log::warning("No catalog data available to inject into inventory yet!");
|
||||
Log::warning("No catalog or custom data available to inject into inventory yet!");
|
||||
}
|
||||
else if (url.find("api/v1/dbd-character-data/get-all") != std::string::npos)
|
||||
{
|
||||
std::vector<std::string> localItems;
|
||||
|
||||
std::vector<std::string> localStackable;
|
||||
std::vector<std::string> localUnique;
|
||||
std::vector<std::string> localPerks;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_dataMutex);
|
||||
localItems = g_dumpedItems;
|
||||
localStackable = g_stackableItems;
|
||||
localUnique = g_uniqueItems;
|
||||
localPerks = g_perks;
|
||||
}
|
||||
|
||||
if (!localItems.empty())
|
||||
if (!localStackable.empty() || !localUnique.empty() || !localPerks.empty())
|
||||
{
|
||||
size_t pos = 0;
|
||||
size_t count = 0;
|
||||
std::unordered_set<std::string> stackableSet(localStackable.begin(), localStackable.end());
|
||||
std::unordered_set<std::string> uniqueSet(localUnique.begin(), localUnique.end());
|
||||
std::unordered_set<std::string> perkSet(localPerks.begin(), localPerks.end());
|
||||
|
||||
while ((pos = data.find("\"characterItems\":[", pos)) != std::string::npos)
|
||||
{
|
||||
pos += 18;
|
||||
|
||||
size_t endPos = data.find("]", pos);
|
||||
std::string currentItems;
|
||||
if (endPos != std::string::npos) currentItems = data.substr(pos, endPos - pos);
|
||||
|
||||
std::string injected;
|
||||
for (const auto& item : localItems)
|
||||
if (endPos != std::string::npos)
|
||||
{
|
||||
if (endPos == std::string::npos ||
|
||||
currentItems.find("\"itemId\":\"" + item + "\"") == std::string::npos)
|
||||
std::string currentItems = data.substr(pos, endPos - pos);
|
||||
std::string newItems;
|
||||
newItems.reserve(currentItems.size() * 2);
|
||||
|
||||
std::unordered_set<std::string> seenIds;
|
||||
|
||||
size_t itemPos = 0;
|
||||
while ((itemPos = currentItems.find("\"itemId\":\"", itemPos)) != std::string::npos)
|
||||
{
|
||||
injected += "{\"itemId\":\"" + item + "\",\"quantity\":100},";
|
||||
itemPos += 10;
|
||||
size_t quotePos = currentItems.find("\"", itemPos);
|
||||
if (quotePos == std::string::npos) break;
|
||||
|
||||
std::string id = currentItems.substr(itemPos, quotePos - itemPos);
|
||||
seenIds.insert(id);
|
||||
|
||||
int qty = 100;
|
||||
if (perkSet.count(id))
|
||||
qty = 3;
|
||||
else if (uniqueSet.count(id))
|
||||
qty = 1;
|
||||
|
||||
newItems += "{\"itemId\":\"" + id + "\",\"quantity\":" + std::to_string(qty) + "},";
|
||||
}
|
||||
}
|
||||
|
||||
if (!injected.empty())
|
||||
{
|
||||
if (data[pos] == ']') injected.pop_back();
|
||||
auto injectIfMissing = [&](const std::vector<std::string>& list, int qty) {
|
||||
for (const auto& id : list)
|
||||
{
|
||||
if (seenIds.find(id) == seenIds.end())
|
||||
{
|
||||
newItems += "{\"itemId\":\"" + id + "\",\"quantity\":" + std::to_string(qty) + "},";
|
||||
seenIds.insert(id);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
data.insert(pos, injected);
|
||||
pos += injected.length();
|
||||
injectIfMissing(localStackable, 100);
|
||||
injectIfMissing(localUnique, 1);
|
||||
injectIfMissing(localPerks, 3);
|
||||
|
||||
if (!newItems.empty()) newItems.pop_back(); // trailing comma
|
||||
|
||||
data.replace(pos, endPos - pos, newItems);
|
||||
|
||||
endPos = pos + newItems.length();
|
||||
pos = endPos;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
Log::info("Injected missing items into {} character inventories", count);
|
||||
Log::info("Injected missing items and targeted perk tiers in {} character inventories", count);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::warning("No custom dumped items available to inject into character inventory!");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+1
-15
@@ -94,7 +94,7 @@ namespace
|
||||
search += ":";
|
||||
|
||||
size_t pos = h_lower.find(search);
|
||||
if (pos == std::string::npos) return ""; // Not found
|
||||
if (pos == std::string::npos) return "";
|
||||
|
||||
size_t vStart = pos + search.length();
|
||||
while (vStart < headers.size() && (headers[vStart] == ' ' || headers[vStart] == '\t'))
|
||||
@@ -379,9 +379,7 @@ void Proxy::handleClient(SOCKET hClientSocket)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
clientStream.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -440,13 +438,9 @@ void Proxy::handleClient(SOCKET hClientSocket)
|
||||
safe_stoi(h_lower.substr(vStart, h_lower.find("\r\n", vStart) - vStart), -1);
|
||||
}
|
||||
else if (sCode == 204 || sCode == 304 || sCode == 205)
|
||||
{
|
||||
serverStream.contentLength = 0;
|
||||
}
|
||||
else if (!serverStream.isChunked)
|
||||
{
|
||||
serverStream.contentLength = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (serverStream.isReceivingBody)
|
||||
@@ -493,9 +487,7 @@ void Proxy::handleClient(SOCKET hClientSocket)
|
||||
processed = serverStream.buffer.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
complete = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (serverStream.contentLength >= 0)
|
||||
@@ -522,9 +514,7 @@ void Proxy::handleClient(SOCKET hClientSocket)
|
||||
body = serverStream.buffer.substr(bStart);
|
||||
}
|
||||
else
|
||||
{
|
||||
complete = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (complete)
|
||||
@@ -542,10 +532,8 @@ void Proxy::handleClient(SOCKET hClientSocket)
|
||||
removeHeader(respHeaders, "Transfer-Encoding");
|
||||
removeHeader(respHeaders, "Content-Length");
|
||||
if (sc != 204 && sc != 304 && sc != 205)
|
||||
{
|
||||
respHeaders.insert(respHeaders.size() - 2,
|
||||
"Content-Length: " + std::to_string(body.size()) + "\r\n");
|
||||
}
|
||||
|
||||
std::string packet = respHeaders + body;
|
||||
SSL_write(clientSSL, packet.data(), (int)packet.size());
|
||||
@@ -555,9 +543,7 @@ void Proxy::handleClient(SOCKET hClientSocket)
|
||||
clientStream.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (connectionClosed) break;
|
||||
|
||||
Reference in New Issue
Block a user