DazedTL/util/forge/config.py
2026-06-13 16:16:07 -05:00

105 lines
3.6 KiB
Python

"""Forge plugin build — hotkey (and MZ UI scale) injection at install time."""
from __future__ import annotations
import json
import re
from pathlib import Path
from util.playtest.config import load_config
_PKG_ROOT = Path(__file__).resolve().parent
PLUGIN_BY_ENGINE = {
"MV": "Forge_MV",
"MZ": "Forge_MZ",
}
def bundled_plugin_path(engine: str) -> Path:
name = PLUGIN_BY_ENGINE.get(engine)
if not name:
raise ValueError(f"Unsupported engine: {engine}")
return _PKG_ROOT / f"{name}.js"
def _js_literal(value) -> str:
if value is None:
return "null"
if isinstance(value, bool):
return "true" if value else "false"
if isinstance(value, (int, float)):
return str(value)
return json.dumps(str(value))
def plugin_entry(engine: str, hotkey: str, ui_scale: str = "auto") -> str:
hk = _js_literal(hotkey.strip() or "F10")
name = PLUGIN_BY_ENGINE[engine]
if engine == "MZ":
scale = _js_literal(ui_scale.strip() or "auto")
return (
f' {{ "name": "{name}", "status": true, '
f'"description": "Forge — in-game cheat & editor overlay", '
f'"parameters": {{ "hotkey": {hk}, "speedKey": "Control", '
f'"startOpen": "false", "itemMaxOverride": "0", "uiScale": {scale} }} }}'
)
return (
f' {{ "name": "{name}", "status": true, '
f'"description": "Forge — in-game cheat & editor overlay", '
f'"parameters": {{ "Hotkey": {hk}, "SpeedKey": "Control", '
f'"StartOpen": "false", "ItemMaxOverride": "0" }} }}'
)
def _patch_forge_hotkey(forge_text: str, hotkey: str, engine: str) -> str:
hk = hotkey.strip() or "F10"
if engine == "MZ":
pattern = (
r"(\* @param hotkey\s*\n"
r"(?:\s*\*[^\n]*\n)*?"
r"\s*\* @default )F10"
)
forge_text, n = re.subn(pattern, rf"\g<1>{hk}", forge_text, count=1)
if n == 0:
raise ValueError("Could not patch @default hotkey in Forge_MZ.js")
forge_text = re.sub(r"\(P\.hotkey \|\| 'F10'\)", f"(P.hotkey || '{hk}')", forge_text)
forge_text = re.sub(r"API\._hotkey \|\| 'F10'", f"API._hotkey || '{hk}'", forge_text)
return forge_text
pattern = (
r"(\* @param Hotkey\s*\n"
r"(?:\s*\*[^\n]*\n)*?"
r"\s*\* @default )F10"
)
forge_text, n = re.subn(pattern, rf"\g<1>{hk}", forge_text, count=1)
if n == 0:
raise ValueError("Could not patch @default Hotkey in Forge_MV.js")
forge_text = re.sub(r"\(P\.Hotkey \|\| 'F10'\)", f"(P.Hotkey || '{hk}')", forge_text)
return forge_text
def prepare_forge_js(engine: str, source: Path | None = None, cfg: dict | None = None) -> str:
"""Build Forge_MV.js or Forge_MZ.js with configured hotkey (and MZ UI scale)."""
src = source or bundled_plugin_path(engine)
effective = {**load_config(), **(cfg or {})}
text = _patch_forge_hotkey(src.read_text(encoding="utf-8"), effective["forgeHotkey"], engine)
if engine != "MZ":
return text
scale = effective.get("uiScale", "auto")
text, n = re.subn(
r"(\* @param uiScale\s*\n(?:\s*\*[^\n]*\n)*?\s*\* @default )auto",
rf"\g<1>{scale}",
text,
count=1,
)
if n == 0:
raise ValueError("Could not patch @default uiScale in Forge_MZ.js")
text = re.sub(r"\(P\.uiScale \|\| 'auto'\)", f"(P.uiScale || '{scale}')", text)
return text
# Back-compat alias
def prepare_forge_mz_js(source: Path | None = None, cfg: dict | None = None) -> str:
return prepare_forge_js("MZ", source, cfg)