import type { ChildProcess } from 'child_process' import { getCurrent } from './auth' import { fetchPackMeta } from './modpack' import { ensureJava } from './java' import { installMinecraft, installNeoForge } from './install' import { syncModpack } from './modpack' import { launchGame } from './launch' import { getSettings } from './settings' import { emit } from './events' import * as logger from './logger' import type { PlayOptions } from '../shared/ipc' /** Process de jeu courant (un seul à la fois). */ let gameProcess: ChildProcess | null = null /** * Séquence complète "Jouer" : * auth (déjà fait) -> pack.toml -> Java 21 -> Minecraft -> NeoForge -> * sync modpack (delta) -> lancement. * * Chaque étape émet sa progression vers le renderer. Les étapes d'install sont * idempotentes, donc à partir du 2e lancement seules les nouveautés du modpack * sont téléchargées. */ export async function play(opts?: PlayOptions): Promise { if (gameProcess) { throw new Error('Le jeu est déjà en cours.') } const auth = getCurrent() if (!auth) { throw new Error('Non connecté. Connecte-toi avec ton compte Microsoft d’abord.') } const repair = opts?.repair ?? false logger.startSession() try { const meta = await fetchPackMeta() const javaPath = await ensureJava() await installMinecraft(meta.minecraft, repair) const versionId = await installNeoForge(meta.neoforge, meta.minecraft, javaPath, repair) await syncModpack(javaPath) const settings = await getSettings() const proc = await launchGame(versionId, auth, javaPath, settings) gameProcess = proc proc.on('close', () => { gameProcess = null }) } catch (e) { emit.progress({ phase: 'error', message: (e as Error).message, progress: undefined }) throw e } } /** Tue le process de jeu courant. Renvoie true si un process tournait. */ export function stopGame(): boolean { if (!gameProcess) return false gameProcess.kill() return true }