#!/usr/bin/env python3 """Generate config_generated.h from dorknet-quest.cfg. Bakes the operator's config into the library at compile time. Keys absent from the cfg are simply not emitted, so the built-in defaults in config.h apply. Secrets (Photon ids, Meta app id) live only in the git-ignored cfg, never in a committed file. Usage: gen_config_header.py """ import sys from pathlib import Path # cfg key -> (macro, kind) where kind is "str", "bool" or "int". KEYS = { "ServerHost": ("DN_SERVER_HOST", "str"), "OculusAppId": ("DN_OCULUS_APPID", "str"), "PhotonAppId": ("DN_PHOTON_REALTIME", "str"), "PhotonVoiceAppId": ("DN_PHOTON_VOICE", "str"), "PhotonChatAppId": ("DN_PHOTON_CHAT", "str"), "PhotonNameServer": ("DN_PHOTON_SERVER", "str"), "PhotonNameServerPort": ("DN_PHOTON_PORT", "int"), "PhotonRegion": ("DN_PHOTON_REGION", "str"), "EnableTlsTrustBypass": ("DN_TLS_TRUST_BYPASS", "bool"), "AcceptUnsignedImages": ("DN_ACCEPT_UNSIGNED_IMAGES", "bool"), "AutoCreateAccount": ("DN_AUTO_CREATE_ACCOUNT", "bool"), "LogHttp": ("DN_LOG_HTTP", "bool"), "Debug": ("DN_DEBUG_HTTP", "bool"), "LogHttpBodyMax": ("DN_LOG_BODY_MAX", "int"), } TRUE = {"true", "1", "yes", "on"} FALSE = {"false", "0", "no", "off"} def c_string(v): return '"' + v.replace("\\", "\\\\").replace('"', '\\"') + '"' def main(): if len(sys.argv) != 4: raise SystemExit("usage: gen_config_header.py ") cfg, package, out = Path(sys.argv[1]), sys.argv[2], Path(sys.argv[3]) lines = ["// Generated by scripts/gen_config_header.py -- do not edit, do not commit.", "#ifndef DORKNET_QUEST_CONFIG_GENERATED_H", "#define DORKNET_QUEST_CONFIG_GENERATED_H", f"#define DN_PACKAGE {c_string(package)}", ""] if cfg.exists(): for raw in cfg.read_text(encoding="utf-8").splitlines(): line = raw.split("#", 1)[0].strip() if not line or "=" not in line or line.startswith("["): continue key, _, val = line.partition("=") key, val = key.strip(), val.strip() if key not in KEYS or val == "": continue macro, kind = KEYS[key] if kind == "str": lines.append(f"#define {macro} {c_string(val)}") elif kind == "int": lines.append(f"#define {macro} {int(val)}") elif kind == "bool": low = val.lower() if low in TRUE: lines.append(f"#define {macro} true") elif low in FALSE: lines.append(f"#define {macro} false") else: raise SystemExit(f"{key}: not a boolean: {val}") else: print(f"note: {cfg} not found; baking package only, all values default", file=sys.stderr) lines += ["", "#endif"] out.write_text("\n".join(lines) + "\n", encoding="utf-8") print(f"wrote {out}") if __name__ == "__main__": main()