- GetCurrentTokens + HasRetrievedUserItems now pass through to original:
spoofed tokens broke the credit-purchase modal; forced retrieved-flag with
empty userItems made flows treat items as definitively not-owned
- UserHasItem/PlayerHasItem keep returning true but LOG itemDef on every call;
IsCharacterUnlocked/HasPerk/HasOutfit log decoded string args
-> next play session reveals whether pet/perk/outfit UI consults these at all
(if silent while browsing locked pets, UI reads userItems list field directly)
- install.sh: replace fragile inline heredoc python with scripts/vdf_patch.py
(chr(92)-built bytes; the old heredoc produced \\ corruption that silently
killed LaunchOptions for account 919954036); warn when Steam is running
76 lines
2.6 KiB
Python
76 lines
2.6 KiB
Python
#!/usr/bin/env python3
|
|
"""Patch Steam localconfig.vdf LaunchOptions for Devour (1274570).
|
|
|
|
Sets WINEDLLOVERRIDES="version=n,b" %command% inside every userdata/*/config/
|
|
localconfig.vdf Apps->1274570 block. Must be run while Steam is CLOSED — Steam
|
|
rewrites localconfig.vdf from memory on exit and discards external edits.
|
|
|
|
VDF escaping note: quotes inside values are a single backslash + quote (\").
|
|
Getting that through bash heredocs is what broke account 919954036 before
|
|
(it ended up as \\\"). This module builds bytes explicitly via chr(92).
|
|
"""
|
|
import pathlib, sys
|
|
|
|
APPID = "1274570"
|
|
BQ = chr(92) + '"' # backslash + quote
|
|
TARGET_LINE = (
|
|
"\t" * 6 + '"LaunchOptions"' + "\t\t"
|
|
+ '"WINEDLLOVERRIDES=' + BQ + 'version=n,b' + BQ + ' %command%"' + "\n"
|
|
)
|
|
|
|
def patch(path: pathlib.Path) -> bool:
|
|
lines = path.read_text(errors="ignore").splitlines(True)
|
|
changed = False
|
|
i = 0
|
|
while i < len(lines) - 1:
|
|
if (
|
|
lines[i].strip() == f'"{APPID}"'
|
|
and lines[i].startswith("\t" * 5)
|
|
and lines[i + 1].strip() == "{"
|
|
and lines[i + 1].startswith("\t" * 5)
|
|
):
|
|
depth = 1
|
|
j = i + 2
|
|
lo_i = 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):
|
|
lo_i = j
|
|
j += 1
|
|
if end is None:
|
|
i = j + 1
|
|
continue
|
|
if lo_i is None:
|
|
lines.insert(end, TARGET_LINE)
|
|
print(f"{path.parent.parent.name}: inserted LaunchOptions")
|
|
changed = True
|
|
elif lines[lo_i] != TARGET_LINE:
|
|
print(f"{path.parent.parent.name}: fixed {lines[lo_i].strip()[:70]!r}")
|
|
lines[lo_i] = TARGET_LINE
|
|
changed = True
|
|
else:
|
|
print(f"{path.parent.parent.name}: already exact")
|
|
i = end + 1
|
|
continue
|
|
i += 1
|
|
if changed:
|
|
bak = path.with_suffix(".vdf.bak.devour")
|
|
bak.write_text("".join(lines))
|
|
path.write_text("".join(lines))
|
|
return changed
|
|
|
|
if __name__ == "__main__":
|
|
paths = [pathlib.Path(a) for a in sys.argv[1:]] or list(
|
|
pathlib.Path.home().glob(".local/share/Steam/userdata/*/config/localconfig.vdf")
|
|
)
|
|
for p in paths:
|
|
if p.exists():
|
|
patch(p)
|