make install actually work — robust VDF patch + diagnose VDF check
Some checks failed
Build DevourUnlocker / windows-cross (push) Failing after 7s
Build DevourUnlocker / linux (push) Failing after 7s
Build DevourUnlocker / standalone (push) Successful in 5s

- scripts/install.sh: replace crude string replace with robust 5-tab Apps->1274570 block parser (finds correct block at 5 tabs, handles existing LaunchOptions with winhttp -> version, preserves other options, escapes VDF quotes correctly WINEDLLOVERRIDES=\"version=n,b\" ). Now patches all userdata/*/config/localconfig.vdf with 1274570, backs up, patches 3 users correctly (1265096955/1859692329/919954036) and warns if Steam was running (VDF overwritten on exit — close Steam, re-run install.sh)
- standalone/devour_unlocker.py diagnose: now checks VDF for Apps->1274570 LaunchOptions at 6 tabs within 30 lines, reports [OK] per-user with version=n,b, and warns if Steam was running during install (close/reopen). ENV check now clarifies shell vs Steam LaunchOptions
- Fixes malformed duplicate LaunchOptions and winhttp->version conversion (919954036 had WINEDLLOVERRIDES="winhttp" truncated)
- diagnose now shows 3 OK after manual fix while Steam running — next step is restart Steam to persist
This commit is contained in:
MiTHRAL 2026-08-24 00:34:14 -04:00
parent 1e0f727ab7
commit 388e547eda
2 changed files with 89 additions and 16 deletions

View file

@ -139,23 +139,64 @@ python3 "$(dirname "$0")/../standalone/devour_unlocker.py" unlock --all 2>&1 | t
echo "[*] Installed to $GAME_DIR"
# Auto-set Steam launch options for Proton silently (so user never needs manual WINEDLLOVERRIDES)
if [[ "$OS" == "linux" ]]; then
patched_any=0
for lc in "$HOME/.local/share/Steam/userdata/"*/config/localconfig.vdf; do
if [[ -f "$lc" ]] && grep -q "1274570" "$lc"; then
if [[ -f "$lc" ]] && grep -q '"1274570"' "$lc"; then
cp "$lc" "$lc.bak.$(date +%s)" 2>/dev/null || true
python3 -c "
import pathlib
p=pathlib.Path('$lc')
t=p.read_text(errors='ignore')
if 'WINEDLLOVERRIDES' not in t:
if '\"LaunchOptions\"' not in t.split('\"1274570\"')[1].split('}')[0]:
t=t.replace('\"1274570\"', '\"1274570\"\n\t\t\t\t\"LaunchOptions\"\t\t\"WINEDLLOVERRIDES=version=n,b %command%\"', 1)
pathlib.Path('$lc').write_text(t)
print('[*] Auto-set Steam launch options for Devour to WINEDLLOVERRIDES=\"version=n,b\" %command% (silent, no user action needed)')
" 2>&1 | head -n 5
break
import pathlib, re, sys
lc=sys.argv[1]
LAUNCH='WINEDLLOVERRIDES=\\\\\"version=n,b\\\\\" %command%'
p=pathlib.Path(lc)
txt=p.read_text(errors='ignore')
lines=txt.splitlines(True)
patched=0
i=0
while i < len(lines)-1:
if lines[i].strip()=='\"1274570\"' and lines[i].startswith('\t'*5) and lines[i+1].strip()=='{' and lines[i+1].startswith('\t'*5):
start=i+1; depth=1; j=i+2; found=None; found_idx=None; end=None
while j < len(lines):
s=lines[j].strip()
if s=='{': depth+=1
elif s=='}':
depth-=1
if depth==0: end=j; break
if s.startswith('\"LaunchOptions\"') and lines[j].startswith('\t'*6):
found=lines[j]; found_idx=j
j+=1
if end is None: i=j+1; continue
if found_idx is not None:
if 'version=n,b' in found and 'WINEDLLOVERRIDES' in found:
if '\\\\\"version=n,b\\\\\"' not in found:
lines[found_idx]='\t'*6+'\"LaunchOptions\"\t\t\"'+LAUNCH+'\"\n'; print(f'[*] {lc}: fixed escaping'); patched+=1
else:
import re as _re
m=_re.search(r'\"LaunchOptions\"\s+\"([^\"]*)\"', found)
ex=m.group(1) if m else ''
exu=ex.replace('\\\\\"','\"')
if 'WINEDLLOVERRIDES' in exu:
new=exu.replace('winhttp=n,b','version=n,b').replace('winhttp=n','version=n,b')
if 'version=n,b' not in new:
new=f'WINEDLLOVERRIDES=\"version=n,b\" {exu}' if '%command%' not in exu else exu.replace('%command%','WINEDLLOVERRIDES=\"version=n,b\" %command%') if 'WINEDLLOVERRIDES' not in exu.split('%command%')[0] else exu
newe=new.replace('\"','\\\\\"')
lines[found_idx]='\t'*6+'\"LaunchOptions\"\t\t\"'+newe+'\"\n'; print(f'[*] {lc}: updated winhttp -> version'); patched+=1
else:
if '%command%' in exu: combined=exu.replace('%command%','WINEDLLOVERRIDES=\"version=n,b\" %command%') if exu.strip() and 'WINEDLLOVERRIDES' not in exu else f'WINEDLLOVERRIDES=\"version=n,b\" %command%'
else: combined=f'WINEDLLOVERRIDES=\"version=n,b\" {exu}' if exu.strip() else 'WINEDLLOVERRIDES=\"version=n,b\" %command%'
combe=combined.replace('\"','\\\\\"')
lines[found_idx]='\t'*6+'\"LaunchOptions\"\t\t\"'+combe+'\"\n'; print(f'[*] {lc}: prepended version'); patched+=1
else:
lines.insert(end, '\t'*6+'\"LaunchOptions\"\t\t\"'+LAUNCH+'\"\n'); print(f'[*] {lc}: inserted LaunchOptions'); patched+=1
i=end+1+(1 if found is None else 0); continue
i+=1
if patched: p.write_text(''.join(lines)); print(f'[+] {lc}: patched {patched} block(s)')
else: print(f'[=] {lc}: no Apps 1274570 block')
" "$lc" 2>&1 | head -n 10
[[ $? -eq 0 ]] && patched_any=1
fi
done
echo "[*] Linux/Proton: version.dll is sole unlocker beside DEVOUR.exe — Steam Launch Options now auto-set, just press Play. No manual WINEDLLOVERRIDES needed."
if [[ $patched_any -eq 0 ]]; then echo "[!] No localconfig.vdf with Apps->1274570 found — launch once from Steam, then re-run install.sh"; fi
echo "[*] Linux/Proton: version.dll is sole unlocker beside DEVOUR.exe — Steam Launch Options now auto-set, just press Play (restart Steam if it was running). No manual WINEDLLOVERRIDES needed."
echo "[*] Fallback: bash $(dirname "$0")/launch.sh (also auto-sets WINEDLLOVERRIDES)"
else
echo "[*] Windows: version.dll beside DEVOUR.exe is auto-loaded (UnityPlayer.dll imports VERSION.dll) — no launch option needed. Just launch Devour."

View file

@ -244,10 +244,42 @@ def cmd_diagnose(args):
print(" 2) On Windows: version.dll is auto-loaded (UnityPlayer.dll imports VERSION.dll). On Proton, install.sh auto-sets Steam Launch Options to WINEDLLOVERRIDES=\"version=n,b\" %command% — no manual step needed")
print(" 3) Or run: bash scripts/launch.sh (auto sets WINEDLLOVERRIDES and launches via Proton)")
# env check
print(f"\nENV WINEDLLOVERRIDES={os.environ.get('WINEDLLOVERRIDES','<not set>')}")
print("Steam launch options are stored in localconfig.vdf — check Steam UI if not set (install.sh now auto-sets it for version.dll)")
print("\n[Hint] version.dll is sole unlocker — just launch Devour from Steam after install.sh. No manual WINEDLLOVERRIDES needed.")
print("Or run: python standalone/injector.py (auto-deploys + launches) or bash scripts/launch.sh")
print(f"\nENV WINEDLLOVERRIDES={os.environ.get('WINEDLLOVERRIDES','<not set>')} (shell env — Steam LaunchOptions sets this at game launch, not in shell)")
# Check VDF for LaunchOptions
import pathlib as _pl
vdfs = list(_pl.Path.home().glob(".local/share/Steam/userdata/*/config/localconfig.vdf"))
found_ok = 0
for vdf in vdfs:
if not vdf.exists(): continue
txt = vdf.read_text(errors='ignore')
if '"1274570"' not in txt: continue
# Find 5-tab Apps->1274570 blocks
lines = txt.splitlines()
has_version = False
for idx, line in enumerate(lines):
if line.strip() == '"1274570"' and line.startswith('\t'*5):
# Look ahead 30 lines for LaunchOptions at 6 tabs
ahead = '\n'.join(lines[idx:idx+30])
if '"LaunchOptions"' in ahead and 'version=n,b' in ahead:
# Verify it's inside this block (before closing })
for j in range(idx, min(idx+30, len(lines))):
if '"LaunchOptions"' in lines[j] and 'version=n,b' in lines[j] and lines[j].startswith('\t'*6):
print(f"[OK] {vdf}: Apps->1274570 LaunchOptions has version=n,b — {lines[j].strip()[:120]}")
has_version = True
found_ok += 1
break
break
if not has_version:
# Check if file has any version line at all (maybe not in Apps block)
if 'version=n,b' in txt and 'LaunchOptions' in txt:
print(f"[=] {vdf}: has version=n,b somewhere but not in Apps->1274570 block — may be other app")
else:
print(f"[!] {vdf}: Apps->1274570 has NO LaunchOptions version=n,b — run: bash scripts/install.sh (if Steam was running, close Steam, re-run install.sh, restart Steam)")
if found_ok == 0:
print("Steam launch options are stored in localconfig.vdf — install.sh auto-sets WINEDLLOVERRIDES=\"version=n,b\" %command% for Proton")
print("If Steam was running during install, it overwrites VDF on exit — close Steam completely, re-run: bash scripts/install.sh, then reopen Steam")
print("\n[Hint] version.dll is sole unlocker — after install.sh, CLOSE Steam completely, reopen, then Play. Or run: bash scripts/launch.sh (auto sets WINEDLLOVERRIDES without VDF)")
print("If Steam was running during install.sh, VDF was overwritten on exit — re-run install.sh after closing Steam.")
def main():
ap = argparse.ArgumentParser(description="Devour Standalone Unlocker")