48 lines
1.5 KiB
Python
48 lines
1.5 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
from .fsutil import sha256_file
|
|
from .state import bootstrap_state_path, load_bootstrap_state
|
|
|
|
|
|
BSIPA_PLUGIN_ID = "bsipa"
|
|
|
|
|
|
def latest_log_path(instance_path: Path) -> Path:
|
|
return instance_path / "Logs" / "_latest.log"
|
|
|
|
|
|
def check_bsipa_health(instance_path: Path, state_root: Path, instance: str) -> dict[str, Any]:
|
|
state = load_bootstrap_state(state_root, instance)
|
|
messages: list[str] = []
|
|
|
|
required = ["IPA.exe", "winhttp.dll"]
|
|
for rel in required:
|
|
if not (instance_path / rel).is_file():
|
|
messages.append(f"missing {rel}")
|
|
for rel in ("IPA", "Libs"):
|
|
if not (instance_path / rel).is_dir():
|
|
messages.append(f"missing {rel}/")
|
|
|
|
log_path = latest_log_path(instance_path)
|
|
if not log_path.is_file():
|
|
messages.append("missing Logs/_latest.log")
|
|
else:
|
|
text = log_path.read_text(encoding="utf-8", errors="replace")
|
|
if "Beat Saber IPA (BSIPA):" not in text and "Beat Saber IPA" not in text:
|
|
messages.append("Logs/_latest.log does not show BSIPA startup")
|
|
|
|
if not state:
|
|
messages.append(f"missing bootstrap state: {bootstrap_state_path(state_root, instance)}")
|
|
|
|
return {
|
|
"ok": not messages,
|
|
"messages": messages,
|
|
"statePath": str(bootstrap_state_path(state_root, instance)),
|
|
"logPath": str(log_path),
|
|
"logSha256": sha256_file(log_path) if log_path.is_file() else None,
|
|
"bootstrapRecordedAt": state.get("updatedAt"),
|
|
}
|