#!/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)