Skip to content

Commit 6450c0d

Browse files
authored
(S12) IMPORTANT - LOOK AT README INSTALL INSTRUCTIONS - Added script to sign DLL so that D4LF will work again (#639)
1 parent 75b106a commit 6450c0d

File tree

11 files changed

+2660
-2492
lines changed

11 files changed

+2660
-2492
lines changed

.pre-commit-config.yaml

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,74 @@
11
default_install_hook_types: [pre-push]
22
default_language_version:
33
python: python3.14
4-
minimum_prek_version: '0.2.3'
4+
minimum_prek_version: '0.3.0'
55
repos:
66
- repo: https://github.com/astral-sh/uv-pre-commit
7-
rev: 0.9.21
7+
rev: 0.10.9
88
hooks:
99
- id: uv-lock
10+
priority: &group1 4294967294
1011
- repo: https://github.com/executablebooks/mdformat
1112
rev: 1.0.0
1213
hooks:
1314
- id: mdformat
15+
priority: *group1
1416
additional_dependencies:
1517
- mdformat-gfm
1618
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
17-
rev: v2.15.0
19+
rev: v2.16.0
1820
hooks:
1921
- id: pretty-format-toml
22+
priority: *group1
2023
args: [--autofix, --indent, "4"]
2124
- id: pretty-format-yaml
25+
priority: *group1
2226
args: [--autofix, --preserve-quotes, --offset, "2"]
2327
- repo: https://github.com/pre-commit/mirrors-clang-format
24-
rev: v21.1.8
28+
rev: v22.1.0
2529
hooks:
2630
- id: clang-format
31+
priority: *group1
2732
files: \.(cpp|h)$
28-
- repo: https://github.com/pre-commit/pre-commit-hooks
29-
rev: v6.0.0
33+
- repo: builtin
3034
hooks:
31-
- id: check-ast
35+
- id: check-added-large-files
36+
priority: &read-only 4294967295
3237
- id: check-case-conflict
38+
priority: *read-only
3339
- id: check-executables-have-shebangs
40+
priority: *read-only
3441
- id: check-json
42+
priority: *read-only
3543
- id: check-toml
36-
- id: check-xml
44+
priority: *read-only
3745
- id: check-yaml
46+
priority: *read-only
3847
- id: end-of-file-fixer
3948
- id: fix-byte-order-marker
49+
- id: trailing-whitespace
50+
- repo: https://github.com/pre-commit/pre-commit-hooks
51+
rev: v6.0.0
52+
hooks:
53+
- id: check-ast
54+
priority: *read-only
4055
- id: pretty-format-json
4156
args: [--autofix, --indent=4, --no-ensure-ascii]
57+
priority: *group1
4258
- id: trailing-whitespace
4359
- repo: https://github.com/astral-sh/ruff-pre-commit
44-
rev: v0.14.10
60+
rev: v0.15.5
4561
hooks:
4662
- id: ruff-format
63+
priority: *group1
4764
- id: ruff-check
65+
priority: &group2 4294967293
4866
args: [--fix]
67+
- repo: https://github.com/thetestlabs/py-psscriptanalyzer
68+
rev: v0.3.1
69+
hooks:
70+
- id: py-psscriptanalyzer
71+
priority: *read-only
72+
args: ['--severity', 'Error']
73+
- id: py-psscriptanalyzer-format
74+
priority: *group1

README.md

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,18 @@ feature request or issue reports join the [discord](https://discord.gg/YyzaPhAN6
2020

2121
## How to Setup
2222

23-
### Game Settings
24-
25-
- Game Language must be English
26-
- IMPORTANT: Advanced Tooltip Information must be enabled in Options > Gameplay > Gameplay. If you don't do this then item parsing will be very inconsistent and you will receive no warning something is wrong.
27-
- Font scale in Graphics settings must be small or medium
28-
- HDR makes the screen too bright and D4LF is unable to read the state of some items on screen. It must be disabled.
29-
- Use Screen Reader must be enabled in Options > Accessibility
30-
- 3rd Party Screen Reader must be enabled in Options > Accessibility (The voice will go away when DLL is installed, see quick start guide below)
31-
32-
### Installation and quick start guide
23+
### Installation and quick start guide (New instructions for season 12 that must be followed!)
3324

3425
- Download and extract the latest version (.zip) from the releases: https://github.com/d4lfteam/d4lf/releases
3526
- Copy `saapi64.dll` from the downloaded folder to your "Diablo IV" directory
3627
- To find your D4 directory:
3728
- In Battle.net, click the gear icon next to the Play button and select "Open in Explorer"
3829
- In Steam, right click the game, select Manage > Browse local files
30+
- **New for Season 12** The saapi64.dll must be locally signed for D4 to pick it up. We have written a script to do this for you. It is a one-time process per computer.
31+
- Navigate to your d4lf directory
32+
- Right click and choose "Open in Terminal"
33+
- Type the following: `.\sign_dll.ps1`
34+
- When prompted for d4_path, paste in the D4 directory you located previously
3935
- Generate a profile of what you want to filter for. To do so you have a few options:
4036
- Run d4lf.exe and import a profile using the import window by pasting a build page from popular planner websites
4137
- Create one yourself by looking at the [examples](#how-to-filter--profiles) below
@@ -48,6 +44,15 @@ feature request or issue reports join the [discord](https://discord.gg/YyzaPhAN6
4844
- Use the hotkeys listed in d4lf.exe to run filtering. By default, F11 will run the loot filter and filter your items.
4945
- For most common issues, if something is wrong, you will see an error or warning when you start d4lf.exe. Join our [discord](https://discord.gg/YyzaPhAN6T) for more help.
5046

47+
### Game Settings
48+
49+
- Game Language must be English
50+
- IMPORTANT: Advanced Tooltip Information must be enabled in Options > Gameplay > Gameplay. If you don't do this then item parsing will be very inconsistent and you will receive no warning something is wrong.
51+
- Font scale in Graphics settings must be small or medium
52+
- HDR makes the screen too bright and D4LF is unable to read the state of some items on screen. It must be disabled.
53+
- Use Screen Reader must be enabled in Options > Accessibility
54+
- 3rd Party Screen Reader must be enabled in Options > Accessibility (The voice will go away when DLL is installed, see quick start guide below)
55+
5156
### Common problems
5257

5358
- The GUI crashes immediately upon opening, with no error message given
@@ -700,7 +705,13 @@ If you receive an error about missing Visual Studio code, follow the link it pro
700705

701706
### Formatting & Linting
702707

703-
Just use prek. If it's your first setup, run:
708+
Just use prek. If it's your first setup, you will need to install the NuGet package provider. Open Windows Powershell and run::
709+
710+
```
711+
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Scope CurrentUser
712+
```
713+
714+
Then run:
704715

705716
```bash
706717
prek install

assets/lang/enUS/affixes.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,13 @@
429429
"familiar_explosion_size": "familiar explosion size",
430430
"familiar_lucky_hit_chance": "familiar lucky hit chance",
431431
"fanaticism_aura_potency": "fanaticism aura potency",
432+
"feast_every_kills_chains_hook_nearby_enemies": "feast every kills, chains hook nearby enemies",
433+
"feast_every_kills_gain_berserking_for_seconds": "feast every kills, gain berserking for seconds",
434+
"feast_every_kills_release_a_bloodspolsion_for_damage": "feast every kills, release a bloodspolsion for damage",
435+
"feast_every_kills_reset_random_cooldowns": "feast every kills, reset random cooldowns",
436+
"feast_every_kills_restore_of_your_maximum_primary_resource": "feast every kills, restore of your maximum primary resource",
437+
"feast_every_kills_savagely_bite_times_for_damage_and_apply_vulnerable": "feast every kills, savagely bite times for damage and apply vulnerable",
438+
"feast_every_kills_your_next_core_skill_cast_deals_additional_damage": "feast every kills, your next core skill cast deals additional damage",
432439
"ferocity_potency": "ferocity potency",
433440
"fire_and_cold_damage": "fire and cold damage",
434441
"fire_damage": "fire damage",
@@ -476,6 +483,19 @@
476483
"hewed_flesh_grants_maximum_life_as_barrier_for_seconds": "hewed flesh grants maximum life as barrier for seconds",
477484
"holy_bolt_resource_generation": "holy bolt resource generation",
478485
"holy_light_aura_potency": "holy light aura potency",
486+
"hunger_after_you_cast_a_basic_skill_chance_for_kill_to_your_kill_streak": "hunger after you cast a basic skill, chance for kill to your kill streak",
487+
"hunger_after_you_cast_a_cooldown_kill_to_your_kill_streak": "hunger after you cast a cooldown, kill to your kill streak",
488+
"hunger_after_you_kill_an_enemy_chance_for_kill_to_your_kill_streak": "hunger after you kill an enemy, chance for kill to your kill streak",
489+
"hunger_every_resource_chance_for_kill_to_your_kill_streak": "hunger every resource, chance for kill to your kill streak",
490+
"hunger_increased_chance_for_additional_gold_during_kill_streaks": "hunger increased chance for additional gold during kill streaks",
491+
"hunger_increased_chance_for_additional_salvage_materials_during_your_kill_streaks": "hunger increased chance for additional salvage materials during your kill streaks",
492+
"hunger_increased_chance_for_feast_items_during_your_kill_streaks": "hunger increased chance for feast items during your kill streaks",
493+
"hunger_increased_chance_for_hunger_items_during_kill_streaks": "hunger increased chance for hunger items during kill streaks",
494+
"hunger_increased_chance_for_rampage_items_during_kill_streaks": "hunger increased chance for rampage items during kill streaks",
495+
"hunger_increased_chance_for_runes_during_your_kill_streaks": "hunger increased chance for runes during your kill streaks",
496+
"hunger_increased_experience_from_kill_streaks": "hunger increased experience from kill streaks",
497+
"hunger_increased_reputation_from_kill_streaks": "hunger increased reputation from kill streaks",
498+
"hunger_lucky_hit_up_to_a_chance_for_kill_to_your_kill_streak": "hunger lucky hit up to a chance for kill to your kill streak",
479499
"hurricane_cooldown_reduction": "hurricane cooldown reduction",
480500
"hurricane_damage": "hurricane damage",
481501
"hurricane_duration": "hurricane duration",
@@ -657,6 +677,14 @@
657677
"rain_of_arrows_skill_cooldown_reduction": "rain of arrows skill cooldown reduction",
658678
"rake_size": "rake size",
659679
"rally_duration": "rally duration",
680+
"rampage_attack_speed_per_kill_streak_tier": "rampage attack speed per kill streak tier",
681+
"rampage_cooldown_reduction_per_kill_streak_tier": "rampage cooldown reduction per kill streak tier",
682+
"rampage_critical_strike_chance_per_kill_streak_tier": "rampage critical strike chance per kill streak tier",
683+
"rampage_life_on_hit_per_kill_streak_tier": "rampage life on hit per kill streak tier",
684+
"rampage_lucky_hit_chance_per_kill_streak_tier": "rampage lucky hit chance per kill streak tier",
685+
"rampage_maximum_life_per_kill_streak_tier": "rampage maximum life per kill streak tier",
686+
"rampage_movement_speed_per_kill_streak_tier": "rampage movement speed per kill streak tier",
687+
"rampage_resource_cost_reduction_per_kill_streak_tier": "rampage resource cost reduction per kill streak tier",
660688
"rank_of_all_agility_skills": "rank of all agility skills",
661689
"ranks_of_the_aggressive_resistance_passive": "ranks of the aggressive resistance passive",
662690
"ranks_of_the_concussive_passive": "ranks of the concussive passive",

assets/lang/enUS/uniques.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,18 @@
8383
"chainscourged_mail": {
8484
"num_inherents": 0
8585
},
86+
"cluckeye": {
87+
"num_inherents": 1
88+
},
89+
"cluckonomicon": {
90+
"num_inherents": 0
91+
},
8692
"condemnation": {
8793
"num_inherents": 1
8894
},
95+
"coop_de_grâce": {
96+
"num_inherents": 1
97+
},
8998
"cowl_of_the_nameless": {
9099
"num_inherents": 0
91100
},
@@ -128,6 +137,12 @@
128137
"ebonpiercer": {
129138
"num_inherents": 0
130139
},
140+
"eggcecutioner": {
141+
"num_inherents": 1
142+
},
143+
"eggis": {
144+
"num_inherents": 3
145+
},
131146
"endurant_faith": {
132147
"num_inherents": 0
133148
},

build.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def copy_additional_resources(release_dir: Path):
2626
shutil.copy("README.md", release_dir)
2727
shutil.copy("tts/saapi64.dll", release_dir)
2828
shutil.copytree("assets", release_dir / "assets")
29+
shutil.copy("tts/sign_dll.ps1", release_dir)
2930

3031

3132
def create_batch_for_consoleonly(release_dir: Path, exe_name: str):

pyproject.toml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ requires = ["hatchling"]
44

55
[dependency-groups]
66
dev = [
7+
"prek",
78
"pyinstaller",
9+
"pytest",
810
"pytest-env",
911
"pytest-mock",
1012
"pytest-pythonpath",
1113
"pytest-xdist",
12-
"pytest",
13-
"typing-extensions",
14-
"prek"
14+
"typing-extensions"
1515
]
1616

1717
[project]
@@ -142,6 +142,7 @@ ignore = [
142142
"RUF043", # fix more in the future
143143
"RUF045", # fix more in the future
144144
"RUF059", # fix more in the future
145+
"RUF067", # fix more in the future
145146
"S101", # fix more in the future
146147
"S311", # fix more in the future
147148
"S404",
@@ -158,7 +159,8 @@ ignore = [
158159
"TRY002", # fix more in the future
159160
"TRY003", # fix more in the future
160161
"TRY004", # fix more in the future
161-
"TRY400" # fix more in the future
162+
"TRY400", # fix more in the future
163+
"UP047" # fix more in the future
162164
]
163165
select = ["ALL"]
164166

src/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
TP = concurrent.futures.ThreadPoolExecutor()
44

5-
__version__ = "8.1.2"
5+
__version__ = "8.2.0"

src/scripts/vision_mode_fast.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,8 @@ def on_tts(self, _):
132132
return self.request_draw("Unknown item", "#ce7e00")
133133

134134
res = Filter().should_keep(item_descr)
135-
match = res.keep
136135

137-
if match:
136+
if res.keep:
138137
color = get_filter_colors().matched
139138
if not res.matched:
140139
if item_descr.rarity == ItemRarity.Unique:

src/tools/gen_data.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ def is_placeholder_or_test_name(name) -> bool:
7878
"_test_",
7979
"(not_used",
8080
"(dns)",
81+
"(crucible)",
8182
]
8283
):
8384
return True

tts/sign_dll.ps1

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
param(
2+
[Parameter(Mandatory = $true)]
3+
[string]$d4_path
4+
)
5+
6+
# ── 1. Create self-signed code-signing certificate (10-year validity) ──────────
7+
$cert = Get-ChildItem -Path "Cert:\CurrentUser\My" |
8+
Where-Object { $_.Subject -eq "CN=Cert for D4LF" -and $_.HasPrivateKey } |
9+
Select-Object -First 1
10+
11+
if ($cert) {
12+
Write-Output "Certificate already exists: $($cert.Thumbprint) — skipping creation."
13+
}
14+
else {
15+
Write-Output "Creating self-signed code-signing certificate..."
16+
$cert = New-SelfSignedCertificate `
17+
-Type CodeSigningCert `
18+
-Subject "CN=Cert for D4LF" `
19+
-CertStoreLocation "Cert:\CurrentUser\My" `
20+
-NotAfter (Get-Date).AddYears(10)
21+
Write-Output "Certificate created: $($cert.Thumbprint)"
22+
}
23+
24+
# ── 2. Copy cert to Trusted Root Certification Authorities ────────────────────
25+
$rootStore = New-Object System.Security.Cryptography.X509Certificates.X509Store(
26+
[System.Security.Cryptography.X509Certificates.StoreName]::Root,
27+
[System.Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser
28+
)
29+
$rootStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
30+
31+
$alreadyTrusted = $rootStore.Certificates | Where-Object { $_.Thumbprint -eq $cert.Thumbprint }
32+
if ($alreadyTrusted) {
33+
Write-Output "Certificate already in Trusted Root — skipping."
34+
}
35+
else {
36+
$rootStore.Add($cert)
37+
Write-Output "Certificate copied to Trusted Root."
38+
}
39+
$rootStore.Close()
40+
41+
# ── 3. Locate signtool.exe under Windows Kits (prefer x64) ───────────────────
42+
Write-Output "Searching for signtool.exe..."
43+
$allSigntools = Get-ChildItem -Path "C:\Program Files (x86)\Windows Kits\10\bin\" `
44+
-Recurse -Filter "signtool.exe" -ErrorAction SilentlyContinue
45+
46+
# Prefer x64, then x86, then anything else
47+
$signtool = $allSigntools | Where-Object { $_.DirectoryName -match "\\x64$" } | Select-Object -First 1
48+
if (-not $signtool) { $signtool = $allSigntools | Where-Object { $_.DirectoryName -match "\\x86$" } | Select-Object -First 1 }
49+
if (-not $signtool) { $signtool = $allSigntools | Select-Object -First 1 }
50+
51+
if (-not $signtool) {
52+
Write-Error "signtool.exe not found under 'C:\Program Files (x86)\Windows Kits\10\bin\'."
53+
exit 1
54+
}
55+
$signtool = $signtool.FullName
56+
Write-Output "Found signtool: $signtool"
57+
58+
# ── 4. Sign the DLL ───────────────────────────────────────────────────────────
59+
$dllPath = Join-Path $d4_path "saapi64.dll"
60+
61+
if (-not (Test-Path $dllPath)) {
62+
Write-Error "DLL not found at: $dllPath"
63+
exit 1
64+
}
65+
66+
$sig = Get-AuthenticodeSignature -FilePath $dllPath
67+
if ($sig.Status -eq "Valid") {
68+
Write-Output "DLL is already signed (status: $($sig.Status)) — skipping."
69+
exit 0
70+
}
71+
72+
Write-Output "Signing $dllPath ..."
73+
& $signtool sign /fd SHA256 /n "Cert for D4LF" $dllPath
74+
75+
if ($LASTEXITCODE -ne 0) {
76+
Write-Error "signtool exited with code $LASTEXITCODE"
77+
exit $LASTEXITCODE
78+
}

0 commit comments

Comments
 (0)