feat: auto-detect new ZIP archives in builds/ + fix exe download path

This commit is contained in:
SashegDev
2026-07-30 11:29:45 +00:00
parent 7ae81b3c91
commit 2846e3edd1
2 changed files with 30 additions and 3 deletions
+21 -3
View File
@@ -227,6 +227,24 @@ async def lifespan(app: FastAPI):
asyncio.create_task(periodic_sync()) asyncio.create_task(periodic_sync())
# Background task: auto-detect new ZIP archives in builds/ and register them
async def watch_new_zips():
watch_interval = int(os.environ.get("ZIP_WATCH_INTERVAL", "15"))
while True:
await asyncio.sleep(watch_interval)
try:
before = set(f.name for f in VERSIONS_DIR.iterdir()) if VERSIONS_DIR.exists() else set()
extract_new_format_versions()
after = set(f.name for f in VERSIONS_DIR.iterdir()) if VERSIONS_DIR.exists() else set()
new_versions = after - before
if new_versions:
logger.info(f"New launcher versions detected: {', '.join(sorted(new_versions))}")
generate_launcher_builds_meta()
except Exception as e:
logger.warning(f"ZIP watch error: {e}")
asyncio.create_task(watch_new_zips())
yield yield
# Cleanup proxy client # Cleanup proxy client
@@ -1567,12 +1585,12 @@ async def get_launcher_version():
"updated_at": datetime.utcnow().isoformat() "updated_at": datetime.utcnow().isoformat()
} }
jar_path = BUILDS_DIR / "ZernMCLauncher.jar" jar_path = BUILDS_DIR / "zernmclauncher.jar"
if jar_path.exists(): if jar_path.exists():
response["download_jar"] = "/launcher/download/jar" response["download_jar"] = "/launcher/download/jar"
response["jar_size"] = jar_path.stat().st_size response["jar_size"] = jar_path.stat().st_size
exe_path = BUILDS_DIR / "ZernMCLauncher.exe" exe_path = BUILDS_DIR / "zernmc.exe"
if exe_path.exists(): if exe_path.exists():
response["download_exe"] = "/launcher/download/exe" response["download_exe"] = "/launcher/download/exe"
response["exe_size"] = exe_path.stat().st_size response["exe_size"] = exe_path.stat().st_size
@@ -1611,7 +1629,7 @@ async def download_launcher_jar(request: Request = None):
@app.get("/launcher/download/exe") @app.get("/launcher/download/exe")
async def download_launcher_exe(request: Request = None): async def download_launcher_exe(request: Request = None):
"""Download launcher EXE file (Windows)""" """Download launcher EXE file (Windows)"""
file_path = BUILDS_DIR / "ZernMCLauncher.exe" file_path = BUILDS_DIR / "zernmc.exe"
if not file_path.exists(): if not file_path.exists():
raise HTTPException(404, "EXE file not found") raise HTTPException(404, "EXE file not found")
+9
View File
@@ -0,0 +1,9 @@
TODO / ideas backlog
====================
Java Agent + IPC (low priority, overkill now)
- Заменить прямой ProcessBuilder.start() на прокси-класс (-javaagent или -cp прокси)
- Прокси класс: подключается к localhost RPC, ждёт "launch", потом reflection вызывает реальный main
- Даёт: двустороннюю связь лаунчер-игра, контроль жизненного цикла, crash-репорты из процесса игры,
передачу настроек/токенов на лету, патчинг классов через Instrumentation API
- Для ZernMC сейчас оверхед — но запомнить на будущее