Bootstrap UI Scaler and Hotkey for Forge
This commit is contained in:
parent
386f19b7f5
commit
6fe5ab1963
3 changed files with 122 additions and 7 deletions
|
|
@ -12,6 +12,7 @@ from pathlib import Path
|
|||
|
||||
from util.playtest.config import load_config
|
||||
from util.forge.scale_patches import apply_ui_scale_patches
|
||||
from util.forge.modern_patches import apply_modern_forge_patches
|
||||
|
||||
_PKG_ROOT = Path(__file__).resolve().parent
|
||||
|
||||
|
|
@ -38,10 +39,16 @@ def _js_literal(value) -> str:
|
|||
return json.dumps(str(value))
|
||||
|
||||
|
||||
def plugin_entry(engine: str, hotkey: str, ui_scale: str = "auto") -> str:
|
||||
def plugin_entry(engine: str, hotkey: str, ui_scale: str = "auto", *, modern: bool = False) -> str:
|
||||
name = PLUGIN_BY_ENGINE[engine]
|
||||
if modern:
|
||||
return (
|
||||
f' {{ "name": "{name}", "status": true, '
|
||||
f'"description": "Forge — in-game cheat & editor overlay", '
|
||||
f'"parameters": {{}} }}'
|
||||
)
|
||||
hk = _js_literal(hotkey.strip() or "F10")
|
||||
scale = _js_literal(ui_scale.strip() or "auto")
|
||||
name = PLUGIN_BY_ENGINE[engine]
|
||||
if engine == "MZ":
|
||||
return (
|
||||
f' {{ "name": "{name}", "status": true, '
|
||||
|
|
@ -149,13 +156,13 @@ def prepare_forge_js(engine: str, source: Path | None = None, cfg: dict | None =
|
|||
"""Build the Forge plugin written into a game folder (vanilla source + Dazed patches)."""
|
||||
src = source or bundled_plugin_path(engine)
|
||||
text = src.read_text(encoding="utf-8")
|
||||
if not is_legacy_forge_plugin(text):
|
||||
return text
|
||||
|
||||
effective = {**load_config(), **(cfg or {})}
|
||||
hotkey = effective.get("forgeHotkey", "F10")
|
||||
ui_scale = effective.get("uiScale", "auto")
|
||||
|
||||
if not is_legacy_forge_plugin(text):
|
||||
return apply_modern_forge_patches(text, hotkey, str(ui_scale))
|
||||
|
||||
text = apply_ui_scale_patches(text, engine)
|
||||
text = _patch_forge_hotkey(text, hotkey, engine)
|
||||
text = _patch_forge_ui_scale_default(text, str(ui_scale), engine)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from __future__ import annotations
|
|||
import re
|
||||
from pathlib import Path
|
||||
|
||||
from util.forge.config import PLUGIN_BY_ENGINE, plugin_entry, prepare_forge_js
|
||||
from util.forge.config import PLUGIN_BY_ENGINE, is_legacy_forge_plugin, plugin_entry, prepare_forge_js
|
||||
|
||||
_PKG_ROOT = Path(__file__).resolve().parent
|
||||
|
||||
|
|
@ -187,7 +187,8 @@ def install(game_root: Path, source_js: Path | None = None, cfg: dict | None = N
|
|||
|
||||
hotkey = (cfg or {}).get("forgeHotkey", "F10")
|
||||
ui_scale = (cfg or {}).get("uiScale", "auto")
|
||||
entry = plugin_entry(engine, hotkey, ui_scale)
|
||||
modern = not is_legacy_forge_plugin((source_js or default_src).read_text(encoding="utf-8"))
|
||||
entry = plugin_entry(engine, hotkey, ui_scale, modern=modern)
|
||||
try:
|
||||
content = _upsert_plugin_entry(content, plugin_name, entry, nl)
|
||||
plugins_js.write_text(content, encoding="utf-8", newline="")
|
||||
|
|
|
|||
107
util/forge/modern_patches.py
Normal file
107
util/forge/modern_patches.py
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
"""Install-time patches for the rewritten Forge plugin (unified forge.js)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
|
||||
_BOOTSTRAP_START = "/*<DazedMTLTool-Forge-bootstrap>*/"
|
||||
_BOOTSTRAP_END = "/*</DazedMTLTool-Forge-bootstrap>*/"
|
||||
|
||||
_MODIFIER_ALIASES = {
|
||||
"control": "ctrl",
|
||||
"ctrl": "ctrl",
|
||||
"alt": "alt",
|
||||
"shift": "shift",
|
||||
"meta": "meta",
|
||||
"cmd": "meta",
|
||||
"command": "meta",
|
||||
"win": "meta",
|
||||
}
|
||||
|
||||
|
||||
def forge_key_str(hotkey: str) -> str:
|
||||
"""Convert a Dazed forgeHotkey value to Forge shortcut keyStr format."""
|
||||
raw = (hotkey or "F10").strip()
|
||||
if not raw:
|
||||
return "f10"
|
||||
parts = re.split(r"\s*\+\s*|\s+", raw)
|
||||
out: list[str] = []
|
||||
for part in parts:
|
||||
token = part.strip().lower()
|
||||
if not token:
|
||||
continue
|
||||
mapped = _MODIFIER_ALIASES.get(token)
|
||||
if mapped:
|
||||
if mapped not in out:
|
||||
out.append(mapped)
|
||||
else:
|
||||
out.append(token)
|
||||
return " ".join(out) or "f10"
|
||||
|
||||
|
||||
def _bootstrap_js(hotkey: str, ui_scale: str) -> str:
|
||||
key_str = json.dumps(forge_key_str(hotkey))
|
||||
scale = json.dumps(str(ui_scale or "auto").strip() or "auto")
|
||||
return f"""{_BOOTSTRAP_START}
|
||||
(function () {{
|
||||
var toggleKey = {key_str};
|
||||
var uiScale = {scale};
|
||||
try {{
|
||||
var saved = JSON.parse(localStorage.getItem("forge:shortcuts") || "{{}}");
|
||||
saved.toggle_ui = Object.assign({{}}, saved.toggle_ui, {{ keyStr: toggleKey, enabled: true }});
|
||||
localStorage.setItem("forge:shortcuts", JSON.stringify(saved));
|
||||
}} catch (e) {{}}
|
||||
function resolveUiScale(v) {{
|
||||
if (v !== "auto" && v != null && String(v).trim() !== "") {{
|
||||
var n = parseFloat(v);
|
||||
if (!isNaN(n) && n > 0) return Math.max(0.75, Math.min(3, n));
|
||||
}}
|
||||
var base = 816;
|
||||
var gameW = (typeof Graphics !== "undefined" && Graphics.width) ? Graphics.width : 0;
|
||||
var viewW = window.innerWidth || document.documentElement.clientWidth || base;
|
||||
var w = Math.max(gameW || base, viewW);
|
||||
var scale = w / base;
|
||||
var dpr = window.devicePixelRatio || 1;
|
||||
if (dpr > 1.15) scale *= Math.min(2, 0.75 + dpr * 0.35);
|
||||
return Math.max(1, Math.min(2.75, scale));
|
||||
}}
|
||||
function applyUiScale() {{
|
||||
var host = document.getElementById("forge-mvmz-host");
|
||||
if (!host) return;
|
||||
var fx = resolveUiScale(uiScale);
|
||||
host.style.zoom = String(fx);
|
||||
}}
|
||||
if (!window.__dazedForgeUiScaleHook) {{
|
||||
window.__dazedForgeUiScaleHook = true;
|
||||
var observer = new MutationObserver(applyUiScale);
|
||||
observer.observe(document.documentElement, {{ childList: true, subtree: true }});
|
||||
window.addEventListener("resize", applyUiScale);
|
||||
setInterval(applyUiScale, 500);
|
||||
}}
|
||||
applyUiScale();
|
||||
}})();
|
||||
{_BOOTSTRAP_END}"""
|
||||
|
||||
|
||||
def _strip_existing_bootstrap(text: str) -> str:
|
||||
while True:
|
||||
start = text.find(_BOOTSTRAP_START)
|
||||
if start < 0:
|
||||
return text
|
||||
end = text.find(_BOOTSTRAP_END, start)
|
||||
if end < 0:
|
||||
return text
|
||||
text = text[:start] + text[end + len(_BOOTSTRAP_END) :]
|
||||
return text
|
||||
|
||||
|
||||
def apply_modern_forge_patches(text: str, hotkey: str, ui_scale: str) -> str:
|
||||
"""Inject Dazed hotkey / UI-scale bootstrap before the Forge bundle runs."""
|
||||
text = _strip_existing_bootstrap(text)
|
||||
bootstrap = _bootstrap_js(hotkey, ui_scale)
|
||||
match = re.search(r"\*/\s*\n", text)
|
||||
if not match:
|
||||
return bootstrap + "\n" + text
|
||||
pos = match.end()
|
||||
return text[:pos] + bootstrap + "\n" + text[pos:]
|
||||
Loading…
Reference in a new issue