63 lines
2.0 KiB
TypeScript
63 lines
2.0 KiB
TypeScript
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<void> {
|
||
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
|
||
}
|